From 31b035cc94412281569490c1901e94467f1c3042 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 30 Oct 2015 08:47:23 -0400 Subject: [PATCH 001/369] fix submodule name used in error reporting --- racket/src/racket/src/module.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index 1e9baef4f3..1487fae340 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -125,6 +125,7 @@ typedef struct Module_Begin_Expand_State { Scheme_Hash_Table *modidx_cache; Scheme_Object *redef_modname; Scheme_Object *end_statementss; /* list of lists */ + Scheme_Object *modsrc; /* source for top-level module */ } Module_Begin_Expand_State; static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_Env *env, @@ -7096,7 +7097,10 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, rmp = SCHEME_STX_VAL(nm); rmp = scheme_intern_resolved_module_path(rmp); m->modname = rmp; - m->modsrc = rmp; + if (super_bxs) + m->modsrc = super_bxs->modsrc; + else + m->modsrc = rmp; if (!SCHEME_NULLP(submodule_ancestry)) submodule_path = scheme_append(submodule_path, scheme_make_pair(SCHEME_STX_VAL(nm), scheme_null)); @@ -8220,6 +8224,7 @@ static Scheme_Object *do_module_begin(Scheme_Object *orig_form, Scheme_Comp_Env bxs->modidx_cache = modidx_cache; bxs->redef_modname = redef_modname; bxs->end_statementss = scheme_null; + bxs->modsrc = env->genv->module->modsrc; if (env->genv->module->super_bxs_info) { /* initialize imports that are available for export from the enclosing module's From 342198625e7db02fff611b9e4a0c637bd367118e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 30 Oct 2015 11:28:14 -0400 Subject: [PATCH 002/369] syntax-debug-info: handle non-identifiers correctly In particular, fix the handling of binding information when the context includes prefixing on import. Closes PR 15173 --- pkgs/racket-test-core/tests/racket/stx.rktl | 12 ++++++++++++ racket/src/racket/src/syntax.c | 3 +++ 2 files changed, 15 insertions(+) diff --git a/pkgs/racket-test-core/tests/racket/stx.rktl b/pkgs/racket-test-core/tests/racket/stx.rktl index 838992b882..41232667cc 100644 --- a/pkgs/racket-test-core/tests/racket/stx.rktl +++ b/pkgs/racket-test-core/tests/racket/stx.rktl @@ -1814,6 +1814,18 @@ (test #t free-identifier=? #'begin (syntax-case a-b-stx () [(b . _) (datum->syntax #'b 'begin)])))) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; syntax-debug-info + +(let ([check (lambda (syntax-debug-info) + (test 'x hash-ref (syntax-debug-info #'x) 'name) + (test 'nope hash-ref (syntax-debug-info #'1) 'name 'nope) + (test 'nope hash-ref (syntax-debug-info #'(x y)) 'name 'nope))]) + (check syntax-debug-info) + (parameterize ([current-namespace (make-base-namespace)]) + (eval '(require (prefix-in foo: racket/base))) + (check (lambda (stx) (syntax-debug-info (namespace-syntax-introduce stx)))))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Check that attacks are thwarted via `syntax-local-get-shadower' ;; or `make-syntax-delta-introducer': diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index 62c5a8b0cb..1320cd5e22 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -4679,6 +4679,9 @@ static Scheme_Object *unmarshal_lookup_adjust(Scheme_Object *sym, Scheme_Object Scheme_Hash_Tree *excepts; Scheme_Object *prefix; + if (!SCHEME_SYMBOLP(sym)) + return scheme_false; + excepts = extract_unmarshal_excepts(SCHEME_VEC_ELS(pes)[3]); prefix = extract_unmarshal_prefix(SCHEME_VEC_ELS(pes)[3]); From fddd85fa18e18c34ab68515065f3e61a1fa375f9 Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Fri, 30 Oct 2015 13:49:40 -0400 Subject: [PATCH 003/369] protect against errors from early-eof, protect against url objects with no path, ensure method is always passed correctly --- racket/collects/net/http-client.rkt | 45 +++++++++------- racket/collects/net/url.rkt | 80 +++++++++++++++++------------ 2 files changed, 73 insertions(+), 52 deletions(-) diff --git a/racket/collects/net/http-client.rkt b/racket/collects/net/http-client.rkt index f74553bb11..b243241944 100644 --- a/racket/collects/net/http-client.rkt +++ b/racket/collects/net/http-client.rkt @@ -184,27 +184,34 @@ (define (http-conn-response-port/chunked! hc #:close? [close? #f]) (define (http-pipe-chunk ip op) + (define (done) + (flush-output op) + (close-output-port op)) (define crlf-bytes (make-bytes 2)) (let loop ([last-bytes #f]) - (define size-str (string-trim (read-line ip eol-type))) - (define chunk-size (string->number size-str 16)) - (unless chunk-size - (error 'http-conn-response/chunked - "Could not parse ~S as hexadecimal number" - size-str)) - (define use-last-bytes? - (and last-bytes (<= chunk-size (bytes-length last-bytes)))) - (if (zero? chunk-size) - (begin (flush-output op) - (close-output-port op)) - (let* ([bs (if use-last-bytes? - (begin - (read-bytes! last-bytes ip 0 chunk-size) - last-bytes) - (read-bytes chunk-size ip))] - [crlf (read-bytes! crlf-bytes ip 0 2)]) - (write-bytes bs op 0 chunk-size) - (loop bs))))) + (define in-v (read-line ip eol-type)) + (cond + [(eof-object? in-v) + (done)] + [else + (define size-str (string-trim in-v)) + (define chunk-size (string->number size-str 16)) + (unless chunk-size + (error 'http-conn-response/chunked + "Could not parse ~S as hexadecimal number" + size-str)) + (define use-last-bytes? + (and last-bytes (<= chunk-size (bytes-length last-bytes)))) + (if (zero? chunk-size) + (done) + (let* ([bs (if use-last-bytes? + (begin + (read-bytes! last-bytes ip 0 chunk-size) + last-bytes) + (read-bytes chunk-size ip))] + [crlf (read-bytes! crlf-bytes ip 0 2)]) + (write-bytes bs op 0 chunk-size) + (loop bs)))]))) (define-values (in out) (make-pipe PIPE-SIZE)) (define chunk-t diff --git a/racket/collects/net/url.rkt b/racket/collects/net/url.rkt index 2a39e39085..9564806d8b 100644 --- a/racket/collects/net/url.rkt +++ b/racket/collects/net/url.rkt @@ -79,20 +79,21 @@ (define proxy (assoc (url-scheme url) (current-proxy-servers))) (define hc (make-ports url proxy)) (define access-string - (url->string - (if proxy - url - ;; RFCs 1945 and 2616 say: - ;; Note that the absolute path cannot be empty; if none is present in - ;; the original URI, it must be given as "/" (the server root). - (let-values ([(abs? path) - (if (null? (url-path url)) - (values #t (list (make-path/param "" '()))) - (values (url-path-absolute? url) (url-path url)))]) - (make-url #f #f #f #f abs? path (url-query url) (url-fragment url)))))) + (ensure-non-empty + (url->string + (if proxy + url + ;; RFCs 1945 and 2616 say: + ;; Note that the absolute path cannot be empty; if none is present in + ;; the original URI, it must be given as "/" (the server root). + (let-values ([(abs? path) + (if (null? (url-path url)) + (values #t (list (make-path/param "" '()))) + (values (url-path-absolute? url) (url-path url)))]) + (make-url #f #f #f #f abs? path (url-query url) (url-fragment url))))))) (hc:http-conn-send! hc access-string - #:method (if get? "GET" "POST") + #:method (if get? #"GET" #"POST") #:headers strings #:content-decode '() #:data post-data) @@ -111,16 +112,19 @@ (cond [(not scheme) (schemeless-url url)] [(or (string=? scheme "http") (string=? scheme "https")) - (define hc (http://getpost-impure-port get? url post-data strings make-ports #f)) - (http-conn-impure-port hc)] + (define hc + (http://getpost-impure-port get? url post-data strings make-ports #f)) + (http-conn-impure-port hc + #:method (if get? "GET" "POST"))] [(string=? scheme "file") (url-error "There are no impure file: ports")] [else (url-error "Scheme ~a unsupported" scheme)]))) -(define (http-conn-impure-port hc) +(define (http-conn-impure-port hc + #:method [method-bss #"GET"]) (define-values (in out) (make-pipe 4096)) (define-values (status headers response-port) - (hc:http-conn-recv! hc #:close? #t #:content-decode '())) + (hc:http-conn-recv! hc #:method method-bss #:close? #t #:content-decode '())) (fprintf out "~a\r\n" status) (for ([h (in-list headers)]) (fprintf out "~a\r\n" h)) @@ -155,7 +159,8 @@ (http://getpost-impure-port get? url post-data strings make-ports #f) - #:content-decode '() + #:method (if get? #"GET" #"POST") + #:content-decode '() #:close? #t)) response-port] [else @@ -187,7 +192,7 @@ make-ports) (and conn #t))) (define-values (status headers response-port) - (hc:http-conn-recv! hc #:close? (not conn) #:content-decode '())) + (hc:http-conn-recv! hc #:method #"GET" #:close? (not conn) #:content-decode '())) (define new-url (ormap (λ (h) @@ -323,20 +328,28 @@ [else (url-error "unsupported method: ~a" method)])] [proxy (assoc (url-scheme url) (current-proxy-servers))] [hc (make-ports url proxy)] - [access-string (url->string - (if proxy - url - (make-url #f #f #f #f - (url-path-absolute? url) - (url-path url) - (url-query url) - (url-fragment url))))]) + [access-string + (ensure-non-empty + (url->string + (if proxy + url + (make-url #f #f #f #f + (url-path-absolute? url) + (url-path url) + (url-query url) + (url-fragment url)))))]) (hc:http-conn-send! hc access-string #:method method #:headers strings #:content-decode '() #:data data) - (http-conn-impure-port hc))) + (http-conn-impure-port hc + #:method method))) + +(define (ensure-non-empty s) + (if (string=? "" s) + "/" + s)) (provide (all-from-out "url-string.rkt")) @@ -394,12 +407,13 @@ (error 'http-sendrecv/url "Host required: ~e" u)) (hc:http-sendrecv (url-host u) - (url->string - (make-url #f #f #f #f - (url-path-absolute? u) - (url-path u) - (url-query u) - (url-fragment u))) + (ensure-non-empty + (url->string + (make-url #f #f #f #f + (url-path-absolute? u) + (url-path u) + (url-query u) + (url-fragment u)))) #:ssl? (if (equal? "https" (url-scheme u)) (current-https-protocol) From bfb245553c179be857cfa5b885c9f1332319bf20 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 30 Oct 2015 19:59:44 -0400 Subject: [PATCH 004/369] fix some syntax-object traversals Fix uses of `SCHEME_STX_VAL` that should be `scheme_stx_content` to ensure propagation of scope changes. --- racket/src/racket/src/module.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index 1487fae340..6edf5dbee8 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -7975,17 +7975,17 @@ static Scheme_Object *shift_require_phase(Scheme_Object *e, Scheme_Object *phase Scheme_Object *l, *a; l = e; - if (SCHEME_STXP(l)) l = SCHEME_STX_VAL(l); + if (SCHEME_STXP(l)) l = scheme_stx_content(l); if (SCHEME_PAIRP(l)) { a = SCHEME_CAR(l); - if (SCHEME_STXP(a)) a = SCHEME_STX_VAL(a); + if (SCHEME_STXP(a)) a = scheme_stx_content(a); if (can_just_meta && SAME_OBJ(a, just_meta_symbol)) { /* Shift any `for-meta` within `just-meta`: */ l = SCHEME_CDR(l); if (scheme_proper_list_length(l) >= 1) { a = SCHEME_CAR(l); - if (SCHEME_STXP(a)) a = SCHEME_STX_VAL(a); + if (SCHEME_STXP(a)) a = scheme_stx_content(a); if (SCHEME_FALSEP(a) || SCHEME_INTP(a) || SCHEME_BIGNUMP(a)) { e = scheme_null; for (l = SCHEME_CDR(l); SCHEME_PAIRP(l); l = SCHEME_CDR(l)) { @@ -8003,7 +8003,7 @@ static Scheme_Object *shift_require_phase(Scheme_Object *e, Scheme_Object *phase l = SCHEME_CDR(l); if (SCHEME_PAIRP(l)) { a = SCHEME_CAR(l); - if (SCHEME_STXP(a)) a = SCHEME_STX_VAL(a); + if (SCHEME_STXP(a)) a = scheme_stx_content(a); if (SCHEME_FALSEP(a)) { return e; } else if (SCHEME_INTP(a) || SCHEME_BIGNUMP(a)) { @@ -8749,7 +8749,7 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ return fm; } #endif - + if (*bxs->_num_phases < phase + 1) *bxs->_num_phases = phase + 1; @@ -9339,6 +9339,7 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ /************ module[*] *************/ /* check outer syntax & name, then expand pre-module or remember for post-module pass */ int k; + e = handle_submodule_form(who, e, env, phase, rn_set, observer, From d719c06e008e65d26664b92611c90f31e82ef579 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 30 Oct 2015 20:30:42 -0400 Subject: [PATCH 005/369] fix cache comparison of scope-propagation tables Repairs 3eb2c20ad0, which used a scope-set comparison for a table that maps scopes to propagation actions (add, remove, or flip). Closes #1113 Merge to v6.3 --- pkgs/racket-test-core/tests/racket/module.rktl | 18 ++++++++++++++++++ racket/src/racket/src/hash.c | 8 ++++++-- racket/src/racket/src/syntax.c | 11 ++++++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/module.rktl b/pkgs/racket-test-core/tests/racket/module.rktl index ecf51d4ab2..1be29de2c8 100644 --- a/pkgs/racket-test-core/tests/racket/module.rktl +++ b/pkgs/racket-test-core/tests/racket/module.rktl @@ -1624,6 +1624,24 @@ case of module-leve bindings; it doesn't cover local bindings. (test 1 values (lifted-require-of-x (submod 'has-a-submodule-that-exports-x b))) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; This test happens to trigger a combination +;; of lazy adds and reoves that exposed a bug +;; in caching lazy scope propagations + +(eval + (expand + #'(module x racket/kernel + (module ma racket/base + (#%module-begin + (#%require (for-syntax racket/kernel)) + (define-values (x) 1) + (define-syntaxes (foo) (lambda (stx) (quote-syntax x))) + (#%provide foo))) + (module mb racket/kernel + (#%require (submod ".." ma)) + (foo))))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/racket/src/racket/src/hash.c b/racket/src/racket/src/hash.c index f2e995b6db..63415f2276 100644 --- a/racket/src/racket/src/hash.c +++ b/racket/src/racket/src/hash.c @@ -2915,8 +2915,12 @@ static int hamt_equal_entries(int stype, void *eql_data, Scheme_Object *k2, Scheme_Object *v2) { if (stype == scheme_eq_hash_tree_type) { - if (SAME_OBJ(k1, k2)) - return scheme_recur_equal(v1, v2, eql_data); + if (SAME_OBJ(k1, k2)) { + if (eql_data) + return scheme_recur_equal(v1, v2, eql_data); + else + return SAME_OBJ(v1, v2); + } } else if (stype == scheme_hash_tree_type) { if (scheme_recur_equal(k1, k2, eql_data)) return scheme_recur_equal(v1, v2, eql_data); diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index 1320cd5e22..f87cd2f529 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -772,6 +772,13 @@ static int scopes_equal(Scheme_Scope_Set *a, Scheme_Scope_Set *b) return (scope_set_count(a) == scope_set_count(b)) && scope_subset(a, b); } +static int scope_props_equal(Scheme_Scope_Set *a, Scheme_Scope_Set *b) +{ + return scheme_hash_tree_equal_rec((Scheme_Hash_Tree *)a, (Scheme_Object *)a, + (Scheme_Hash_Tree *)b, (Scheme_Object *)b, + NULL); +} + static Scheme_Object *make_fallback_pair(Scheme_Object *a, Scheme_Object *b) { a = scheme_make_vector(2, a); @@ -1809,8 +1816,10 @@ static void intern_scope_set(Scheme_Scope_Table *t, int prop_table) 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)) { + if (scopes_equal(recent_scope_sets[prop_table][i], t->simple_scopes) + && (!prop_table || scope_props_equal(recent_scope_sets[prop_table][i], t->simple_scopes))) { t->simple_scopes = recent_scope_sets[prop_table][i]; + return; } } } From 2f25a1e2bd903a80944e3eb0119dbee8b5f7669f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 30 Oct 2015 21:31:57 -0400 Subject: [PATCH 006/369] fix GC-related issue with recent cache repair Repairs a problem with d719c06e00. A GC can happen while checking whether a cache entry matches, in which case the cache is cleared, so don't check the cache slot again after comparing. Merge to v6.3 --- racket/src/racket/src/syntax.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index f87cd2f529..8c3c630c86 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -1808,17 +1808,19 @@ static void intern_scope_set(Scheme_Scope_Table *t, int prop_table) enough. */ { int i; + Scheme_Scope_Set *s; 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) + s = recent_scope_sets[prop_table][i]; + if (s) { + if (s == t->simple_scopes) return; - if (scopes_equal(recent_scope_sets[prop_table][i], t->simple_scopes) - && (!prop_table || scope_props_equal(recent_scope_sets[prop_table][i], t->simple_scopes))) { - t->simple_scopes = recent_scope_sets[prop_table][i]; + if (scopes_equal(s, t->simple_scopes) + && (!prop_table || scope_props_equal(s, t->simple_scopes))) { + t->simple_scopes = s; return; } } From 352a5dd2d54bacb9e202fe41f62458e2fcaa0495 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 30 Oct 2015 21:40:22 -0400 Subject: [PATCH 007/369] avoid thread swap in checking scope-propagation cache Continuing with 2f25a1e2bd... On further reflection, a GC is possible because a thread swap is possible, and that's asking for trouble. Disallow thread swaps (and, incidentally, GCs) whle comparing scope propagations from the cache. Merge to v6.3 --- racket/src/racket/src/hash.c | 22 ++++++++++++++++++++++ racket/src/racket/src/schpriv.h | 1 + racket/src/racket/src/syntax.c | 14 +++++++------- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/racket/src/racket/src/hash.c b/racket/src/racket/src/hash.c index 63415f2276..92f123b318 100644 --- a/racket/src/racket/src/hash.c +++ b/racket/src/racket/src/hash.c @@ -2950,6 +2950,16 @@ static int hamt_equal_entries(int stype, void *eql_data, #define HAMT_USE_FUEL(n) /* empty */ #include "hamt_subset.inc" +/* fast variant for eq-based dictionaries, where values are compared with `eq?` */ +#define HAMT_NONGCING XFORM_NONGCING +#define HAMT_SUBSET_OF hamt_eq_subset_match_of +#define HAMT_ELEMENT_OF hamt_eq_element_match_of +#define HAMT_ELEMENT_OF_COLLISION hamt_eq_element_match_of_collision +#define HAMT_EQUAL_ENTRIES(stype, eql_data, k1, v1, k2, v2) (SAME_OBJ(k1, k2) && SAME_OBJ(v1, v2)) +#define HAMT_IF_VAL(v, n) n +#define HAMT_USE_FUEL(n) /* empty */ +#include "hamt_subset.inc" + static uintptr_t hamt_combine_key_hashes(Scheme_Hash_Tree *ht) { int popcount, i; @@ -3030,6 +3040,18 @@ int scheme_eq_hash_tree_subset_of(Scheme_Hash_Tree *t1, Scheme_Hash_Tree *t2) return hamt_eq_subset_of(t1, t2, 0, scheme_eq_hash_tree_type, NULL); } +int scheme_eq_hash_tree_subset_match_of(Scheme_Hash_Tree *t1, Scheme_Hash_Tree *t2) +/* assumes that `t1` and `t2` are sets, as opposed to maps */ +{ + t1 = resolve_placeholder(t1); + t2 = resolve_placeholder(t2); + + if (t1->count > t2->count) + return 0; + + return hamt_eq_subset_match_of(t1, t2, 0, scheme_eq_hash_tree_type, NULL); +} + intptr_t scheme_hash_tree_key_hash(Scheme_Hash_Tree *ht) { ht = resolve_placeholder(ht); diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 8da3285bec..86751c1ed9 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -4236,6 +4236,7 @@ void scheme_hash_tree_tie_placeholder(Scheme_Hash_Tree *t, Scheme_Hash_Tree *bas XFORM_NONGCING Scheme_Hash_Tree *scheme_hash_tree_resolve_placeholder(Scheme_Hash_Tree *t); int scheme_hash_tree_kind(Scheme_Hash_Tree *t); XFORM_NONGCING int scheme_eq_hash_tree_subset_of(Scheme_Hash_Tree *t1, Scheme_Hash_Tree *t2); +XFORM_NONGCING int scheme_eq_hash_tree_subset_match_of(Scheme_Hash_Tree *t1, Scheme_Hash_Tree *t2); intptr_t scheme_hash_tree_key_hash(Scheme_Hash_Tree *t1); void scheme_set_root_param(int p, Scheme_Object *v); diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index 8c3c630c86..2fb4dfb106 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -772,11 +772,11 @@ static int scopes_equal(Scheme_Scope_Set *a, Scheme_Scope_Set *b) return (scope_set_count(a) == scope_set_count(b)) && scope_subset(a, b); } -static int scope_props_equal(Scheme_Scope_Set *a, Scheme_Scope_Set *b) +XFORM_NONGCING static int scope_props_equal(Scheme_Scope_Set *a, Scheme_Scope_Set *b) { - return scheme_hash_tree_equal_rec((Scheme_Hash_Tree *)a, (Scheme_Object *)a, - (Scheme_Hash_Tree *)b, (Scheme_Object *)b, - NULL); + return ((scope_set_count(a) == scope_set_count(b)) + && scheme_eq_hash_tree_subset_match_of((Scheme_Hash_Tree *)a, + (Scheme_Hash_Tree *)b)); } static Scheme_Object *make_fallback_pair(Scheme_Object *a, Scheme_Object *b) @@ -1798,7 +1798,7 @@ 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) +XFORM_NONGCING 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 @@ -1818,8 +1818,8 @@ static void intern_scope_set(Scheme_Scope_Table *t, int prop_table) if (s) { if (s == t->simple_scopes) return; - if (scopes_equal(s, t->simple_scopes) - && (!prop_table || scope_props_equal(s, t->simple_scopes))) { + if ((!prop_table && scopes_equal(s, t->simple_scopes)) + || (prop_table && scope_props_equal(s, t->simple_scopes))) { t->simple_scopes = s; return; } From 101fac5c1e1a3ec5ba4f17e8d33e8dce2e3b1d41 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 30 Oct 2015 22:24:40 -0400 Subject: [PATCH 008/369] repair scope-propagtion cache yet again Commit 352a5dd2d5 effectively reverted the repair of d719c06e00. Merge to v6.3 --- 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 92f123b318..b7fd3672aa 100644 --- a/racket/src/racket/src/hash.c +++ b/racket/src/racket/src/hash.c @@ -2956,7 +2956,7 @@ static int hamt_equal_entries(int stype, void *eql_data, #define HAMT_ELEMENT_OF hamt_eq_element_match_of #define HAMT_ELEMENT_OF_COLLISION hamt_eq_element_match_of_collision #define HAMT_EQUAL_ENTRIES(stype, eql_data, k1, v1, k2, v2) (SAME_OBJ(k1, k2) && SAME_OBJ(v1, v2)) -#define HAMT_IF_VAL(v, n) n +#define HAMT_IF_VAL(v, n) v #define HAMT_USE_FUEL(n) /* empty */ #include "hamt_subset.inc" From 14d25abd761bbfd3521eaec2d6db594abdb2a9fd Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Sun, 1 Nov 2015 02:50:12 -0500 Subject: [PATCH 009/369] Add *-keys, *-values, in-* functions for id-tables Bump version to 6.3.0.3 too --- pkgs/base/info.rkt | 2 +- .../syntax/scribblings/id-table.scrbl | 34 ++++++++++- .../tests/racket/id-table-test.rktl | 59 ++++++++++++++++++- racket/collects/syntax/id-table.rkt | 7 +++ racket/collects/syntax/private/id-table.rkt | 39 ++++++++++++ racket/src/racket/src/schvers.h | 4 +- 6 files changed, 139 insertions(+), 6 deletions(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index 8918b1c225..3b90eb63e3 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.3.0.2") +(define version "6.3.0.3") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/pkgs/racket-doc/syntax/scribblings/id-table.scrbl b/pkgs/racket-doc/syntax/scribblings/id-table.scrbl index a1ad334f79..376954301e 100644 --- a/pkgs/racket-doc/syntax/scribblings/id-table.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/id-table.scrbl @@ -155,6 +155,30 @@ Like @racket[hash-remove]. Like @racket[hash-map]. } +@defproc[(free-id-table-keys [table free-id-table?]) + (listof identifier?)]{ + +Like @racket[hash-keys]. + +@history[#:added "6.3.0.3"] +} + +@defproc[(free-id-table-values [table free-id-table?]) + (listof any/c)]{ + +Like @racket[hash-values]. + +@history[#:added "6.3.0.3"] +} + +@defproc[(in-free-id-table [table free-id-table?]) + sequence?]{ + +Like @racket[in-hash]. + +@history[#:added "6.3.0.3"] +} + @defproc[(free-id-table-for-each [table free-id-table?] [proc (-> identifier? any/c any)]) void?]{ @@ -247,6 +271,12 @@ etc) can be used on bound-identifier tables. @defproc[(bound-id-table-map [table bound-id-table?] [proc (-> identifier? any/c any)]) list?] +@defproc[(bound-id-table-keys [table bound-id-table?]) + (listof identifier?)] +@defproc[(bound-id-table-values [table bound-id-table?]) + (listof any/c)] +@defproc[(in-bound-id-table [table bound-id-table?]) + sequence?] @defproc[(bound-id-table-for-each [table bound-id-table?] [proc (-> identifier? any/c any)]) void?] @@ -273,6 +303,8 @@ Like the procedures for free-identifier tables (@racket[make-free-id-table], @racket[free-id-table-ref], etc), but for bound-identifier tables, which use @racket[bound-identifier=?] to compare keys. + +@history[#:changed "6.3.0.3" "Added bound-id-table-keys, bound-id-table-values, in-bound-id-table."] } -@close-eval[id-table-eval] \ No newline at end of file +@close-eval[id-table-eval] diff --git a/pkgs/racket-test-core/tests/racket/id-table-test.rktl b/pkgs/racket-test-core/tests/racket/id-table-test.rktl index f824b89c6e..3ae9668228 100644 --- a/pkgs/racket-test-core/tests/racket/id-table-test.rktl +++ b/pkgs/racket-test-core/tests/racket/id-table-test.rktl @@ -26,6 +26,8 @@ (test 4 bound-id-table-count (make-immutable-bound-id-table alist)) (test 3 free-id-table-count (make-free-id-table alist)) (test 3 free-id-table-count (make-immutable-free-id-table alist)) + (test 3 length (free-id-table-keys (make-immutable-free-id-table alist))) + (test 3 length (free-id-table-values (make-immutable-free-id-table alist))) (let () ;; Test in-dict, iteration methods for immutable id-tables @@ -34,10 +36,18 @@ (define d2 (for/fold ([d (make-immutable-bound-id-table)]) ([(id v) (in-dict d1)]) (dict-set d id (add1 v)))) + ;; Test in-bound-id-table + (define d3 (for/fold ([d (make-immutable-bound-id-table)]) + ([(id v) (in-bound-id-table d1)]) + (dict-set d id (add1 v)))) (test 2 bound-id-table-ref d2 a) (test 3 bound-id-table-ref d2 b) (test 4 bound-id-table-ref d2 b2) - (test 5 bound-id-table-ref d2 b3)) + (test 5 bound-id-table-ref d2 b3) + (test 2 bound-id-table-ref d3 a) + (test 3 bound-id-table-ref d3 b) + (test 4 bound-id-table-ref d3 b2) + (test 5 bound-id-table-ref d3 b3)) (let () ;; Test in-dict, iteration methods for mutable id-tables @@ -46,7 +56,13 @@ (test (+ 1 2 3 4) (lambda () (for/sum ([(id v) (in-dict d1)]) v))) (for ([(id v) (in-dict d1)]) (bound-id-table-set! d1 id (add1 v))) - (test (+ 2 3 4 5) (lambda () (for/sum ([(id v) (in-dict d1)]) v))))) + (test (+ 2 3 4 5) (lambda () (for/sum ([(id v) (in-dict d1)]) v))) + ;; Repeat test with in-bound-id-table + (define d2 (make-bound-id-table alist)) + (test (+ 1 2 3 4) (lambda () (for/sum ([(id v) (in-bound-id-table d2)]) v))) + (for ([(id v) (in-bound-id-table d2)]) + (bound-id-table-set! d2 id (add1 v))) + (test (+ 2 3 4 5) (lambda () (for/sum ([(id v) (in-bound-id-table d2)]) v))))) (let () ;; contains-same? : (listof x) (listof x) -> boolean @@ -91,6 +107,10 @@ contains-same? (list 2 4) (bound-id-table-map table (lambda (x y) y))) + (test #t + contains-same? + (list 2 4) + (bound-id-table-values table)) (test #t contains-same? (list 2 4) @@ -133,6 +153,10 @@ contains-same? (list 2 4) (free-id-table-map table (lambda (x y) y))) + (test #t + contains-same? + (list 2 4) + (free-id-table-values table)) (test #t contains-same? (list 2 4) @@ -181,6 +205,10 @@ contains-same? (list 1 2 3 4) (bound-id-table-map table (lambda (x y) y))) + (test #t + contains-same? + (list 1 2 3 4) + (bound-id-table-values table)) (test #t contains-same? (list 1 2 3 4) @@ -223,6 +251,10 @@ contains-same? (list 2 4) (free-id-table-map table (lambda (x y) y))) + (test #t + contains-same? + (list 2 4) + (free-id-table-values table)) (test #t contains-same? (list 2 4) @@ -334,6 +366,29 @@ )) +;; Tests for id-table-keys +(let () + ;; contains-same-keys? : (listof id) (listof id) -> boolean + (define (contains-same-keys? l1 l2 id=?) + (and (andmap (lambda (x) (member x l2 id=?)) l1) + (andmap (lambda (x) (member x l1 id=?)) l2) + #t)) + + (test #t + contains-same-keys? + (list #'x #'y) + (free-id-table-keys + (make-immutable-free-id-table + (list (cons #'x 0) (cons #'x 1) (cons #'y 2)))) + free-identifier=?) + (test #t + contains-same-keys? + (list #'x #'y) + (bound-id-table-keys + (make-immutable-bound-id-table + (list (cons #'x 0) (cons #'x 1) (cons #'y 2)))) + bound-identifier=?)) + (define-syntax name-for-boundmap-test 'dummy) (define-syntax alias-for-boundmap-test (make-rename-transformer #'name-for-boundmap-test)) (define table (make-free-id-table)) diff --git a/racket/collects/syntax/id-table.rkt b/racket/collects/syntax/id-table.rkt index ef62869be1..f4b96fd79c 100644 --- a/racket/collects/syntax/id-table.rkt +++ b/racket/collects/syntax/id-table.rkt @@ -200,6 +200,7 @@ idtbl-count idtbl-iterate-first idtbl-iterate-next idtbl-iterate-key idtbl-iterate-value + idtbl-keys idtbl-values in-idtbl idtbl-map idtbl-for-each idtbl-mutable-methods idtbl-immutable-methods idtbl/c)) @@ -288,6 +289,12 @@ (-> idtbl? id-table-iter? identifier?)] [idtbl-iterate-value (-> idtbl? id-table-iter? any)] + [idtbl-keys + (-> idtbl? (listof identifier?))] + [idtbl-values + (-> idtbl? list?)] + [in-idtbl + (-> idtbl? sequence?)] [idtbl-map (-> idtbl? (-> identifier? any/c any) list?)] [idtbl-for-each diff --git a/racket/collects/syntax/private/id-table.rkt b/racket/collects/syntax/private/id-table.rkt index f1d7fb9a42..e09c3646d1 100644 --- a/racket/collects/syntax/private/id-table.rkt +++ b/racket/collects/syntax/private/id-table.rkt @@ -214,6 +214,35 @@ Notes (FIXME?): ;; ======== +(define (id-table-keys who d) + (let do-keys ([pos (id-table-iterate-first d)]) + (if (not pos) + null + (cons (id-table-iterate-key who d pos) + (do-keys (id-table-iterate-next who d pos)))))) + +(define (id-table-values who d identifier->symbol identifier=?) + (let do-values ([pos (id-table-iterate-first d)]) + (if (not pos) + null + (cons (id-table-iterate-value who d pos identifier->symbol identifier=?) + (do-values (id-table-iterate-next who d pos)))))) + +(define (in-id-table who d identifier->symbol identifier=?) + (make-do-sequence + (λ () + (values + (λ (pos) + (values + (id-table-iterate-key who d pos) + (id-table-iterate-value who d pos identifier->symbol identifier=?))) + (λ (pos) (id-table-iterate-next who d pos)) + (id-table-iterate-first d) + values + #f #f)))) + +;; ======== + (define (alist-set identifier=? phase l0 id v) ;; To minimize allocation ;; - add new pairs to front @@ -286,6 +315,7 @@ Notes (FIXME?): idtbl-count idtbl-iterate-first idtbl-iterate-next idtbl-iterate-key idtbl-iterate-value + idtbl-keys idtbl-values in-idtbl idtbl-map idtbl-for-each idtbl-mutable-methods idtbl-immutable-methods)) #'(begin @@ -331,6 +361,12 @@ Notes (FIXME?): (id-table-iterate-key 'idtbl-iterate-key d pos)) (define (idtbl-iterate-value d pos) (id-table-iterate-value 'idtbl-iterate-value d pos identifier->symbol identifier=?)) + (define (idtbl-keys d) + (id-table-keys 'idtbl-keys d)) + (define (idtbl-values d) + (id-table-values 'idtbl-values d identifier->symbol identifier=?)) + (define (in-idtbl d) + (in-id-table 'in-idtbl d identifier->symbol identifier=?)) (define idtbl-mutable-methods (vector-immutable idtbl-ref @@ -388,6 +424,9 @@ Notes (FIXME?): idtbl-iterate-value idtbl-map idtbl-for-each + idtbl-keys + idtbl-values + in-idtbl ;; just for use/extension by syntax/id-table idtbl-set/constructor diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index f5551d1d19..bf329bf946 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.2" +#define MZSCHEME_VERSION "6.3.0.3" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 3 #define MZSCHEME_VERSION_Z 0 -#define MZSCHEME_VERSION_W 2 +#define MZSCHEME_VERSION_W 3 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From 37dc3ffa01613322972faf62a0a226d525ff069b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 1 Nov 2015 13:44:52 -0700 Subject: [PATCH 010/369] report error when `--enable-extflonums` fails The `--enable-extflonums` option doesn't really do anything, since extflonum support is enabled automtatically when the compiler's configuration allows it. To make this slightly less confusing, report an error when extflonums cannot be supported, despite `--enable-extflonums`. The error is reported via compiling, instead of via `configure`, but hopefully that's enough to be helpful. --- racket/src/configure | 5 +++++ racket/src/racket/configure.ac | 4 ++++ racket/src/racket/include/scheme.h | 3 +++ racket/src/racket/mzconfig.h.in | 3 +++ 4 files changed, 15 insertions(+) diff --git a/racket/src/configure b/racket/src/configure index dbc52ea48d..21aecfa370 100755 --- a/racket/src/configure +++ b/racket/src/configure @@ -6583,6 +6583,11 @@ $as_echo "#define MZ_NO_EXTFLONUMS 1" >>confdefs.h fi fi +if test "${enable_extflonum}" = "yes" ; then + $as_echo "#define MZ_INSIST_EXTFLONUMS 1" >>confdefs.h + +fi + ############## libffi ################ # Depends on pthread on some platforms diff --git a/racket/src/racket/configure.ac b/racket/src/racket/configure.ac index 46b76c953f..bff753b8ed 100644 --- a/racket/src/racket/configure.ac +++ b/racket/src/racket/configure.ac @@ -1475,6 +1475,10 @@ if test "${enable_extflonum}" = "default" ; then fi fi +if test "${enable_extflonum}" = "yes" ; then + AC_DEFINE(MZ_INSIST_EXTFLONUMS) +fi + ############## libffi ################ # Depends on pthread on some platforms diff --git a/racket/src/racket/include/scheme.h b/racket/src/racket/include/scheme.h index 1ede3d0c9b..4381de52e2 100644 --- a/racket/src/racket/include/scheme.h +++ b/racket/src/racket/include/scheme.h @@ -93,6 +93,9 @@ typedef struct { typedef long double mz_long_double; # endif #else +# ifdef MZ_INSIST_EXTFLONUMS +# error "cannot support extflonums; you may need to adjust compiler options" +# endif typedef double mz_long_double; #endif diff --git a/racket/src/racket/mzconfig.h.in b/racket/src/racket/mzconfig.h.in index 154363d47e..8987178abf 100644 --- a/racket/src/racket/mzconfig.h.in +++ b/racket/src/racket/mzconfig.h.in @@ -95,6 +95,9 @@ typedef unsigned long uintptr_t; /* To disable extflonums when they would otherwise work: */ #undef MZ_NO_EXTFLONUMS +/* Extflonums are specifically requested (so complain if not supported): */ +#undef MZ_INSIST_EXTFLONUMS + /* Library subpath */ #undef SPLS_SUFFIX From 827fc4559879c73d46268fc72f95efe0009ff905 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 2 Nov 2015 09:07:43 -0700 Subject: [PATCH 011/369] syntax-local-infer-name: restore some lost generality In #956, @gus-massa warned that `syntax-local-infer-name` was changed in a breaking way, but the implications were not clear. At a minimum, identifiers need to be treated like symbols, so that `mzlib/contract` name inference works right. I'm erroring more generally on the side of keeping the old behavior for anything other than pair-based trees. Closes #1117. --- pkgs/racket-doc/syntax/scribblings/name.scrbl | 4 ++-- racket/collects/racket/private/name.rkt | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-doc/syntax/scribblings/name.scrbl b/pkgs/racket-doc/syntax/scribblings/name.scrbl index c9ad9ac6d1..71a8cf0d17 100644 --- a/pkgs/racket-doc/syntax/scribblings/name.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/name.scrbl @@ -8,8 +8,8 @@ @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 that is a symbol -(which overrides any inferred name) or @|void-const|. +checked for an @racket['inferred-name] property +(which overrides any inferred name). 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 diff --git a/racket/collects/racket/private/name.rkt b/racket/collects/racket/private/name.rkt index 26c5b98609..9a9ccec647 100644 --- a/racket/collects/racket/private/name.rkt +++ b/racket/collects/racket/private/name.rkt @@ -7,7 +7,8 @@ (case-lambda [(stx use-local?) (let-values ([(prop) (simplify-inferred-name (syntax-property stx 'inferred-name))]) - (or (and (symbol? prop) + (or (and prop + (not (void? prop)) prop) (let ([n (and use-local? (not (void? prop)) From 86f19474caa9653ca475a6ad8b2998e9ca4de0d2 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 3 Nov 2015 18:18:08 -0600 Subject: [PATCH 012/369] Have `magnitude` preserve single-precision-ness. Found using random testing. --- pkgs/racket-test-core/tests/racket/number.rktl | 3 +++ racket/src/racket/src/number.c | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/pkgs/racket-test-core/tests/racket/number.rktl b/pkgs/racket-test-core/tests/racket/number.rktl index d6dd69800d..968562d2fd 100644 --- a/pkgs/racket-test-core/tests/racket/number.rktl +++ b/pkgs/racket-test-core/tests/racket/number.rktl @@ -1607,6 +1607,9 @@ (test +inf.0 magnitude 0.0+inf.0i) (test +nan.0 magnitude +nan.0+inf.0i) (test +nan.0 magnitude +inf.0+nan.0i) +(test +inf.f magnitude 3.0f0-inf.fi) +(test +nan.f magnitude 3.0f0+nan.fi) +(test 3.0f0 magnitude 3.0f0+0.0f0i) (test 0 angle 1) (test 0 angle 1.0) diff --git a/racket/src/racket/src/number.c b/racket/src/racket/src/number.c index 16b4eeee5d..bb20444a58 100644 --- a/racket/src/racket/src/number.c +++ b/racket/src/racket/src/number.c @@ -3804,6 +3804,21 @@ static Scheme_Object *magnitude(int argc, Scheme_Object *argv[]) a[0] = i; return scheme_exact_to_inexact(1, a); } +#ifdef MZ_USE_SINGLE_FLOATS + if (SCHEME_FLTP(i)) { + float f; + f = SCHEME_FLT_VAL(i); + if (MZ_IS_POS_INFINITY((double) f)) { + if (SCHEME_FLTP(r)) { /* `r` is either a single-precision float or exact 0 */ + f = SCHEME_FLT_VAL(r); + if (MZ_IS_NAN((double) f)) { + return scheme_single_nan_object; + } + return scheme_single_inf_object; + } + } + } +#endif if (SCHEME_FLOATP(i)) { double d; d = SCHEME_FLOAT_VAL(i); From 5a8d2e42041ec3e78482c50de85903c767ca0bdd Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 4 Nov 2015 07:51:56 -0700 Subject: [PATCH 013/369] fix bugs in the reader, especially related to readtables Closes #1118, but improved testing exposed many other bugs. --- .../scribblings/reference/fixnums.scrbl | 4 + .../scribblings/reference/flonums.scrbl | 4 + .../scribblings/reference/printer.scrbl | 2 +- .../scribblings/reference/reader.scrbl | 2 +- .../scribblings/reference/readtables.scrbl | 2 +- pkgs/racket-test-core/tests/racket/read.rktl | 68 +++++++++++- racket/src/racket/src/hash.c | 17 ++- racket/src/racket/src/read.c | 103 +++++++++++++----- 8 files changed, 166 insertions(+), 36 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/fixnums.scrbl b/pkgs/racket-doc/scribblings/reference/fixnums.scrbl index 0028ce1332..f63da787de 100644 --- a/pkgs/racket-doc/scribblings/reference/fixnums.scrbl +++ b/pkgs/racket-doc/scribblings/reference/fixnums.scrbl @@ -104,6 +104,10 @@ Two @tech{fxvectors} are @racket[equal?] if they have the same length, and if the values in corresponding slots of the @tech{fxvectors} are @racket[equal?]. +A printed @tech{fxvector} starts with @litchar{#fx(}, optionally with +a number between the @litchar{#fx} and +@litchar{(}. @see-read-print["vector" #:print "vectors"]{fxvectors} + @defproc[(fxvector? [v any/c]) boolean?]{ Returns @racket[#t] if @racket[v] is a @tech{fxvector}, @racket[#f] otherwise.} diff --git a/pkgs/racket-doc/scribblings/reference/flonums.scrbl b/pkgs/racket-doc/scribblings/reference/flonums.scrbl index d4fc72b233..377d66455f 100644 --- a/pkgs/racket-doc/scribblings/reference/flonums.scrbl +++ b/pkgs/racket-doc/scribblings/reference/flonums.scrbl @@ -163,6 +163,10 @@ Two @tech{flvectors} are @racket[equal?] if they have the same length, and if the values in corresponding slots of the @tech{flvectors} are @racket[equal?]. +A printed @tech{flvector} starts with @litchar{#fl(}, optionally with +a number between the @litchar{#fl} and +@litchar{(}. @see-read-print["vector" #:print "vectors"]{flvectors} + @defproc[(flvector? [v any/c]) boolean?]{ Returns @racket[#t] if @racket[v] is a @tech{flvector}, @racket[#f] otherwise.} diff --git a/pkgs/racket-doc/scribblings/reference/printer.scrbl b/pkgs/racket-doc/scribblings/reference/printer.scrbl index 3c63fc7041..4d479715a4 100644 --- a/pkgs/racket-doc/scribblings/reference/printer.scrbl +++ b/pkgs/racket-doc/scribblings/reference/printer.scrbl @@ -288,7 +288,7 @@ all @tech{quotable}, then the vector @racket[print]s as and a closing @litchar{)}. A vector is @tech{quotable} when all of its elements are @tech{quotable}. -In @racket[write] or @racket[display] mode, an @tech{flvector} prints +In @racket[write] or @racket[display] mode, a @tech{flvector} prints like a @tech{vector}, but with a @litchar{#fl} prefix instead of @litchar{#}. A @tech{fxvector} similarly prints with a @litchar{#fx} prefix instead of @litchar{#}. The @racket[print-vector-length] diff --git a/pkgs/racket-doc/scribblings/reference/reader.scrbl b/pkgs/racket-doc/scribblings/reference/reader.scrbl index f01f408323..84ff9248cb 100644 --- a/pkgs/racket-doc/scribblings/reference/reader.scrbl +++ b/pkgs/racket-doc/scribblings/reference/reader.scrbl @@ -631,7 +631,7 @@ The elements of the vector are recursively read until a matching lists (see @secref["parse-pair"]). A delimited @litchar{.} is not allowed among the vector elements. In the case of @tech{flvectors}, the recursive read for element is implicitly prefixed with @litchar{#i} -and must produce a @tech{flonum}. In the case of @tech{flvectors}, +and must produce a @tech{flonum}. In the case of @tech{fxvectors}, the recursive read for element is implicitly prefixed with @litchar{#e} and must produce a @tech{fixnum}. diff --git a/pkgs/racket-doc/scribblings/reference/readtables.scrbl b/pkgs/racket-doc/scribblings/reference/readtables.scrbl index 9c7ba4ee26..2f32fc32ae 100644 --- a/pkgs/racket-doc/scribblings/reference/readtables.scrbl +++ b/pkgs/racket-doc/scribblings/reference/readtables.scrbl @@ -67,7 +67,7 @@ otherwise. } -@defproc[(make-readtable [readtable readtable?] +@defproc[(make-readtable [readtable (or/c readtable? #f)] [key (or/c char? #f)] [mode (or/c (or/c 'terminating-macro 'non-terminating-macro diff --git a/pkgs/racket-test-core/tests/racket/read.rktl b/pkgs/racket-test-core/tests/racket/read.rktl index 8348d7783e..c974f2a63f 100644 --- a/pkgs/racket-test-core/tests/racket/read.rktl +++ b/pkgs/racket-test-core/tests/racket/read.rktl @@ -2,7 +2,7 @@ (load-relative "loadtest.rktl") (Section 'reading) -(define readstr +(define core-readstr (lambda (s) (let* ([o (open-input-string s)] [read (lambda () (read o))]) @@ -12,6 +12,37 @@ last (loop v))))))) +(define (readstr s) + (if (current-readtable) + (core-readstr s) + ;; Try using a readtable that behaves the same as the default, + ;; since that triggers some different paths in the reader: + (let* ([normal (with-handlers ([exn:fail? values]) + (core-readstr s))] + [c-normal (adjust-result-to-compare normal)] + [rt (adjust-result-to-compare + (with-handlers ([exn:fail? values]) + (parameterize ([current-readtable (make-readtable (current-readtable))]) + (core-readstr s))))]) + (if (equal? c-normal rt) + (if (exn? normal) + (raise normal) + normal) + (list "different with readtable" s c-normal rt))))) + +(define (adjust-result-to-compare v) + ;; Make results from two readstrs comparable + (cond + [(hash? v) + (for/fold ([ht (hash)]) ([(k hv) (in-hash v)]) + (hash-update ht + (if (eq? k v) 'SELF k) + (lambda (vht) + (hash-set vht hv #t)) + (hash)))] + [(exn? v) (exn-message v)] + [else v])) + (define readerrtype (lambda (x) x)) @@ -54,6 +85,9 @@ (err/rt-test (readstr "(8 . 9 . ]") exn:fail:read?) (err/rt-test (readstr "(8 . 9 . 1 . )") exn:fail:read?) (err/rt-test (readstr "(8 . 9 . 1 . 10)") exn:fail:read?) +(err/rt-test (readstr "(8 . 9 . #;1)") exn:fail:read?) +(err/rt-test (readstr "(8 . 9 . ;\n)") exn:fail:read?) +(err/rt-test (readstr "(8 . 9 . #|x|#)") exn:fail:read?) (let ([w-suffix (lambda (s) @@ -857,7 +891,31 @@ (err/rt-test (read (make-p (list #"|x" a-special #"y|") (lambda (x) 1) void)) exn:fail:read:non-char?)) (run-delim-special a-special) (run-delim-special special-comment) +(parameterize ([current-readtable (make-readtable #f)]) + (run-delim-special special-comment)) +(require racket/flonum + racket/fixnum) + +(define (run-comment-special) + (test (list 5) read (make-p (list #"(" special-comment #"5)") (lambda (x) 1) void)) + (test (list 5) read (make-p (list #"(5" special-comment #")") (lambda (x) 1) void)) + (test (cons 1 5) read (make-p (list #"(1 . " special-comment #"5)") (lambda (x) 1) void)) + (test (cons 1 5) read (make-p (list #"(1 . 5" special-comment #")") (lambda (x) 1) void)) + (err/rt-test (read (make-p (list #"(1 . " special-comment #")") (lambda (x) 1) void)) exn:fail:read?) + (test (list 2 1 5) read (make-p (list #"(1 . 2 . " special-comment #"5)") (lambda (x) 1) void)) + (test (list 2 1 a-special 5) read (make-p (list #"(1 . 2 ." a-special #"5)") (lambda (x) 1) void)) + (test (list 2 1 5) read (make-p (list #"(1 . " special-comment #"2 . 5)") (lambda (x) 1) void)) + (test (list 2 1 5) read (make-p (list #"(1 . 2 " special-comment #" . 5)") (lambda (x) 1) void)) + (test (vector 1 2 5) read (make-p (list #"#(1 2 " special-comment #"5)") (lambda (x) 1) void)) + (test (flvector 1.0) read (make-p (list #"#fl(1.0 " special-comment #")") (lambda (x) 1) void)) + (test (fxvector 1) read (make-p (list #"#fx(1 " special-comment #")") (lambda (x) 1) void)) + (err/rt-test (read (make-p (list #"#fl(1.0 " a-special #")") (lambda (x) 1) void)) exn:fail:read?) + (err/rt-test (read (make-p (list #"#fx(1 " a-special #")") (lambda (x) 1) void)) exn:fail:read?)) +(run-comment-special) +(parameterize ([current-readtable (make-readtable #f)]) + (run-comment-special)) + ;; Test read-char-or-special: (let ([p (make-p (list #"x" a-special #"y") (lambda (x) 5) void)]) (test #\x peek-char-or-special p) @@ -1134,6 +1192,9 @@ (test #t equal? (fxvector 1000 76 100000 100000 100000 100000 100000 100000 100000 100000) (readstr "#fx10(1000 76 100000)")) (test #t equal? (flvector 0.0 0.0 0.0) (readstr "#fl3()")) (test #t equal? (flvector 2.0 1.0 1.0) (readstr "#fl3(2 1)")) +(test #t equal? (flvector 2.0 1.0) (readstr "#fl(2 #;5 1)")) +(test #t equal? (flvector 2.0 1.0) (readstr "#fl(2 #|5|# 1)")) +(test #t equal? (flvector 2.0 1.0) (readstr "#fl(2 ;5\n 1)")) (test #t equal? (fxvector 0 0 0) (readstr "#fx3()")) (test #t equal? (fxvector 2 1 1) (readstr "#fx3(2 1)")) @@ -1151,6 +1212,11 @@ (err/rt-test (read-syntax 'x (open-input-string "#fx()")) exn:fail:read?) (err/rt-test (read-syntax 'x (open-input-string "#fl()")) exn:fail:read?) +(parameterize ([current-readtable (make-readtable + #f + #f 'non-terminating-macro (lambda args 3.0))]) + (test #t equal? (flvector 3.0) (readstr "#fl(3)"))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (require racket/extflonum) diff --git a/racket/src/racket/src/hash.c b/racket/src/racket/src/hash.c index b7fd3672aa..ab9d0fd289 100644 --- a/racket/src/racket/src/hash.c +++ b/racket/src/racket/src/hash.c @@ -1331,7 +1331,12 @@ static uintptr_t equal_hash_key(Scheme_Object *o, uintptr_t k, Hash_Info *hi) t = SCHEME_TYPE(o); if (t == scheme_hash_tree_indirection_type) { - o = (Scheme_Object *)scheme_hash_tree_resolve_placeholder((Scheme_Hash_Tree *)o); + if (SAME_OBJ(o, orig_obj)) { + o = (Scheme_Object *)scheme_hash_tree_resolve_placeholder((Scheme_Hash_Tree *)o); + orig_obj = o; + } else { + o = (Scheme_Object *)scheme_hash_tree_resolve_placeholder((Scheme_Hash_Tree *)o); + } t = SCHEME_TYPE(o); } @@ -2064,10 +2069,16 @@ static uintptr_t equal_hash_key2(Scheme_Object *o, Hash_Info *hi) return k; } - case scheme_hash_tree_type: + case scheme_hash_tree_indirection_type: + if (!SAME_OBJ(o, orig_obj)) { + o = (Scheme_Object *)scheme_hash_tree_resolve_placeholder((Scheme_Hash_Tree *)o); + } else { + o = (Scheme_Object *)scheme_hash_tree_resolve_placeholder((Scheme_Hash_Tree *)o); + orig_obj = o; + } + case scheme_hash_tree_type: /* ^^^ fallthrough ^^^ */ case scheme_eq_hash_tree_type: case scheme_eqv_hash_tree_type: - case scheme_hash_tree_indirection_type: { Scheme_Hash_Tree *ht = (Scheme_Hash_Tree *)o; Scheme_Object *iv, *ik; diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index f9126e2fca..2de0929d48 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -311,7 +311,8 @@ static int next_is_delim(Scheme_Object *port, static int skip_whitespace_comments(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table **ht, Scheme_Object *indentation, - ReadParams *params, Readtable *table); + ReadParams *params, Readtable *table, + Scheme_Object **prefetched); static Scheme_Object *readtable_call(int w_char, int ch, Scheme_Object *proc, ReadParams *params, Scheme_Object *port, Scheme_Object *src, intptr_t line, intptr_t col, intptr_t pos, @@ -448,6 +449,7 @@ void scheme_init_read(Scheme_Env *env) } builtin_fast[';'] = READTABLE_TERMINATING; builtin_fast['\''] = READTABLE_TERMINATING; + builtin_fast['`'] = READTABLE_TERMINATING; builtin_fast[','] = READTABLE_TERMINATING; builtin_fast['"'] = READTABLE_TERMINATING; builtin_fast['|'] = READTABLE_MULTIPLE_ESCAPE; @@ -874,14 +876,17 @@ static int read_vector_length(Scheme_Object *port, Readtable *table, int *ch, mz } if (!(*overflow)) { - intptr_t old_len; + uintptr_t old_len; + uintptr_t new_len; if (*vector_length < 0) *vector_length = 0; old_len = *vector_length; - *vector_length = ((*vector_length) * 10) + ((*ch) - 48); - if ((*vector_length < 0)|| ((*vector_length / 10) != old_len)) { + new_len = *vector_length; + new_len = ((new_len) * 10) + ((*ch) - 48); + *vector_length = new_len; + if ((*vector_length < 0) || ((new_len / 10) != old_len)) { *overflow = 1; } } @@ -894,6 +899,11 @@ static int read_vector_length(Scheme_Object *port, Readtable *table, int *ch, mz vecbuf[j] = 0; tagbuf[i] = 0; + if (!j) { + vecbuf[j] = '0'; + vecbuf[0] = 0; + } + return readtable_effective_char(table, (*ch)); } @@ -1847,7 +1857,7 @@ read_inner_inner(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table * if (!ph) { scheme_read_err(port, stxsrc, line, col, pos, SPAN(port, pos), 0, indentation, - "read: no #%ld= preceding #%ld#", + "read: no #%d= preceding #%d#", vector_length, vector_length); return scheme_void; } @@ -1874,7 +1884,7 @@ read_inner_inner(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table * if (*ht) { if (scheme_hash_get(*ht, scheme_make_integer(vector_length))) { scheme_read_err(port, stxsrc, line, col, pos, SPAN(port, pos), 0, indentation, - "read: multiple #%ld= tags", + "read: multiple #%d= tags", vector_length); return NULL; } @@ -2662,7 +2672,7 @@ read_list(Scheme_Object *port, else if (got_ch_already) got_ch_already = 0; else - ch = skip_whitespace_comments(port, stxsrc, ht, indentation, params, table); + ch = skip_whitespace_comments(port, stxsrc, ht, indentation, params, table, NULL); if ((ch == EOF) && (closer != EOF)) { char *suggestion = ""; @@ -2754,9 +2764,11 @@ read_list(Scheme_Object *port, switch (shape) { case mz_shape_fl_vec: car = read_flonum(port, NULL, ht, indentation, params, RETURN_FOR_SPECIAL_COMMENT); + MZ_ASSERT(SCHEME_DBLP(car)); break; case mz_shape_fx_vec: car = read_fixnum(port, NULL, ht, indentation, params, RETURN_FOR_SPECIAL_COMMENT); + MZ_ASSERT(SCHEME_INTP(car)); break; default: car = read_inner(port, stxsrc, ht, indentation, params, RETURN_FOR_SPECIAL_COMMENT); @@ -2770,7 +2782,7 @@ read_list(Scheme_Object *port, retry_before_dot: - ch = skip_whitespace_comments(port, stxsrc, ht, indentation, params, table); + ch = skip_whitespace_comments(port, stxsrc, ht, indentation, params, table, NULL); effective_ch = readtable_effective_char(table, ch); if (effective_ch == closer) { if (shape == mz_shape_hash_elem) { @@ -2819,7 +2831,7 @@ read_list(Scheme_Object *port, /* can't be eof, due to check above: */ cdr = read_inner(port, stxsrc, ht, indentation, params, 0); - ch = skip_whitespace_comments(port, stxsrc, ht, indentation, params, table); + ch = skip_whitespace_comments(port, stxsrc, ht, indentation, params, table, &prefetched); effective_ch = readtable_effective_char(table, ch); if ((effective_ch != closer) || (shape == mz_shape_vec_plus_infix)) { if (params->can_read_infix_dot @@ -2848,14 +2860,15 @@ read_list(Scheme_Object *port, last = pair; /* Make sure there's not a closing paren immediately after the dot: */ - ch = skip_whitespace_comments(port, stxsrc, ht, indentation, params, table); + ch = skip_whitespace_comments(port, stxsrc, ht, indentation, params, table, &prefetched); effective_ch = readtable_effective_char(table, ch); if ((effective_ch == closer) || (ch == EOF)) { scheme_read_err(port, stxsrc, dotline, dotcol, dotpos, 1, (ch == EOF) ? EOF : 0, indentation, "read: illegal use of `%c'", ch); return NULL; } - got_ch_already = 1; + if (!prefetched) + got_ch_already = 1; } else { scheme_read_err(port, stxsrc, dotline, dotcol, dotpos, 1, (ch == EOF) ? EOF : 0, indentation, "read: illegal use of `%c'", @@ -2880,14 +2893,25 @@ read_list(Scheme_Object *port, return list; } } else { - if ((ch == SCHEME_SPECIAL) - || (table && (ch != EOF) && (shape != mz_shape_hash_list))) { + if ((ch == SCHEME_SPECIAL) + || (table + && (ch != EOF) + && (shape != mz_shape_hash_list) + && (shape != mz_shape_fl_vec) + && (shape != mz_shape_fx_vec))) { /* We have to try the read, because it might be a comment. */ scheme_ungetc(ch, port); prefetched = read_inner(port, stxsrc, ht, indentation, params, RETURN_FOR_SPECIAL_COMMENT); if (!prefetched) goto retry_before_dot; + if ((shape == mz_shape_fl_vec) && !SCHEME_DBLP(prefetched)) { + scheme_read_err(port, stxsrc, startline, startcol, start, SPAN(port, start), ch, indentation, + "read: stream produced a non-flonum for flvector"); + } else if ((shape == mz_shape_fx_vec) && !SCHEME_INTP(prefetched)) { + scheme_read_err(port, stxsrc, startline, startcol, start, SPAN(port, start), ch, indentation, + "read: stream produced a non-fixnum for fxvector"); + } } else { got_ch_already = 1; } @@ -4111,9 +4135,12 @@ Scheme_Object *scheme_read_intern(Scheme_Object *o) static int skip_whitespace_comments(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table **ht, Scheme_Object *indentation, - ReadParams *params, Readtable *table) + ReadParams *params, Readtable *table, + Scheme_Object **_prefetched) +/* If `_prefetched` is non_NULL, then a SCHEME_SPECIAL result means that + the special value has already been read, and it wasn't a comment. */ { - int ch; + int ch, effective_ch; int blockc_1, blockc_2; blockc_1 = '#'; @@ -4126,21 +4153,23 @@ skip_whitespace_comments(Scheme_Object *port, Scheme_Object *stxsrc, if (!(readtable_kind(table, ch, params) & READTABLE_WHITESPACE)) break; } - return ch; } else { while ((ch = scheme_getc_special_ok(port), NOT_EOF_OR_SPECIAL(ch) && scheme_isspace(ch))) {} } - if (ch == ';') { + effective_ch = readtable_effective_char(table, ch); + if (effective_ch == ';') { do { ch = scheme_getc_special_ok(port); - if (ch == SCHEME_SPECIAL) + effective_ch = readtable_effective_char(table, ch); + if (effective_ch == SCHEME_SPECIAL) scheme_get_ready_read_special(port, stxsrc, ht); - } while (!is_line_comment_end(ch) && ch != EOF); + } while (!is_line_comment_end(effective_ch) && (effective_ch != EOF)); goto start_over; } - if (ch == blockc_1 && (scheme_peekc_special_ok(port) == blockc_2)) { + if ((effective_ch == blockc_1) + && (readtable_effective_char(table, scheme_peekc_special_ok(port)) == blockc_2)) { int depth = 0; int ch2 = 0; intptr_t col, pos, line; @@ -4150,27 +4179,29 @@ skip_whitespace_comments(Scheme_Object *port, Scheme_Object *stxsrc, (void)scheme_getc(port); /* re-read '|' */ do { ch = scheme_getc_special_ok(port); - - if (ch == EOF) + effective_ch = readtable_effective_char(table, ch); + + if (effective_ch == EOF) scheme_read_err(port, stxsrc, line, col, pos, MINSPAN(port, pos, 2), EOF, indentation, "read: end of file in #| comment"); - else if (ch == SCHEME_SPECIAL) + else if (effective_ch == SCHEME_SPECIAL) scheme_get_ready_read_special(port, stxsrc, ht); - if ((ch2 == blockc_2) && (ch == blockc_1)) { + if ((ch2 == blockc_2) && (effective_ch == blockc_1)) { if (!(depth--)) goto start_over; - ch = 0; /* So we don't count '#' toward an opening "#|" */ + effective_ch = 0; /* So we don't count '#' toward an opening "#|" */ } else if ((ch2 == blockc_1) && (ch == blockc_2)) { depth++; - ch = 0; /* So we don't count '|' toward a closing "|#" */ + effective_ch = 0; /* So we don't count '|' toward a closing "|#" */ } - ch2 = ch; + ch2 = effective_ch; } while (1); goto start_over; } - if (ch == '#' && (scheme_peekc_special_ok(port) == ';')) { + if ((effective_ch == '#') + && (readtable_effective_char(table, scheme_peekc_special_ok(port)) == ';')) { Scheme_Object *skipped; intptr_t col, pos, line; @@ -4198,6 +4229,20 @@ skip_whitespace_comments(Scheme_Object *port, Scheme_Object *stxsrc, goto start_over; } + if ((ch == SCHEME_SPECIAL) && _prefetched) { + Scheme_Object *v; + intptr_t col, pos, line; + + scheme_tell_all(port, &line, &col, &pos); + v = scheme_get_special(port, stxsrc, line, col, pos, 0, ht); + if (!scheme_special_comment_value(v)) { + *_prefetched = v; + return SCHEME_SPECIAL; + } + + goto start_over; + } + return ch; } @@ -6303,7 +6348,7 @@ static void check_proc_either_arity(const char *who, int a1, int a2, int which, { if (!scheme_check_proc_arity(NULL, a1, which, argc, argv) && !scheme_check_proc_arity(NULL, a2, which, argc, argv)) { - char buffer[60]; + char buffer[256]; sprintf(buffer, "(or (procedure-arity-includes/c %d) (procedure-arity-includes/c %d))", a1, a2); scheme_wrong_contract(who, buffer, which, argc, argv); } From 42e5d9f5cf34469bec5fd7c12e07624271e21123 Mon Sep 17 00:00:00 2001 From: Phil Nguyen Date: Wed, 4 Nov 2015 14:20:32 -0500 Subject: [PATCH 014/369] fix typo in documented contracts for `extfl->exact` and `extfl->inexact` --- pkgs/racket-doc/scribblings/reference/extflonums.scrbl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/extflonums.scrbl b/pkgs/racket-doc/scribblings/reference/extflonums.scrbl index f1b5004a03..309d3dadc6 100644 --- a/pkgs/racket-doc/scribblings/reference/extflonums.scrbl +++ b/pkgs/racket-doc/scribblings/reference/extflonums.scrbl @@ -109,8 +109,8 @@ Like @racket[flsin], @racket[flcos], @racket[fltan], @racket[flasin], @defproc[(->extfl [a exact-integer?]) extflonum?] @defproc[(extfl->exact-integer [a extflonum?]) exact-integer?] @defproc[(real->extfl [a real?]) extflonum?] -@defproc[(extfl->exact [a real?]) (and/c real? exact?)] -@defproc[(extfl->inexact [a real?]) flonum?] +@defproc[(extfl->exact [a extflonum?]) (and/c real? exact?)] +@defproc[(extfl->inexact [a extflonum?]) flonum?] )]{ The first four are like @racket[->fl], @racket[fl->exact], From c5f4740b31c1ba1451da7d91ddad0c3a306ad112 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 4 Nov 2015 14:03:19 -0700 Subject: [PATCH 015/369] fix reader error for bad surrogate-style encodings --- racket/src/racket/src/read.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index 2de0929d48..da264e0c24 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -3143,10 +3143,11 @@ read_string(int is_byte, Scheme_Object *port, case 'U': if (!is_byte) { int maxc = ((ch == 'u') ? 4 : 8); - char initial[8]; + char initial[9]; ch = scheme_getc_special_ok(port); if (NOT_EOF_OR_SPECIAL(ch) && scheme_isxdigit(ch)) { int count = 1; + initial[0] = ch; n = ch<='9' ? ch-'0' : (scheme_toupper(ch)-'A'+10); while (count < maxc) { ch = scheme_peekc_special_ok(port); @@ -3158,6 +3159,7 @@ read_string(int is_byte, Scheme_Object *port, } else break; } + initial[count] = 0; if ((maxc == 4) && ((n >= 0xD800) && (n <= 0xDBFF))) { /* Allow a surrogate-pair-like encoding, as long as the next part is "\uD..." */ @@ -3202,7 +3204,6 @@ read_string(int is_byte, Scheme_Object *port, else if (NOT_EOF_OR_SPECIAL(ch)) snd[sndp++] = ch; snd[sndp] = 0; - initial[4] = 0; if (err_ok) scheme_read_err(port, stxsrc, line, col, pos, SPAN(port, pos), ch, indentation, "read: bad or incomplete surrogate-style encoding at `\\u%s%5'", From b54c03bb04d73f96189965e1d326710a20f88272 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 4 Nov 2015 16:45:44 -0700 Subject: [PATCH 016/369] refine Cairo patch for CTFontCreatePathForGlyph The CTFontCreatePathForGlyph() function can return NULL when the glyph exists but has an empty path. Instead of treating that as failure, which causes Cairo to generate a bitmap version of the glyph, check that the glyph is mapped for bounding boxes, and treat a NULL path as an empty path in that case. --- .../native-libs/patches/cgfontgetglyph.patch | 40 ++++++++++++++++--- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/racket/src/native-libs/patches/cgfontgetglyph.patch b/racket/src/native-libs/patches/cgfontgetglyph.patch index bde65a327e..c936bb52f4 100644 --- a/racket/src/native-libs/patches/cgfontgetglyph.patch +++ b/racket/src/native-libs/patches/cgfontgetglyph.patch @@ -1,6 +1,6 @@ -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 +diff -r -u 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-11-04 15:21:19.000000000 -0700 ++++ new/cairo-1.12.16/src/cairo-quartz-font.c 2015-11-04 15:21:37.000000000 -0700 @@ -81,9 +81,6 @@ static void (*CGContextSetAllowsFontSmoothingPtr) (CGContextRef, bool) = NULL; static bool (*CGContextGetAllowsFontSmoothingPtr) (CGContextRef) = NULL; @@ -27,22 +27,50 @@ diff -u -r old/cairo-1.12.16/src/cairo-quartz-font.c new/cairo-1.12.16/src/cairo (CGFontGetHMetricsPtr || (CGFontGetAscentPtr && CGFontGetDescentPtr && CGFontGetLeadingPtr))) _cairo_quartz_font_symbols_present = TRUE; -@@ -592,6 +587,7 @@ +@@ -592,6 +587,8 @@ CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph); CGAffineTransform textMatrix; CGPathRef glyphPath; + CTFontRef ctFont; ++ int empty_path; cairo_path_fixed_t *path; if (glyph == INVALID_GLYPH) { -@@ -606,7 +602,9 @@ +@@ -606,19 +603,32 @@ -font->base.scale.yy, 0, 0); - glyphPath = CGFontGetGlyphPathPtr (font_face->cgFont, &textMatrix, 0, glyph); +- if (!glyphPath) + ctFont = CTFontCreateWithGraphicsFont (font_face->cgFont, 1.0, NULL, NULL); + glyphPath = CTFontCreatePathForGlyph (ctFont, glyph, &textMatrix); ++ empty_path = 0; ++ if (!glyphPath) { ++ /* an empty glyph path may just reflect whitespace; check bounding rects */ ++ CGRect r; ++ r = CTFontGetBoundingRectsForGlyphs(ctFont, kCTFontHorizontalOrientation, &glyph, NULL, 1); ++ if (memcmp(&CGRectNull, &r, sizeof(CGRect))) ++ empty_path = 1; ++ } + CFRelease (ctFont); - if (!glyphPath) ++ if (!glyphPath && !empty_path) return CAIRO_INT_STATUS_UNSUPPORTED; + path = _cairo_path_fixed_create (); + if (!path) { +- CGPathRelease (glyphPath); ++ if (glyphPath) ++ CGPathRelease (glyphPath); + return _cairo_error(CAIRO_STATUS_NO_MEMORY); + } + +- CGPathApply (glyphPath, path, _cairo_quartz_path_apply_func); ++ if (glyphPath) ++ CGPathApply (glyphPath, path, _cairo_quartz_path_apply_func); + +- CGPathRelease (glyphPath); ++ if (glyphPath) ++ CGPathRelease (glyphPath); + + _cairo_scaled_glyph_set_path (scaled_glyph, &font->base, path); + From 585f14744e52909c1487624f2b64e090b56810a5 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 4 Nov 2015 16:48:33 -0700 Subject: [PATCH 017/369] ffi/unsafe/com: repair for safe arrays, and add `com-omit?` Repair provided by Antonio Menezes Leitao. --- .../scribblings/foreign/com-auto.scrbl | 8 +++++++ racket/collects/ffi/com.rkt | 2 +- racket/collects/ffi/unsafe/com.rkt | 21 ++++++++++--------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/pkgs/racket-doc/scribblings/foreign/com-auto.scrbl b/pkgs/racket-doc/scribblings/foreign/com-auto.scrbl index c10cbaeb34..e295970af7 100644 --- a/pkgs/racket-doc/scribblings/foreign/com-auto.scrbl +++ b/pkgs/racket-doc/scribblings/foreign/com-auto.scrbl @@ -209,6 +209,14 @@ A constant for use with @racket[com-invoke] in place of an optional argument.} +@defproc[(com-omit? [v any/c]) boolean?]{ + +Returns @racket[#t] if @racket[v] is @racket[com-omit], @racket[#f] +otherwise. + +@history[#:added "6.3.0.3"]} + + @; ---------------------------------------- @section{COM Properties} diff --git a/racket/collects/ffi/com.rkt b/racket/collects/ffi/com.rkt index be1f5a42c1..71b8ac10cf 100644 --- a/racket/collects/ffi/com.rkt +++ b/racket/collects/ffi/com.rkt @@ -14,7 +14,7 @@ com-release com-object-type com-type? com-type=? - com-methods com-method-type com-invoke com-omit + com-methods com-method-type com-invoke com-omit com-omit? com-get-properties com-get-property-type com-get-property com-get-property* com-set-properties com-set-property-type com-set-property! diff --git a/racket/collects/ffi/unsafe/com.rkt b/racket/collects/ffi/unsafe/com.rkt index b5b18e1e92..dc2691b8dc 100644 --- a/racket/collects/ffi/unsafe/com.rkt +++ b/racket/collects/ffi/unsafe/com.rkt @@ -54,7 +54,7 @@ com-release com-object-type com-type? com-type=? - com-methods com-method-type com-invoke com-omit + com-methods com-method-type com-invoke com-omit com-omit? com-get-properties com-get-property-type com-get-property com-get-property* com-set-properties com-set-property-type com-set-property! @@ -1407,10 +1407,10 @@ (define-oleaut VariantInit (_wfun _VARIANT-pointer -> _void)) -(define com-omit +(define-values (com-omit com-omit?) (let () (struct com-omit ()) - (com-omit))) + (values (com-omit) com-omit?))) (define CY-factor 10000) @@ -1732,13 +1732,14 @@ (let loop ([dims dims] [level 1] [index null]) (define lb (SafeArrayGetLBound sa level)) (for/vector ([i (in-range (car dims))]) - (if (null? (cdr dims)) - (let ([var (make-a-VARIANT)]) - (set-VARIANT-vt! var vt) - (SafeArrayGetElement sa (reverse (cons i index)) - (extract-variant-pointer var #t)) - (variant-to-scheme var #:mode mode)) - (loop (cdr dims) (add1 level) (cons i index)))))))) + (let ([i (+ i lb)]) + (if (null? (cdr dims)) + (let ([var (make-a-VARIANT)]) + (set-VARIANT-vt! var vt) + (SafeArrayGetElement sa (reverse (cons i index)) + (extract-variant-pointer var #t)) + (variant-to-scheme var #:mode mode)) + (loop (cdr dims) (add1 level) (cons i index))))))))) (define (_IUnknown-pointer-or-com-object mode) (make-ctype From 5cc3059de2fe4abb8a05f4f39b8b794eba9e3558 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 4 Nov 2015 19:54:27 -0700 Subject: [PATCH 018/369] fix reader tests for disable extflonums --- pkgs/racket-test-core/tests/racket/read.rktl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkgs/racket-test-core/tests/racket/read.rktl b/pkgs/racket-test-core/tests/racket/read.rktl index c974f2a63f..67f79a2b08 100644 --- a/pkgs/racket-test-core/tests/racket/read.rktl +++ b/pkgs/racket-test-core/tests/racket/read.rktl @@ -30,6 +30,8 @@ normal) (list "different with readtable" s c-normal rt))))) +(require racket/extflonum) + (define (adjust-result-to-compare v) ;; Make results from two readstrs comparable (cond @@ -41,6 +43,7 @@ (hash-set vht hv #t)) (hash)))] [(exn? v) (exn-message v)] + [(extflonum? v) (format "~s" v)] [else v])) (define readerrtype From 58c919c04e3e49e6347f49f0807db78796debb12 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 5 Nov 2015 06:40:05 -0700 Subject: [PATCH 019/369] fix getting port name for reader errors Closes #1121 --- pkgs/racket-test-core/tests/racket/port.rktl | 18 ++++++++++++++++++ racket/src/racket/include/scheme.h | 4 ---- racket/src/racket/src/error.c | 2 +- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/port.rktl b/pkgs/racket-test-core/tests/racket/port.rktl index 77a06e6091..d53324ace8 100644 --- a/pkgs/racket-test-core/tests/racket/port.rktl +++ b/pkgs/racket-test-core/tests/racket/port.rktl @@ -888,6 +888,24 @@ (delete-file path)) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check reader error-message formatting for a struct port + +(let () + (define-struct wrapper (other port) + #:property prop:input-port 1) + (err/rt-test + (read (wrapper #f + (make-input-port "wrapped" + (lambda (bstr) + (bytes-set! bstr 0 (char->integer #\))) + 1) + (lambda (bstr d evt) + (bytes-set! bstr 0 (char->integer #\))) + 1) + void))) + exn:fail:read?)) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/racket/src/racket/include/scheme.h b/racket/src/racket/include/scheme.h index 4381de52e2..eda74a245d 100644 --- a/racket/src/racket/include/scheme.h +++ b/racket/src/racket/include/scheme.h @@ -1545,10 +1545,6 @@ struct Scheme_Output_Port struct Scheme_Input_Port *input_half; }; -#define SCHEME_INPORT_VAL(obj) (((Scheme_Input_Port *)(obj))->port_data) -#define SCHEME_OUTPORT_VAL(obj) (((Scheme_Output_Port *)(obj))->port_data) -#define SCHEME_IPORT_NAME(obj) (((Scheme_Input_Port *)obj)->name) - #define SCHEME_SPECIAL (-2) #define SCHEME_UNLESS_READY (-3) diff --git a/racket/src/racket/src/error.c b/racket/src/racket/src/error.c index fd768f074f..ec7db16c28 100644 --- a/racket/src/racket/src/error.c +++ b/racket/src/racket/src/error.c @@ -2175,7 +2175,7 @@ void scheme_read_err(Scheme_Object *port, if (port) { Scheme_Object *pn; - pn = SCHEME_IPORT_NAME(port); + pn = scheme_input_port_record(port)->name; if (SCHEME_PATHP(pn)) { pn = scheme_remove_current_directory_prefix(pn); fn = SCHEME_PATH_VAL(pn); From 7e497db831de1010920c03ef28eb449c0df3d5f8 Mon Sep 17 00:00:00 2001 From: Juan Francisco Cantero Hurtado Date: Fri, 6 Nov 2015 02:27:46 +0100 Subject: [PATCH 020/369] Add *.orig, *.rej and *.core files to gitignore. --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index fe632798e0..ba51fea2b4 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,10 @@ compiled/ .DS_Store *.bak TAGS + +# generated by patch +*.orig +*.rej + +# coredumps +*.core From 5e2421b1a09edb75b1a853cce459d44c58d24772 Mon Sep 17 00:00:00 2001 From: Juan Francisco Cantero Hurtado Date: Fri, 6 Nov 2015 02:39:58 +0100 Subject: [PATCH 021/369] Doc: github.com/plt -> github.com/racket --- pkgs/racket-doc/scribblings/guide/guide.scrbl | 2 +- pkgs/racket-doc/scribblings/inside/overview.scrbl | 2 +- pkgs/racket-doc/scribblings/reference/reference.scrbl | 2 +- pkgs/racket-doc/scribblings/style/testing.scrbl | 4 ++-- racket/src/native-libs/README.txt | 2 +- racket/src/worksp/README | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pkgs/racket-doc/scribblings/guide/guide.scrbl b/pkgs/racket-doc/scribblings/guide/guide.scrbl index 9a868c8db5..2f4a09b52a 100644 --- a/pkgs/racket-doc/scribblings/guide/guide.scrbl +++ b/pkgs/racket-doc/scribblings/guide/guide.scrbl @@ -16,7 +16,7 @@ into details---covering much of the Racket toolbox, but leaving precise details to @|Racket| and other reference manuals. @margin-note{The source of this manual is available on -@hyperlink["https://github.com/plt/racket/tree/master/pkgs/racket-doc/scribblings/guide"]{GitHub}.} +@hyperlink["https://github.com/racket/racket/tree/master/pkgs/racket-doc/scribblings/guide"]{GitHub}.} @table-of-contents[] diff --git a/pkgs/racket-doc/scribblings/inside/overview.scrbl b/pkgs/racket-doc/scribblings/inside/overview.scrbl index be196db743..658422b4af 100644 --- a/pkgs/racket-doc/scribblings/inside/overview.scrbl +++ b/pkgs/racket-doc/scribblings/inside/overview.scrbl @@ -41,7 +41,7 @@ source distribution from @url{http://download.racket-lang.org}; detailed build instructions are in the @filepath{README} file in the top-level @filepath{src} directory. You can also get the latest sources from the @tt{git} repository at -@url{https://github.com/plt/racket}, but beware that the repository is +@url{https://github.com/racket/racket}, but beware that the repository is one step away from a normal source distribution, and it provides build modes that are more suitable for developing Racket itself; see @filepath{INSTALL.txt} in the @tt{git} repository for more diff --git a/pkgs/racket-doc/scribblings/reference/reference.scrbl b/pkgs/racket-doc/scribblings/reference/reference.scrbl index ba9103632d..29a7af9425 100644 --- a/pkgs/racket-doc/scribblings/reference/reference.scrbl +++ b/pkgs/racket-doc/scribblings/reference/reference.scrbl @@ -32,7 +32,7 @@ friendlier (though less precise and less complete) overview of the language. @margin-note{The source of this manual is available on -@hyperlink["https://github.com/plt/racket/tree/master/pkgs/racket-doc/scribblings/reference"]{GitHub}.} +@hyperlink["https://github.com/racket/racket/tree/master/pkgs/racket-doc/scribblings/reference"]{GitHub}.} @defmodulelang*[(racket/base racket) ;; Use sources for overlap with `scheme' and `mzscheme': diff --git a/pkgs/racket-doc/scribblings/style/testing.scrbl b/pkgs/racket-doc/scribblings/style/testing.scrbl index e40cd24c5f..c350d6c34f 100644 --- a/pkgs/racket-doc/scribblings/style/testing.scrbl +++ b/pkgs/racket-doc/scribblings/style/testing.scrbl @@ -16,7 +16,7 @@ Most of our collections come with test suites. These tests suites tend to Run the test suites before you commit. To facilitate testing, we urge you to add a @tt{TESTME.txt} file to your collections. Ideally, you may also wish to have a file in this directory that runs the basic tests. See the - @hyperlink["https://github.com/plt/racket/tree/master/collects/2htdp/"]{2htdp}, + @hyperlink["https://github.com/racket/racket/tree/master/collects/2htdp/"]{2htdp}, which is one of the collections with its own testing style. The file should describe where the tests are located, how to run these tests, and what to look for in terms of successes and failures. These files are necessary @@ -30,7 +30,7 @@ After you commit, watch for and read(!) parts: @tt{success} and @tt{failure}. The former is for tests that should succeed now, and the latter is for tests that are currently expected to fail. See the - @hyperlink["https://github.com/plt/racket/tree/master/collects/tests/typed-scheme"]{Typed + @hyperlink["https://github.com/racket/racket/tree/master/collects/tests/typed-scheme"]{Typed Racket testing arrangement} for an example. When you create such @tt{failure} tests, you may wish to disable DrDr's checking like this: @verbatim[#:indent 2]{ diff --git a/racket/src/native-libs/README.txt b/racket/src/native-libs/README.txt index 6d8a2d0aa8..8d174f7e68 100644 --- a/racket/src/native-libs/README.txt +++ b/racket/src/native-libs/README.txt @@ -123,7 +123,7 @@ Build Steps (assuming no version changes) where contains the package "source" directories, such as "draw-win32-i386". The is normally a - checkout of "https://github.com/plt/libs.git". + checkout of "https://github.com/racket/libs.git". Details ------- diff --git a/racket/src/worksp/README b/racket/src/worksp/README index eddefb2230..fe3f96f6bc 100644 --- a/racket/src/worksp/README +++ b/racket/src/worksp/README @@ -121,7 +121,7 @@ supply them in binary form. The DLLs are distributed in packages, but they are also available from - https://github.com/plt/libs + https://github.com/racket/libs and they must be installed into From f126fd2356b62566aadbebe00a6e1d3e1be86f64 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Fri, 6 Nov 2015 08:41:10 -0500 Subject: [PATCH 022/369] Revert "change or/c so that it takes the first ho projection" This reverts commit 5a33856802f1f82260dc07ab1c3b9df3175867a9. Merge to 6.3. --- .../scribblings/reference/contracts.scrbl | 18 ++---- .../tests/racket/contract/or-and.rkt | 22 +++---- .../collects/racket/contract/private/orc.rkt | 64 +++++++++++++++---- 3 files changed, 68 insertions(+), 36 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index d22ffc44cc..a5889db64f 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -182,25 +182,21 @@ 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, taking the first one that returns -true as the contract for the value. - +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. For example, this contract @racketblock[ (or/c (-> number? number?) (-> string? string? string?)) ] -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. +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. If all of its arguments are @racket[list-contract?]s, then @racket[or/c] returns a @racket[list-contract?]. - -@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.}] } @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 7b41b4cc65..32cecad7ad 100644 --- a/pkgs/racket-test/tests/racket/contract/or-and.rkt +++ b/pkgs/racket-test/tests/racket/contract/or-and.rkt @@ -86,6 +86,14 @@ 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 '()]) @@ -223,21 +231,11 @@ 'pos 'neg) (lambda (x y z) 1))) - (test/spec-passed/result + (test/neg-blame '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)) - 1)) + (lambda (x) 1)))) diff --git a/racket/collects/racket/contract/private/orc.rkt b/racket/collects/racket/contract/private/orc.rkt index de482e19d6..d1ee02c67f 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 (reverse ho-contracts) (reverse flat-contracts))] + [(null? args) (values ho-contracts (reverse flat-contracts))] [else (let ([arg (car args)]) (cond @@ -242,18 +242,36 @@ [else (let loop ([checks first-order-checks] [procs partial-contracts] - [contracts ho-contracts]) + [contracts ho-contracts] + [candidate-proc #f] + [candidate-contract #f]) (cond [(null? checks) - (raise-blame-error blame val - '("none of the branches of the or/c matched" given: "~e") - val)] + (if candidate-proc + (candidate-proc val) + (raise-blame-error blame val + '("none of the branches of the or/c matched" given: "~e") + val))] [((car checks) val) - ((car procs) 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)))] [else (loop (cdr checks) (cdr procs) - (cdr contracts))]))]))))) + (cdr contracts) + candidate-proc + candidate-contract)]))]))))) (define (multi-or/c-late-neg-proj ctc) (define ho-contracts (multi-or/c-ho-ctcs ctc)) @@ -271,18 +289,38 @@ [else (let loop ([checks first-order-checks] [c-projs c-projs+blame] - [contracts ho-contracts]) + [contracts ho-contracts] + [candidate-c-proj #f] + [candidate-contract #f]) (cond [(null? checks) - (raise-blame-error blame val #:missing-party neg-party - '("none of the branches of the or/c matched" given: "~e") - val)] + (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)])] [((car checks) val) - ((car c-projs) val neg-party)] + (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)))] [else (loop (cdr checks) (cdr c-projs) - (cdr contracts))]))])))) + (cdr contracts) + candidate-c-proj + candidate-contract)]))])))) (define (multi-or/c-first-order ctc) (let ([flats (map flat-contract-predicate (multi-or/c-flat-ctcs ctc))] From 171e4fba41fb30a1aa236ab2a6b970c3c432a5ab Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Thu, 5 Nov 2015 16:30:46 -0500 Subject: [PATCH 023/369] Use a semaphore instead of sleeping in this test. --- pkgs/racket-test/tests/pkg/tests-locking.rkt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-test/tests/pkg/tests-locking.rkt b/pkgs/racket-test/tests/pkg/tests-locking.rkt index 0cd93a2d0e..768b0ce615 100644 --- a/pkgs/racket-test/tests/pkg/tests-locking.rkt +++ b/pkgs/racket-test/tests/pkg/tests-locking.rkt @@ -16,6 +16,7 @@ (initialize-catalogs) (define okay-to-start?-sema (make-semaphore)) (define okay-to-respond?-sema (make-semaphore)) + (define okay-to-quit?-sema (make-semaphore)) (thread (λ () (serve/servlet (pkg-index/basic @@ -28,7 +29,8 @@ #:command-line? #t #:servlet-regexp #rx"" #:port 9967) - (sleep 2))) + (semaphore-wait okay-to-quit?-sema) + (semaphore-wait okay-to-quit?-sema))) ;; Step 2: Assign it as our server $ "raco pkg config --set catalogs http://localhost:9967" @@ -37,11 +39,13 @@ (thread (λ () (shelly-begin - $ "raco pkg install pkg-test1"))) + $ "raco pkg install pkg-test1") + (semaphore-post okay-to-quit?-sema))) (semaphore-wait okay-to-start?-sema) ;; Step 4: Start the installation request that will fail $ "raco pkg install pkg-test1" =exit> 1 ;; Step 5: Free the other one - (semaphore-post okay-to-respond?-sema)))) + (semaphore-post okay-to-respond?-sema) + (semaphore-post okay-to-quit?-sema)))) From b6939b0b2e376c622748837da994d6470a5952ec Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Thu, 5 Nov 2015 16:34:01 -0500 Subject: [PATCH 024/369] Namespace `scheme_boxmap_size` now that it isn't static. --- racket/src/racket/src/marshal.c | 4 ++-- racket/src/racket/src/resolve.c | 16 ++++++++-------- racket/src/racket/src/schpriv.h | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/racket/src/racket/src/marshal.c b/racket/src/racket/src/marshal.c index b64b84866d..c639f9ec2e 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 += boxmap_size(data->num_params + data->closure_size); + svec_size += scheme_boxmap_size(data->num_params + data->closure_size); { int k, mv; for (k = data->num_params + data->closure_size; --k; ) { @@ -1016,7 +1016,7 @@ static Scheme_Object *read_compiled_closure(Scheme_Object *obj) 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)) + if (data->closure_size + scheme_boxmap_size(data->closure_size + data->num_params) != SCHEME_SVEC_LEN(v)) return NULL; data->closure_map = SCHEME_SVEC_VEC(v); diff --git a/racket/src/racket/src/resolve.c b/racket/src/racket/src/resolve.c index f1bd0fea3b..90787abaa0 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 int boxmap_size(int n) +XFORM_NONGCING int scheme_boxmap_size(int n) { return ((CLOS_TYPE_BITS_PER_ARG * n) + (BITS_PER_MZSHORT - 1)) / BITS_PER_MZSHORT; } @@ -1693,7 +1693,7 @@ static mzshort *allocate_boxmap(int n) mzshort *boxmap; int size; - size = boxmap_size(n); + size = scheme_boxmap_size(n); boxmap = MALLOC_N_ATOMIC(mzshort, size); memset(boxmap, 0, size * sizeof(mzshort)); @@ -1807,7 +1807,7 @@ resolve_closure_compilation(Scheme_Object *_data, Resolve_Info *info, } } if (at_least_one) { - closure_size += boxmap_size(data->num_params + closure_size); + closure_size += scheme_boxmap_size(data->num_params + closure_size); expanded_already = 1; } else cl->local_type_map = NULL; @@ -1857,7 +1857,7 @@ resolve_closure_compilation(Scheme_Object *_data, Resolve_Info *info, /* Currently, we only need local_type information as a closure type */ if (flags & SCHEME_INFO_TYPED_VAL_MASK) { if (!expanded_already) { - closure_size += boxmap_size(data->num_params + closure_size); + closure_size += scheme_boxmap_size(data->num_params + closure_size); new_closure_map = (mzshort *)scheme_malloc_atomic(sizeof(mzshort) * closure_size); memset(new_closure_map, 0, sizeof(mzshort) * closure_size); memcpy(new_closure_map, closure_map, sizeof(mzshort) * data->closure_size); @@ -1935,7 +1935,7 @@ resolve_closure_compilation(Scheme_Object *_data, Resolve_Info *info, new_size = (captured->count + (has_tl ? 1 : 0)); if (cl->local_type_map || expanded_already || convert_boxes || captured_typed) { need_flags = new_size; - new_size += boxmap_size(data->num_params + new_size); + new_size += scheme_boxmap_size(data->num_params + new_size); expanded_already = 1; } else need_flags = 0; @@ -1978,13 +1978,13 @@ resolve_closure_compilation(Scheme_Object *_data, Resolve_Info *info, if (has_tl || convert_boxes || cl->local_type_map) { int new_boxes_size; int sz; - new_boxes_size = boxmap_size(convert_size + data->num_params + (has_tl ? 1 : 0)); + new_boxes_size = scheme_boxmap_size(convert_size + data->num_params + (has_tl ? 1 : 0)); sz = ((has_tl ? sizeof(mzshort) : 0) + new_boxes_size * sizeof(mzshort)); closure_map = (mzshort *)scheme_malloc_atomic(sz); memset(closure_map, 0, sz); if (convert_boxes) { int bsz; - bsz = boxmap_size(convert_size); + bsz = scheme_boxmap_size(convert_size); memcpy(closure_map XFORM_OK_PLUS (has_tl ? 1 : 0), convert_boxes, bsz * sizeof(mzshort)); @@ -2014,7 +2014,7 @@ resolve_closure_compilation(Scheme_Object *_data, Resolve_Info *info, && expanded_already && !no_map_shift_needed) { /* shift boxmap down, since we're dropping closure elements */ int bsz; - bsz = boxmap_size(data->num_params + offset); + bsz = scheme_boxmap_size(data->num_params + offset); memmove(closure_map + offset, closure_map + data->closure_size, sizeof(mzshort) * bsz); } diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 86751c1ed9..2171018ac8 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -2737,7 +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); +XFORM_NONGCING int scheme_boxmap_size(int n); int scheme_has_method_property(Scheme_Object *code); From 4d9c5d8dd24a8e1415c612b812092c20320ade6e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 6 Nov 2015 15:49:50 -0700 Subject: [PATCH 025/369] patch Cairo to avoid writing to a global constant This bug is already fixed in the Cairo source repo, so we can discard the patch on the next Cairo upgrade. It's not clear which platforms are affected. On OS X, at least, writing to a global constant can cause a crash. Thanks to Spencer for making a small example that triggers the bug (added to the "draw-test" package). --- racket/src/native-libs/build.rkt | 4 ++++ .../native-libs/patches/allclipmodifybug.patch | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 racket/src/native-libs/patches/allclipmodifybug.patch diff --git a/racket/src/native-libs/build.rkt b/racket/src/native-libs/build.rkt index 506ea17b63..7a71fd8c7f 100644 --- a/racket/src/native-libs/build.rkt +++ b/racket/src/native-libs/build.rkt @@ -116,6 +116,9 @@ ;; Avoid CGFontGetGlyphPath: (define-runtime-path cairo-cgfontgetglpyh-patch "patches/cgfontgetglyph.patch") +;; Patch to avoid writing to a global constant: +(define-runtime-path cairo-allclipmodifybug-patch "patches/allclipmodifybug.patch") + ;; Hack to workaround broken Courier New in Mac OS X 10.{7.8}: (define-runtime-path courier-new-patch "patches/courier-new.patch") @@ -419,6 +422,7 @@ null) #:patches (list cairo-coretext-patch cairo-cgfontgetglpyh-patch + cairo-allclipmodifybug-patch courier-new-patch win32cairofallback-patch))] [("harfbuzz") (config #:depends '("fontconfig" "freetype" "cairo") diff --git a/racket/src/native-libs/patches/allclipmodifybug.patch b/racket/src/native-libs/patches/allclipmodifybug.patch new file mode 100644 index 0000000000..3824c8fef3 --- /dev/null +++ b/racket/src/native-libs/patches/allclipmodifybug.patch @@ -0,0 +1,17 @@ +diff -u -r old/cairo-1.12.16/src/cairo-clip-boxes.c new/cairo-1.12.16/src/cairo-clip-boxes.c +--- old/cairo-1.12.16/src/cairo-clip-boxes.c 2015-11-06 15:46:30.000000000 -0700 ++++ new/cairo-1.12.16/src/cairo-clip-boxes.c 2015-11-06 15:47:36.000000000 -0700 +@@ -172,8 +172,11 @@ + if (clip->path == NULL) { + clip->extents = *r; + } else { +- if (! _cairo_rectangle_intersect (&clip->extents, r)) ++ if (! _cairo_rectangle_intersect (&clip->extents, r)) { + clip = _cairo_clip_set_all_clipped (clip); ++ /* return so that there's no attempt to modify `clip`: */ ++ return clip; ++ } + } + if (clip->path == NULL) + clip->is_region = _cairo_box_is_pixel_aligned (box); +Only in new/cairo-1.12.16/src: cairo-clip-boxes.c~ From e94b07b3aabac7d8103ae3626a804c7bfacfa3e3 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 7 Nov 2015 08:19:50 -0700 Subject: [PATCH 026/369] patch Pango to handle font-info failure Getting NULL from CTFontCollectionCreateMatchingFontDescriptors() might indicate a font installation problem; I'm not sure. In any case, checking for NULL avoids a crash on at least one installation. --- racket/src/native-libs/build.rkt | 4 ++++ .../patches/coretext-nullarray.patch | 21 +++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 racket/src/native-libs/patches/coretext-nullarray.patch diff --git a/racket/src/native-libs/build.rkt b/racket/src/native-libs/build.rkt index 7a71fd8c7f..f955c40eae 100644 --- a/racket/src/native-libs/build.rkt +++ b/racket/src/native-libs/build.rkt @@ -128,6 +128,9 @@ ;; Support registration of extra font families: (define-runtime-path coretext-fontreg-patch "patches/coretext-fontreg.patch") +;; Avoid crash when CTFontCollectionCreateMatchingFontDescriptors fails: +(define-runtime-path coretext-nullarray "patches/coretext-nullarray.patch") + ;; Enable "symbol" fonts, and fix off-by-one: (define-runtime-path win32text-patch "patches/win32text.patch") @@ -441,6 +444,7 @@ "--with-dynamic-modules=no")) #:patches (list coretext-patch coretext-fontreg-patch + coretext-nullarray 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-nullarray.patch b/racket/src/native-libs/patches/coretext-nullarray.patch new file mode 100644 index 0000000000..da247c600b --- /dev/null +++ b/racket/src/native-libs/patches/coretext-nullarray.patch @@ -0,0 +1,21 @@ +diff -r -u 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-11-07 08:15:41.000000000 -0700 ++++ new/pango-1.36.6/pango/pangocoretext-fontmap.c 2015-11-07 08:16:56.000000000 -0700 +@@ -649,7 +649,7 @@ + + italic_faces = g_hash_table_new (g_direct_hash, g_direct_equal); + +- count = CFArrayGetCount (ctfaces); ++ count = (ctfaces ? CFArrayGetCount (ctfaces) : 0); + for (i = 0; i < count; i++) + { + PangoCoreTextFace *face; +@@ -669,7 +669,7 @@ + + CFRelease (font_descriptors); + CFRelease (attributes); +- CFRelease (ctfaces); ++ if (ctfaces) CFRelease (ctfaces); + + /* For all fonts for which a non-synthetic italic variant does + * not exist on the system, we create synthesized versions here. From 66f89cb6f65998bb388bb01c8f0a94c21d3cafdb Mon Sep 17 00:00:00 2001 From: Phil Nguyen Date: Fri, 6 Nov 2015 14:59:14 -0500 Subject: [PATCH 027/369] fix documented contract ranges of `set-subtract!` and `set-symmetric-difference!` --- pkgs/racket-doc/scribblings/reference/sets.scrbl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/sets.scrbl b/pkgs/racket-doc/scribblings/reference/sets.scrbl index 9500bfd8e8..875c189a93 100644 --- a/pkgs/racket-doc/scribblings/reference/sets.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sets.scrbl @@ -518,7 +518,7 @@ both @racket[set-clear] and @racket[set-add], and @supp{supports} @racket[set->s } -@defproc[(set-subtract! [st0 generic-set?] [st generic-set?] ...) generic-set?]{ +@defproc[(set-subtract! [st0 generic-set?] [st generic-set?] ...) void?]{ Removes every element from @racket[st0] that is contained by any of the @racket[st]s. @@ -557,7 +557,7 @@ Supported for any @racket[st] that @impl{implements} @racket[set-remove] or both } -@defproc[(set-symmetric-difference! [st0 generic-set?] [st generic-set?] ...) generic-set?]{ +@defproc[(set-symmetric-difference! [st0 generic-set?] [st generic-set?] ...) void?]{ Adds and removes elements of @racket[st0] so that it includes all of the elements contained an odd number of times in the @racket[st]s and the From 348cd7976f697cdd32f7433131c81969b8ea3e31 Mon Sep 17 00:00:00 2001 From: Juan M Uys Date: Wed, 4 Nov 2015 11:13:33 +0000 Subject: [PATCH 028/369] provide example for in-directory --- .../scribblings/reference/sequences.scrbl | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/sequences.scrbl b/pkgs/racket-doc/scribblings/reference/sequences.scrbl index d82c0bb81d..d73390911b 100644 --- a/pkgs/racket-doc/scribblings/reference/sequences.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sequences.scrbl @@ -384,7 +384,31 @@ each element in the sequence. content of a directory, use the result of @racket[directory-list] as a sequence. -@history[#:changed "6.0.0.1" @elem{Added @racket[use-dir?] argument.}]} +@history[#:changed "6.0.0.1" @elem{Added @racket[use-dir?] argument.}] + +Examples: + + @racketblock[ + (code:comment @#,t{Given a directory tree:}) + (code:comment @#,t{}) + (code:comment @#,t{ /example}) + (code:comment @#,t{ ├── a}) + (code:comment @#,t{ │ ├── alpha}) + (code:comment @#,t{ │ └── apple}) + (code:comment @#,t{ ├── b}) + (code:comment @#,t{ │ └── beta}) + (code:comment @#,t{ └── c}) + (code:comment @#,t{}) + (code:comment @#,t{Output:}) + (code:comment @#,t{}) + (code:comment @#,t{/example/c}) + (code:comment @#,t{/example/b}) + (code:comment @#,t{/example/b/beta}) + (code:comment @#,t{/example/a}) + (code:comment @#,t{}) + (let ([f (lambda (path) (regexp-match? #rx"/example/b.*" (path->string path)))]) + (for ([p (in-directory "/example" f)]) + (printf "~a\n" p)))]} @defproc*[([(in-producer [producer procedure?]) From b5224743b8c97753b8c1b28ed1f8cfbcbd16e079 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 7 Nov 2015 08:56:05 -0700 Subject: [PATCH 029/369] refine `in-directory` example Extend Juan's nice example to show simpler modes, too. --- .../scribblings/reference/sequences.scrbl | 48 +++++++++++++------ 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/sequences.scrbl b/pkgs/racket-doc/scribblings/reference/sequences.scrbl index d73390911b..c49ced9fb3 100644 --- a/pkgs/racket-doc/scribblings/reference/sequences.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sequences.scrbl @@ -384,11 +384,7 @@ each element in the sequence. content of a directory, use the result of @racket[directory-list] as a sequence. -@history[#:changed "6.0.0.1" @elem{Added @racket[use-dir?] argument.}] - -Examples: - - @racketblock[ +@examples[ (code:comment @#,t{Given a directory tree:}) (code:comment @#,t{}) (code:comment @#,t{ /example}) @@ -399,16 +395,38 @@ Examples: (code:comment @#,t{ │ └── beta}) (code:comment @#,t{ └── c}) (code:comment @#,t{}) - (code:comment @#,t{Output:}) - (code:comment @#,t{}) - (code:comment @#,t{/example/c}) - (code:comment @#,t{/example/b}) - (code:comment @#,t{/example/b/beta}) - (code:comment @#,t{/example/a}) - (code:comment @#,t{}) - (let ([f (lambda (path) (regexp-match? #rx"/example/b.*" (path->string path)))]) - (for ([p (in-directory "/example" f)]) - (printf "~a\n" p)))]} + (eval:alts + (parameterize ([current-directory "/example"]) + (for ([p (in-directory)]) + (printf "~a\n" p))) + (for ([p (in-list '("a" + "a/alpha" + "a/apple" + "b" + "b/beta" + "c"))]) + (printf "~a\n" p))) + (eval:alts + (for ([p (in-directory "/example")]) + (printf "~a\n" p)) + (for ([p (in-list '("/example/a" + "/example/a/alpha" + "/example/a/apple" + "/example/b" + "/example/b/beta" + "/example/c"))]) + (printf "~a\n" p))) + (eval:alts + (let ([f (lambda (path) (regexp-match? #rx"/example/b.*" path))]) + (for ([p (in-directory "/example" f)]) + (printf "~a\n" p))) + (for ([p (in-list '("/example/a" + "/example/b" + "/example/b/beta" + "/example/c"))]) + (printf "~a\n" p)))] + +@history[#:changed "6.0.0.1" @elem{Added @racket[use-dir?] argument.}]} @defproc*[([(in-producer [producer procedure?]) From 83c4a2a19c2551fab2ffc1ee47acf6e2142a9452 Mon Sep 17 00:00:00 2001 From: Stephen Chang Date: Tue, 27 Oct 2015 13:51:39 -0400 Subject: [PATCH 030/369] typo in doc for make-syntax-delta-introducer I'm not sure about the _m-id_ part but I think this is what the docs are trying to say. --- pkgs/racket-doc/scribblings/reference/stx-trans.scrbl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl index db3f8f36b3..a7d5194838 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl @@ -916,7 +916,7 @@ and different result procedures use distinct scopes. added the optional operation argument in the result procedure.}]} -@defproc[(make-syntax-delta-introducer [ext-stx syntax?] +@defproc[(make-syntax-delta-introducer [ext-stx identifier?] [base-stx (or/c syntax? #f)] [phase-level (or/c #f exact-integer?) (syntax-local-phase-level)]) @@ -926,7 +926,7 @@ Produces a procedure that behaves like the result of @racket[make-syntax-introducer], but using the @tech{scopes} of @racket[ext-stx] that are not shared with @racket[base-stx]. -This procedure is potentially useful when @racket[_m-id] has a +This procedure is potentially useful when some @racket[_m-id] has a transformer binding that records some @racket[_orig-id], and a use of @racket[_m-id] introduces a binding of @racket[_orig-id]. In that case, the @tech{scopes} one the use of @racket[_m-id] added since the From 6655352789edc891c921b1d6cdd15cb0e6b90c85 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 7 Nov 2015 09:15:56 -0700 Subject: [PATCH 031/369] guard against some cyclic lists in bytecode decoding Closes #1098 --- 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 2fb4dfb106..51b9711a33 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -6721,6 +6721,8 @@ Scheme_Scope_Set *list_to_scope_set(Scheme_Object *l, Scheme_Unmarshal_Tables *u Scheme_Scope_Set *scopes = NULL; Scheme_Object *r = scheme_null, *scope; + if (scheme_proper_list_length(l) < 0) return_NULL; + while (!SCHEME_NULLP(l)) { if (!SCHEME_PAIRP(l)) return_NULL; scopes = (Scheme_Scope_Set *)scheme_hash_get_either(ut->rns, ut->current_rns, l); @@ -6812,6 +6814,8 @@ Scheme_Object *unmarshal_multi_scopes(Scheme_Object *multi_scopes, if (SCHEME_FALLBACKP(l)) l = SCHEME_FALLBACK_FIRST(l); + if (scheme_proper_list_length(l) < 0) return_NULL; + l_first = scheme_null; l_last = NULL; for (; !SCHEME_NULLP(l); l = SCHEME_CDR(l)) { From 0beee9cd6a542bbe7b854497c674c15a7d396189 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 7 Nov 2015 13:58:56 -0700 Subject: [PATCH 032/369] remove visit of available module in `dynamic-require` Even though `dynamic-require` might lead to loading source, the path into the compiler for that source will force compile-time code as needed. One benefit of ths change is that `racket -l pict3d` takes about half as long, because `racket/gui` includes a `dynamic-require` to load a platform-specific back-end, while `pict3d` can pull in a lot of compile-time code to cooperate with Typed Racket. --- racket/src/racket/src/module.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index 6edf5dbee8..ba5ef57854 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -1129,8 +1129,6 @@ static Scheme_Object *_dynamic_require(int argc, Scheme_Object *argv[], base_phase = env->phase; - scheme_prepare_compile_env(env); - m = module_load(modname, env, errname); srcm = m; From 657cda6e12b34e69f836bca65d1ddfa9d4e66045 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 7 Nov 2015 15:06:32 -0600 Subject: [PATCH 033/369] add missing ->i well-formedness check --- racket/collects/racket/contract/private/arr-i-parse.rkt | 1 + 1 file changed, 1 insertion(+) diff --git a/racket/collects/racket/contract/private/arr-i-parse.rkt b/racket/collects/racket/contract/private/arr-i-parse.rkt index 9362f76785..d88942fc2d 100644 --- a/racket/collects/racket/contract/private/arr-i-parse.rkt +++ b/racket/collects/racket/contract/private/arr-i-parse.rkt @@ -142,6 +142,7 @@ code does the parsing and validation of the syntax. ;; no dups in the rest var (when (istx-rst istx) (when (arg/res-vars (istx-rst istx)) + (ensure-bound (arg/res-vars (istx-rst istx))) (not-range-bound (arg/res-vars (istx-rst istx)) #t)) (no-var-dups (arg/res-var (istx-rst istx)))) From 12d063ad873fceaec6cbde9647b01c197f292d4e Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 7 Nov 2015 19:10:32 -0600 Subject: [PATCH 034/369] improve error message when an unknown dependent variable is used --- .../racket/contract/private/arr-i-parse.rkt | 40 +++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/racket/collects/racket/contract/private/arr-i-parse.rkt b/racket/collects/racket/contract/private/arr-i-parse.rkt index d88942fc2d..7eabb799c1 100644 --- a/racket/collects/racket/contract/private/arr-i-parse.rkt +++ b/racket/collects/racket/contract/private/arr-i-parse.rkt @@ -5,7 +5,8 @@ ;; has these old, wrong names in it. [make-module-identifier-mapping make-free-identifier-mapping] [module-identifier-mapping-get free-identifier-mapping-get] - [module-identifier-mapping-put! free-identifier-mapping-put!]) + [module-identifier-mapping-put! free-identifier-mapping-put!] + [module-identifier-mapping-for-each free-identifier-mapping-for-each]) "application-arity-checking.rkt" "arr-util.rkt" (for-template racket/base @@ -100,8 +101,41 @@ code does the parsing and validation of the syntax. (define (ensure-bound vars) (for ([var (in-list vars)]) (unless (free-identifier-mapping-get nm var (λ () #f)) - (raise-syntax-error #f "dependent variable not bound" - stx var)))) + (define vars '()) + (free-identifier-mapping-for-each + nm + (λ (id _) + (define sym (syntax-e id)) + (unless (member sym vars) + (set! vars (cons sym vars))))) + + (define (insert x l) + (cond + [(null? l) (list x)] + [else + (cond + [(symboli expression" + "\n variables:" + (for/list ([var (in-list sorted-vars)] + [i (in-naturals)]) + (format " ~a" var))) + stx var)))) ;; not-range-bound : (listof identifier[used-by-an-arg]) -> void (define (not-range-bound arg-vars arg?) From 71690384a4b294018c6a519fe8ada140ca9af767 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 7 Nov 2015 19:24:46 -0600 Subject: [PATCH 035/369] add first-or/c --- .../scribblings/reference/contracts.scrbl | 42 +++++ .../tests/racket/contract-rand-test.rkt | 61 +++++++ .../tests/racket/contract/arrow-neg-party.rkt | 16 ++ .../tests/racket/contract/arrow-star.rkt | 17 ++ .../tests/racket/contract/async-channel.rkt | 7 + .../tests/racket/contract/context.rkt | 17 +- .../tests/racket/contract/first-order.rkt | 27 +++ .../tests/racket/contract/flat-contracts.rkt | 14 ++ .../tests/racket/contract/instanceof.rkt | 49 ++++- .../tests/racket/contract/list-contract.rkt | 42 ++++- .../tests/racket/contract/name.rkt | 33 ++++ .../tests/racket/contract/obligations.rkt | 10 +- .../tests/racket/contract/or-and.rkt | 147 ++++++++++++++- .../tests/racket/contract/parametric.rkt | 8 + .../tests/racket/contract/predicates.rkt | 21 ++- .../tests/racket/contract/stream.rkt | 10 ++ .../tests/racket/contract/stronger.rkt | 97 ++++++++++ .../tests/racket/contract/struct-dc.rkt | 16 ++ racket/collects/racket/contract/base.rkt | 2 +- .../racket/contract/private/opters.rkt | 3 +- .../collects/racket/contract/private/orc.rkt | 167 +++++++++++++++--- 21 files changed, 769 insertions(+), 37 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index a5889db64f..6b92ebb301 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -199,6 +199,48 @@ If all of its arguments are @racket[list-contract?]s, then @racket[or/c] returns a @racket[list-contract?]. } +@defproc[(first-or/c [contract contract?] ...) + contract?]{ + + Takes any number of contracts and returns a contract that + accepts any value that any one of the contracts accepts + individually. + + The @racket[first-or/c] result tests any value by applying the + contracts in order from left to right. Thus, a contract + such as @racket[(first-or/c (not/c real?) positive?)] + is guaranteed to only invoke the + @racket[positive?] predicate on real numbers. + + If all of the arguments are procedures or @tech{flat + contracts}, the result is a @tech{flat contract} and + similarly if all of the arguments are @tech{chaperone + contracts} the result is too. Otherwise, the result is an + @tech{impersonator contract}. + + If there are multiple higher-order contracts, + @racket[first-or/c] uses @racket[contract-first-order-passes?] + to distinguish between them. More precisely, when an + @racket[first-or/c] is checked, it checks the first order passes + of the first contract against the value. If it succeeds, + then it uses only that contract. If it fails, then it moves + to the second contract, continuing until it finds one of + the contracts where the first order check succeeds. If none + of them do, a contract violation is signaled. + + For example, this contract + @racketblock[ + (first-or/c (-> number? number?) + (-> string? string? string?))] + accepts the function @racket[(λ args 0)], + applying the @racket[(->number? number?)] contract to the function + because it comes first, even though + @racket[(-> string? string? string?)] also applies. + + If all of its arguments are @racket[list-contract?]s, then @racket[first-or/c] + returns a @racket[list-contract?]. +} + @defproc[(and/c [contract contract?] ...) contract?]{ Takes any number of contracts and returns a contract that diff --git a/pkgs/racket-test/tests/racket/contract-rand-test.rkt b/pkgs/racket-test/tests/racket/contract-rand-test.rkt index 099decc9a0..a53fe1eb58 100644 --- a/pkgs/racket-test/tests/racket/contract-rand-test.rkt +++ b/pkgs/racket-test/tests/racket/contract-rand-test.rkt @@ -58,6 +58,7 @@ (check-not-exn (λ () (test-contract-generation (=/c 0)))) (check-not-exn (λ () (test-contract-generation (=/c 0.0)))) (check-not-exn (λ () (test-contract-generation (or/c boolean? boolean?)))) +(check-not-exn (λ () (test-contract-generation (first-or/c boolean? boolean?)))) (check-not-exn (λ () (test-contract-generation (cons/c integer? boolean?)))) (check-not-exn (λ () (test-contract-generation (cons/dc [hd integer?] [tl (hd) (<=/c hd)])))) (check-not-exn (λ () (test-contract-generation (cons/dc [hd (tl) (<=/c tl)] [tl integer?])))) @@ -69,6 +70,7 @@ (check-not-exn (λ () (test-contract-generation (and/c procedure? (-> integer? integer?))))) (check-not-exn (λ () (test-contract-generation (and/c integer? even?)))) (check-not-exn (λ () (test-contract-generation (or/c (and/c real? positive? ( char? integer?)) 0))) (check-not-exn (λ () ((test-contract-generation (-> integer? integer?)) 1))) @@ -149,6 +175,7 @@ (check-not-exn (lambda () (test-contract-generation (or/c #f number?)))) +(check-not-exn (lambda () (test-contract-generation (first-or/c #f number?)))) (check-not-exn (lambda () (test-contract-generation (or/c some-crazy-predicate? some-crazy-predicate? some-crazy-predicate? @@ -160,9 +187,23 @@ some-crazy-predicate? some-crazy-predicate? #f)))) +(check-not-exn (lambda () (test-contract-generation (first-or/c some-crazy-predicate? + some-crazy-predicate? + some-crazy-predicate? + some-crazy-predicate? + some-crazy-predicate? + some-crazy-predicate? + some-crazy-predicate? + some-crazy-predicate? + some-crazy-predicate? + some-crazy-predicate? + #f)))) (check-exn cannot-generate-exn? (λ () (test-contract-generation (or/c some-crazy-predicate? some-crazy-predicate?)))) +(check-exn cannot-generate-exn? (λ () (test-contract-generation + (first-or/c some-crazy-predicate? + some-crazy-predicate?)))) ;; testing a bunch of impossible and/c's inside some or/c doesn't crash (check-not-exn (λ () (test-contract-generation @@ -171,6 +212,12 @@ (and/c (-> number? number?) any/c number?))))) +(check-not-exn (λ () (test-contract-generation + (first-or/c (first-or/c (and/c integer? boolean?) + (and/c (listof integer?) string?)) + (and/c (-> number? number?) + any/c + number?))))) ;; in this test, the and/c shoudl generate a dynamic ;; failure, which should trigger the 'cons/c' failing @@ -285,6 +332,13 @@ (λ (x) (if x 'fail 11)) 'pos 'neg)) +(check-exercise + 10000 + pos-exn? + (contract (-> (first-or/c #f some-crazy-predicate?) some-crazy-predicate?) + (λ (x) (if x 'fail 11)) + 'pos + 'neg)) (check-exercise 10000 @@ -293,3 +347,10 @@ (λ (x) (if x 'fail 11)) 'pos 'neg)) +(check-exercise + 10000 + pos-exn? + (contract (-> (first-or/c #f some-crazy-predicate?) (first-or/c #f some-crazy-predicate?)) + (λ (x) (if x 'fail 11)) + 'pos + 'neg)) 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 e9583fa296..261edd75d1 100644 --- a/pkgs/racket-test/tests/racket/contract/arrow-neg-party.rkt +++ b/pkgs/racket-test/tests/racket/contract/arrow-neg-party.rkt @@ -243,6 +243,22 @@ 'neg #:database "db" #:password "password" #:user "user") (list "user" "db" "password" #f)) + (test/spec-passed/result + '->*neg-party18b + '((neg-party-fn + (->* (#:user string?) + (#:database (or/c string? #f) + #:password (first-or/c string? (list/c 'hash string?) #f) + #:port (first-or/c exact-positive-integer? #f)) + any/c) + (λ (#:user user + #:database [db #f] + #:password [password #f] + #:port [port #f]) + (list user db password port))) + 'neg #:database "db" #:password "password" #:user "user") + (list "user" "db" "password" #f)) + (test/pos-blame '->*neg-party19 '((neg-party-fn diff --git a/pkgs/racket-test/tests/racket/contract/arrow-star.rkt b/pkgs/racket-test/tests/racket/contract/arrow-star.rkt index 04507c1668..a4b5383b96 100644 --- a/pkgs/racket-test/tests/racket/contract/arrow-star.rkt +++ b/pkgs/racket-test/tests/racket/contract/arrow-star.rkt @@ -543,6 +543,23 @@ 'pos 'neg) #:database "db" #:password "password" #:user "user") (list "user" "db" "password" #f)) + + (test/spec-passed/result + 'contract-arrow-star-optional25b + '((contract + (->* (#:user string?) + (#:database (first-or/c string? #f) + #:password (first-or/c string? (list/c 'hash string?) #f) + #:port (first-or/c exact-positive-integer? #f)) + any/c) + (λ (#:user user + #:database [db #f] + #:password [password #f] + #:port [port #f]) + (list user db password port)) + 'pos 'neg) + #:database "db" #:password "password" #:user "user") + (list "user" "db" "password" #f)) (test/spec-passed 'contract-arrow-star-keyword-ordering diff --git a/pkgs/racket-test/tests/racket/contract/async-channel.rkt b/pkgs/racket-test/tests/racket/contract/async-channel.rkt index 322317630d..2627c27612 100644 --- a/pkgs/racket-test/tests/racket/contract/async-channel.rkt +++ b/pkgs/racket-test/tests/racket/contract/async-channel.rkt @@ -30,4 +30,11 @@ '(let ([ac (contract (or/c (async-channel/c integer?) (integer? . -> . integer?)) (make-async-channel) 'pos 'neg)]) (async-channel-put ac 1) + (async-channel-get ac))) + + (test/spec-passed + 'async-channel/c-with-higher-order2 + '(let ([ac (contract (first-or/c (async-channel/c integer?) (integer? . -> . integer?)) + (make-async-channel) 'pos 'neg)]) + (async-channel-put ac 1) (async-channel-get ac)))) diff --git a/pkgs/racket-test/tests/racket/contract/context.rkt b/pkgs/racket-test/tests/racket/contract/context.rkt index df1ba7712c..2f2c788705 100644 --- a/pkgs/racket-test/tests/racket/contract/context.rkt +++ b/pkgs/racket-test/tests/racket/contract/context.rkt @@ -94,8 +94,8 @@ 'neg)) 1)) - (context-test '("a part of the or/c of") - '(contract (or/c 1 (-> number? number?)) + (context-test '() + '(contract (or/c 1 2) 3 'pos 'neg)) @@ -106,6 +106,19 @@ 'pos 'neg) 1)) + + (context-test '() + '(contract (first-or/c 1 (-> number? number?)) + 3 + 'pos + 'neg)) + + (context-test '("the range of" "a part of the first-or/c of") + '((contract (first-or/c 1 (-> number? number?) (-> number? boolean? number?)) + (λ (x) #f) + 'pos + 'neg) + 1)) (context-test '("the 2nd conjunct of") '(contract (and/c procedure? (-> integer? integer?)) diff --git a/pkgs/racket-test/tests/racket/contract/first-order.rkt b/pkgs/racket-test/tests/racket/contract/first-order.rkt index b5cd734b12..e80a37b640 100644 --- a/pkgs/racket-test/tests/racket/contract/first-order.rkt +++ b/pkgs/racket-test/tests/racket/contract/first-order.rkt @@ -130,6 +130,27 @@ (-> integer? integer?)) 1) + (ctest #t contract-first-order-passes? (first-or/c (-> (>=/c 5) (>=/c 5)) boolean?) #t) + (ctest #t contract-first-order-passes? (first-or/c (-> (>=/c 5) (>=/c 5)) boolean?) (λ (x) x)) + (ctest #f contract-first-order-passes? (first-or/c (-> (>=/c 5) (>=/c 5)) boolean?) 'x) + + (ctest #t contract-first-order-passes? + (first-or/c (-> integer? integer? integer?) + (-> integer? integer?)) + (λ (x) x)) + (ctest #t contract-first-order-passes? + (first-or/c (-> integer? integer? integer?) + (-> integer? integer?)) + (λ (x y) x)) + (ctest #f contract-first-order-passes? + (first-or/c (-> integer? integer? integer?) + (-> integer? integer?)) + (λ () x)) + (ctest #f contract-first-order-passes? + (first-or/c (-> integer? integer? integer?) + (-> integer? integer?)) + 1) + (ctest #t contract-first-order-passes? (hash/c any/c any/c) (make-hash)) (ctest #f contract-first-order-passes? (hash/c any/c any/c) #f) (ctest #f contract-first-order-passes? (hash/c symbol? boolean?) (let ([ht (make-hash)]) @@ -175,6 +196,12 @@ (ctest #f contract-first-order-passes? (or/c 'x "x" #rx"x.") "yx") (ctest #f contract-first-order-passes? (or/c 'x "x" #rx"x.") 'y) + (ctest #t contract-first-order-passes? (first-or/c 'x "x" #rx"x") 'x) + (ctest #t contract-first-order-passes? (first-or/c 'x "x" #rx"x") "x") + (ctest #t contract-first-order-passes? (first-or/c 'x "x" #rx"x.") "xy") + (ctest #f contract-first-order-passes? (first-or/c 'x "x" #rx"x.") "yx") + (ctest #f contract-first-order-passes? (first-or/c 'x "x" #rx"x.") 'y) + (ctest #f contract-first-order-passes? (->m integer? integer?) (λ (x) 1)) (ctest #t contract-first-order-passes? (->m integer? integer?) (λ (this x) 1)) diff --git a/pkgs/racket-test/tests/racket/contract/flat-contracts.rkt b/pkgs/racket-test/tests/racket/contract/flat-contracts.rkt index 178a91c6ea..b992b427ac 100644 --- a/pkgs/racket-test/tests/racket/contract/flat-contracts.rkt +++ b/pkgs/racket-test/tests/racket/contract/flat-contracts.rkt @@ -109,6 +109,12 @@ (contract-eval `(new (class* object% (flat-is-a-test<%>) (super-new)))) (contract-eval '(new object%))) (test-flat-contract `(or/c #f (is-a?/c flat-is-a-test%)) + (contract-eval `(new flat-is-a-test%)) + (contract-eval '(new object%))) + (test-flat-contract `(first-or/c #f (is-a?/c flat-is-a-test<%>)) + (contract-eval `(new (class* object% (flat-is-a-test<%>) (super-new)))) + (contract-eval '(new object%))) + (test-flat-contract `(first-or/c #f (is-a?/c flat-is-a-test%)) (contract-eval `(new flat-is-a-test%)) (contract-eval '(new object%)))) @@ -162,6 +168,11 @@ even1) '(1 2 3 4) '(1 2 3)) + (test-flat-contract '(flat-murec-contract ([even1 (first-or/c null? (cons/c number? even2))] + [even2 (cons/c number? even1)]) + even1) + '(1 2 3 4) + '(1 2 3)) (test-flat-contract '(hash/c symbol? boolean? #:flat? #t) (make-hash) 1) (test-flat-contract '(hash/c symbol? boolean? #:flat? #t) @@ -200,6 +211,9 @@ (test-flat-contract '(or/c (flat-contract integer?) char?) #\a #t) (test-flat-contract '(or/c (flat-contract integer?) char?) 1 #t) + (test-flat-contract '(first-or/c (flat-contract integer?) char?) #\a #t) + (test-flat-contract '(first-or/c (flat-contract integer?) char?) 1 #t) + ;; test flat-contract-predicate (test #t (flat-contract-predicate integer?) 1) diff --git a/pkgs/racket-test/tests/racket/contract/instanceof.rkt b/pkgs/racket-test/tests/racket/contract/instanceof.rkt index 52c891a2f9..4845fe31b6 100644 --- a/pkgs/racket-test/tests/racket/contract/instanceof.rkt +++ b/pkgs/racket-test/tests/racket/contract/instanceof.rkt @@ -55,6 +55,27 @@ [c%/c (class/c [m (->m number? number?)])] [d%/c (class/c [n (->m number? number?)])]) (contract (instanceof/c (or/c c%/c d%/c)) (new e%) 'pos 'neg))) + + (test/spec-passed + 'instanceof/c-first-order-9 + '(let* ([c% (class object% (super-new) (define/public (m x) x))] + [c%/c (class/c [m (->m number? number?)])] + [d%/c (class/c [n (->m number? number?)])]) + (contract (instanceof/c (first-or/c c%/c d%/c)) (new c%) 'pos 'neg))) + + (test/spec-passed + 'instanceof/c-first-order-10 + '(let* ([d% (class object% (super-new) (define/public (n x) x))] + [c%/c (class/c [m (->m number? number?)])] + [d%/c (class/c [n (->m number? number?)])]) + (contract (instanceof/c (first-or/c c%/c d%/c)) (new d%) 'pos 'neg))) + + (test/pos-blame + 'instanceof/c-first-order-11 + '(let* ([e% (class object% (super-new) (define/public (p x) x))] + [c%/c (class/c [m (->m number? number?)])] + [d%/c (class/c [n (->m number? number?)])]) + (contract (instanceof/c (first-or/c c%/c d%/c)) (new e%) 'pos 'neg))) (test/spec-passed/result 'instanceof/c-higher-order-1 @@ -87,7 +108,7 @@ (send o m 3))) (test/pos-blame - 'instanceof/c-higher-order-4 + 'instanceof/c-higher-order-5 '(let* ([c% (class object% (super-new) (define/public (m x) #t))] [c%/c (class/c [m (->m number? number?)])] [d%/c (class/c [n (->m number? number?)])] @@ -95,9 +116,33 @@ (send o m 3))) (test/neg-blame - 'instanceof/c-higher-order-4 + 'instanceof/c-higher-order-6 '(let* ([c% (class object% (super-new) (define/public (m x) x))] [c%/c (class/c [m (->m number? number?)])] [d%/c (class/c [n (->m number? number?)])] [o (contract (instanceof/c (or/c c%/c d%/c)) (new c%) 'pos 'neg)]) + (send o m #t))) + + (test/spec-passed + 'instanceof/c-higher-order-7 + '(let* ([c% (class object% (super-new) (define/public (m x) x))] + [c%/c (class/c [m (->m number? number?)])] + [d%/c (class/c [n (->m number? number?)])] + [o (contract (instanceof/c (first-or/c c%/c d%/c)) (new c%) 'pos 'neg)]) + (send o m 3))) + + (test/pos-blame + 'instanceof/c-higher-order-8 + '(let* ([c% (class object% (super-new) (define/public (m x) #t))] + [c%/c (class/c [m (->m number? number?)])] + [d%/c (class/c [n (->m number? number?)])] + [o (contract (instanceof/c (first-or/c c%/c d%/c)) (new c%) 'pos 'neg)]) + (send o m 3))) + + (test/neg-blame + 'instanceof/c-higher-order-9 + '(let* ([c% (class object% (super-new) (define/public (m x) x))] + [c%/c (class/c [m (->m number? number?)])] + [d%/c (class/c [n (->m number? number?)])] + [o (contract (instanceof/c (first-or/c c%/c d%/c)) (new c%) 'pos 'neg)]) (send o m #t)))) \ No newline at end of file diff --git a/pkgs/racket-test/tests/racket/contract/list-contract.rkt b/pkgs/racket-test/tests/racket/contract/list-contract.rkt index e8e890e573..b82ee6e1ef 100644 --- a/pkgs/racket-test/tests/racket/contract/list-contract.rkt +++ b/pkgs/racket-test/tests/racket/contract/list-contract.rkt @@ -115,5 +115,45 @@ 'pos 'neg) (λ (x) (and (exn:fail? x) - (regexp-match #rx"list-contract[?]" (exn-message x)))))) + (regexp-match #rx"list-contract[?]" (exn-message x))))) + + (test/spec-passed/result + 'list-contract-20 + '(list-contract? (first-or/c (cons/c 1 empty?) empty?)) + #t) + + (test/spec-passed/result + 'list-contract-21 + '(list-contract? (first-or/c (cons/c (-> integer? integer?) empty?) + empty?)) + #t) + + (test/spec-passed/result + 'list-contract-22 + '(list-contract? (first-or/c (cons/c (-> integer? integer?) empty?) + (cons/c (-> integer? integer? integer?) empty?) + empty?)) + #t) + + (test/spec-passed/result + 'list-contract-23 + '(list-contract? + (letrec ([c (recursive-contract (first-or/c (cons/c 1 c) empty?))]) + c)) + #f) + + (test/spec-passed/result + 'list-contract-24 + '(list-contract? + (letrec ([c (recursive-contract (first-or/c (cons/c 1 c) empty?) #:list-contract?)]) + c)) + #t) + + (test/pos-blame + 'test-contract-25 + '(contract (letrec ([c (recursive-contract (first-or/c (cons/c any/c c) empty?) + #:list-contract?)]) + c) + (read (open-input-string "#1=(1 . #1#)")) + 'pos 'neg))) diff --git a/pkgs/racket-test/tests/racket/contract/name.rkt b/pkgs/racket-test/tests/racket/contract/name.rkt index 4c93ca5860..384f830148 100644 --- a/pkgs/racket-test/tests/racket/contract/name.rkt +++ b/pkgs/racket-test/tests/racket/contract/name.rkt @@ -33,6 +33,16 @@ (test-name '(or/c boolean? (-> (>=/c 5) (>=/c 5))) (or/c boolean? (-> (>=/c 5) (>=/c 5)))) + (test-name '(first-or/c) (first-or/c)) + (test-name '(first-or/c integer? gt0?) (first-or/c integer? (let ([gt0? (lambda (x) (> x 0))]) gt0?))) + (test-name '(first-or/c integer? boolean?) + (first-or/c (flat-contract integer?) + (flat-contract boolean?))) + (test-name '(first-or/c (-> (>=/c 5) (>=/c 5)) boolean?) + (first-or/c (-> (>=/c 5) (>=/c 5)) boolean?)) + (test-name '(first-or/c boolean? (-> (>=/c 5) (>=/c 5))) + (first-or/c boolean? (-> (>=/c 5) (>=/c 5)))) + (test-name 'mumble (let ([frotz/c integer?] [bazzle/c boolean?]) (flat-named-contract 'mumble @@ -167,6 +177,29 @@ (-> (>=/c 5) (>=/c 5)) (-> (<=/c 5) (<=/c 5) (<=/c 5)))) + (test-name '(first-or/c) (first-or/c)) + (test-name 'integer? (first-or/c integer?)) + (test-name '(first-or/c integer? gt0?) (first-or/c integer? (let ([gt0? (lambda (x) (> x 0))]) gt0?))) + (test-name '(first-or/c integer? boolean?) + (first-or/c (flat-contract integer?) + (flat-contract boolean?))) + (test-name '(first-or/c integer? boolean?) + (first-or/c integer? boolean?)) + (test-name '(first-or/c (-> (>=/c 5) (>=/c 5)) boolean?) + (first-or/c (-> (>=/c 5) (>=/c 5)) boolean?)) + (test-name '(first-or/c boolean? (-> (>=/c 5) (>=/c 5))) + (first-or/c boolean? (-> (>=/c 5) (>=/c 5)))) + (test-name '(first-or/c (-> (>=/c 5) (>=/c 5)) + (-> (<=/c 5) (<=/c 5) (<=/c 5))) + (first-or/c (-> (>=/c 5) (>=/c 5)) + (-> (<=/c 5) (<=/c 5) (<=/c 5)))) + (test-name '(first-or/c boolean? + (-> (>=/c 5) (>=/c 5)) + (-> (<=/c 5) (<=/c 5) (<=/c 5))) + (first-or/c boolean? + (-> (>=/c 5) (>=/c 5)) + (-> (<=/c 5) (<=/c 5) (<=/c 5)))) + (test-name 'any/c (and/c)) (test-name '(and/c any/c) (and/c any/c)) (test-name '(and/c any/c any/c) (and/c any/c any/c)) diff --git a/pkgs/racket-test/tests/racket/contract/obligations.rkt b/pkgs/racket-test/tests/racket/contract/obligations.rkt index 979dbfd86f..4b11f7e406 100644 --- a/pkgs/racket-test/tests/racket/contract/obligations.rkt +++ b/pkgs/racket-test/tests/racket/contract/obligations.rkt @@ -94,4 +94,12 @@ '((racket/contract:contract (vector-immutable/c) ()) (racket/contract:positive-position a) (racket/contract:positive-position b) - (racket/contract:positive-position c)))) + (racket/contract:positive-position c))) + (test-obligations '(or/c a b) + '((racket/contract:contract (or/c) ()) + (racket/contract:positive-position a) + (racket/contract:positive-position b))) + (test-obligations '(first-or/c a b) + '((racket/contract:contract (first-or/c) ()) + (racket/contract:positive-position a) + (racket/contract:positive-position b)))) diff --git a/pkgs/racket-test/tests/racket/contract/or-and.rkt b/pkgs/racket-test/tests/racket/contract/or-and.rkt index 32cecad7ad..6c94591d7b 100644 --- a/pkgs/racket-test/tests/racket/contract/or-and.rkt +++ b/pkgs/racket-test/tests/racket/contract/or-and.rkt @@ -93,7 +93,7 @@ 'pos 'neg) exn:fail?) - + (test/spec-passed/result 'or/c-ordering '(let ([x '()]) @@ -238,4 +238,147 @@ number?) (λ (x) 1) 'pos 'neg) - (lambda (x) 1)))) + (lambda (x) 1))) + + (test/pos-blame + 'first-or/c1 + '(contract (first-or/c false/c) #t 'pos 'neg)) + + (test/spec-passed + 'first-or/c2 + '(contract (first-or/c false/c) #f 'pos 'neg)) + + (test/spec-passed + 'first-or/c3 + '((contract (first-or/c (-> integer? integer?)) (lambda (x) x) 'pos 'neg) 1)) + + (test/neg-blame + 'first-or/c4 + '((contract (first-or/c (-> integer? integer?)) (lambda (x) x) 'pos 'neg) #f)) + + (test/pos-blame + 'first-or/c5 + '((contract (first-or/c (-> integer? integer?)) (lambda (x) #f) 'pos 'neg) 1)) + + (test/spec-passed + 'first-or/c6 + '(contract (first-or/c false/c (-> integer? integer?)) #f 'pos 'neg)) + + (test/spec-passed + 'first-or/c7 + '((contract (first-or/c false/c (-> integer? integer?)) (lambda (x) x) 'pos 'neg) 1)) + + (test/spec-passed/result + 'first-or/c8 + '((contract ((first-or/c false/c (-> string?)) . -> . any) + (λ (y) y) + 'pos + 'neg) + #f) + #f) + + (test/spec-passed/result + 'first-or/c9 + '((contract (first-or/c (-> string?) (-> integer? integer?)) + (λ () "x") + 'pos + 'neg)) + "x") + + (test/spec-passed/result + 'first-or/c10 + '((contract (first-or/c (-> string?) (-> integer? integer?)) + (λ (x) x) + 'pos + 'neg) + 1) + 1) + + (test/pos-blame + 'first-or/c11 + '(contract (first-or/c (-> string?) (-> integer? integer?)) + 1 + 'pos + 'neg)) + + (test/pos-blame + 'first-or/c12 + '((contract (first-or/c (-> string?) (-> integer? integer?)) + 1 + 'pos + 'neg) + 'x)) + + (test/pos-blame + 'first-or/c13 + '(contract (first-or/c not) #t 'pos 'neg)) + + (test/spec-passed + 'first-or/c14 + '(contract (first-or/c not) #f 'pos 'neg)) + + (test/spec-passed/result + 'first-or/c-not-error-early + '(begin (first-or/c (-> integer? integer?) (-> boolean? boolean?)) + 1) + 1) + + (test/spec-passed/result + 'contract-not-an-error-test4-ior + '((contract (first-or/c (-> integer? integer?) (-> boolean? boolean?)) + (λ (x) x) + 'pos + 'neg) 1) + 1) + + (test/spec-passed/result + 'first-or/c-ordering + '(let ([x '()]) + (contract (first-or/c (lambda (y) (set! x (cons 2 x)) #f) (lambda (y) (set! x (cons 1 x)) #t)) + 'anything + 'pos + 'neg) + x) + '(1 2)) + + (test/spec-passed/result + 'first-or/c-ordering2 + '(let ([x '()]) + (contract (first-or/c (lambda (y) (set! x (cons 2 x)) #t) (lambda (y) (set! x (cons 1 x)) #t)) + 'anything + 'pos + 'neg) + x) + '(2)) + + (test/spec-passed + 'first-or/c-hmm + '(let ([funny/c (first-or/c (and/c procedure? (-> any)) (listof (-> number?)))]) + (contract (-> funny/c any) void 'pos 'neg))) + + + (test/spec-passed + 'first-or/c-opt-unknown-flat + '(let () + (define arr (-> number? number?)) + ((contract (opt/c (first-or/c not arr)) (λ (x) x) 'pos 'neg) 1))) + + + (test/neg-blame + 'ho-first-or/c-val-first1 + '((contract (-> (first-or/c (-> number?) + (-> number? number?)) + number?) + (λ (x) 1) + 'pos 'neg) + (lambda (x y z) 1))) + + (test/spec-passed/result + 'ho-first-or/c-val-first2 + '((contract (-> (first-or/c (-> number? number?) + (-> number? number?)) + number?) + (λ (x) (x 1)) + 'pos 'neg) + (lambda (x) (+ x 1))) + 2)) diff --git a/pkgs/racket-test/tests/racket/contract/parametric.rkt b/pkgs/racket-test/tests/racket/contract/parametric.rkt index 888f71d01e..819d9a761d 100644 --- a/pkgs/racket-test/tests/racket/contract/parametric.rkt +++ b/pkgs/racket-test/tests/racket/contract/parametric.rkt @@ -53,6 +53,14 @@ 'pos 'neg) 1 "foo") 1) + + (test/spec-passed/result + 'parametric->/c6b + '((contract (parametric->/c (A B) (-> A B (first-or/c A B))) + (λ (x y) x) + 'pos 'neg) + 1 "foo") + 1) (test/pos-blame 'parametric->/c7 diff --git a/pkgs/racket-test/tests/racket/contract/predicates.rkt b/pkgs/racket-test/tests/racket/contract/predicates.rkt index 535c256171..031d9baaf6 100644 --- a/pkgs/racket-test/tests/racket/contract/predicates.rkt +++ b/pkgs/racket-test/tests/racket/contract/predicates.rkt @@ -10,6 +10,11 @@ (ctest #t flat-contract? (or/c (flat-contract integer?) (flat-contract boolean?))) (ctest #t flat-contract? (or/c integer? boolean?)) + (ctest #t flat-contract? (first-or/c)) + (ctest #t flat-contract? (first-or/c integer? (lambda (x) (> x 0)))) + (ctest #t flat-contract? (first-or/c (flat-contract integer?) (flat-contract boolean?))) + (ctest #t flat-contract? (first-or/c integer? boolean?)) + (ctest #t flat-contract? (-> any/c any/c any)) (ctest #t flat-contract? (and/c)) @@ -196,7 +201,7 @@ (cons/c (recursive-contract ctc #:flat) (recursive-contract ctc #:flat)))]) ctc)) - + (ctest #f flat-contract? (letrec ([ctc (or/c number? (box/c (recursive-contract ctc #:chaperone)))]) ctc)) @@ -204,6 +209,20 @@ (box/c (recursive-contract ctc #:chaperone)))]) ctc)) (ctest #f impersonator-contract? (letrec ([ctc (or/c number? + (box/c (recursive-contract ctc #:chaperone)))]) + ctc)) + (ctest #t flat-contract? (letrec ([ctc (first-or/c number? + (cons/c (recursive-contract ctc #:flat) + (recursive-contract ctc #:flat)))]) + ctc)) + + (ctest #f flat-contract? (letrec ([ctc (first-or/c number? + (box/c (recursive-contract ctc #:chaperone)))]) + ctc)) + (ctest #t chaperone-contract? (letrec ([ctc (first-or/c number? + (box/c (recursive-contract ctc #:chaperone)))]) + ctc)) + (ctest #f impersonator-contract? (letrec ([ctc (first-or/c number? (box/c (recursive-contract ctc #:chaperone)))]) ctc)) diff --git a/pkgs/racket-test/tests/racket/contract/stream.rkt b/pkgs/racket-test/tests/racket/contract/stream.rkt index 81c15f22e5..50ea9373d1 100644 --- a/pkgs/racket-test/tests/racket/contract/stream.rkt +++ b/pkgs/racket-test/tests/racket/contract/stream.rkt @@ -31,4 +31,14 @@ (test/pos-blame 'stream/c7 '(stream-first (stream-rest (contract (stream/c (and/c integer? (or/c 0 positive?))) + (stream 0 -1) 'pos 'neg)))) + + (test/spec-passed + 'stream/c8 + '(stream-first (stream-rest (contract (stream/c (and/c integer? (first-or/c 0 positive?))) + (in-naturals) 'pos 'neg)))) + + (test/pos-blame + 'stream/c9 + '(stream-first (stream-rest (contract (stream/c (and/c integer? (first-or/c 0 positive?))) (stream 0 -1) 'pos 'neg))))) diff --git a/pkgs/racket-test/tests/racket/contract/stronger.rkt b/pkgs/racket-test/tests/racket/contract/stronger.rkt index 1a159ab71a..38d5c5d1a2 100644 --- a/pkgs/racket-test/tests/racket/contract/stronger.rkt +++ b/pkgs/racket-test/tests/racket/contract/stronger.rkt @@ -108,6 +108,38 @@ (ctest #t contract-stronger? (-> (or/c #f number?) any/c) (-> number? any/c)) (ctest #f contract-stronger? (-> (or/c #f number?)) (-> number?)) (ctest #f contract-stronger? (-> number? any/c) (-> (or/c #f number?) any/c)) + + (ctest #t contract-stronger? (first-or/c null? any/c) (first-or/c null? any/c)) + (ctest #f contract-stronger? (first-or/c null? any/c) (first-or/c boolean? any/c)) + (ctest #t contract-stronger? (first-or/c null? boolean?) (first-or/c null? boolean?)) + (ctest #t contract-stronger? (first-or/c null? boolean?) (first-or/c boolean? null?)) + (ctest #t contract-stronger? + (first-or/c null? (-> integer? integer?)) + (first-or/c null? (-> integer? integer?))) + (ctest #f contract-stronger? + (first-or/c null? (-> boolean? boolean?)) + (first-or/c null? (-> integer? integer?))) + (ctest #f contract-stronger? (first-or/c number? #f) number?) + (ctest #t contract-stronger? number? (first-or/c number? #f)) + (ctest #f contract-stronger? (first-or/c (-> number? number?) #f) (-> number? number?)) + (ctest #t contract-stronger? (-> number? number?) (first-or/c (-> number? number?) #f)) + (ctest #f contract-stronger? (first-or/c (-> number? number?) (-> number? number? number?) #f) #f) + (ctest #t contract-stronger? #f (first-or/c (-> number? number?) (-> number? number? number?) #f)) + (ctest #t contract-stronger? (first-or/c real?) (first-or/c integer? real?)) + (ctest #t contract-stronger? (-> number?) (-> (first-or/c #f number?))) + (ctest #t contract-stronger? (-> (first-or/c #f number?) any/c) (-> number? any/c)) + (ctest #f contract-stronger? (-> (first-or/c #f number?)) (-> number?)) + (ctest #f contract-stronger? (-> number? any/c) (-> (first-or/c #f number?) any/c)) + + (ctest #t contract-stronger? (first-or/c null? any/c) (or/c null? any/c)) + (ctest #f contract-stronger? (first-or/c null? any/c) (or/c boolean? any/c)) + (ctest #t contract-stronger? (first-or/c null? boolean?) (or/c null? boolean?)) + (ctest #t contract-stronger? (first-or/c null? boolean?) (or/c boolean? null?)) + + (ctest #t contract-stronger? (or/c null? any/c) (first-or/c null? any/c)) + (ctest #f contract-stronger? (or/c null? any/c) (first-or/c boolean? any/c)) + (ctest #t contract-stronger? (or/c null? boolean?) (first-or/c null? boolean?)) + (ctest #t contract-stronger? (or/c null? boolean?) (first-or/c boolean? null?)) (ctest #t contract-stronger? number? number?) (ctest #f contract-stronger? boolean? number?) @@ -226,6 +258,10 @@ `(let () (define x (flat-rec-contract x (or/c (cons/c x '()) '()))) (,test #t contract-stronger? x (or/c (cons/c x '()) '())))) + (contract-eval + `(let () + (define x (flat-rec-contract x (first-or/c (cons/c x '()) '()))) + (,test #t contract-stronger? x (first-or/c (cons/c x '()) '())))) (ctest #t contract-stronger? "x" string?) (ctest #f contract-stronger? string? "x") @@ -263,10 +299,13 @@ (ctest #f contract-stronger? (syntax/c (<=/c 4)) (syntax/c (<=/c 3))) (ctest #t contract-stronger? (parametric->/c (x) (-> x x)) (parametric->/c (x) (-> x (or/c x #f)))) + (ctest #t contract-stronger? (parametric->/c (x) (-> x x)) (parametric->/c (x) (-> x (first-or/c x #f)))) (ctest #f contract-stronger? (parametric->/c (x y) (-> x y)) (parametric->/c (x y) (-> x x y))) (contract-eval `(define α (new-∀/c))) (ctest #t contract-stronger? (-> α α) (-> α (or/c #f α))) (ctest #f contract-stronger? (-> α (or/c #f α)) (-> α α)) + (ctest #t contract-stronger? (-> α α) (-> α (first-or/c #f α))) + (ctest #f contract-stronger? (-> α (first-or/c #f α)) (-> α α)) (ctest #t contract-stronger? (class/c (m (-> any/c (<=/c 3)))) @@ -464,6 +503,64 @@ [c (a b) (or/c #f (mk-c a))]))]) (,test #t contract-stronger? (mk-c 1) (mk-c 2))))) + (contract-eval + `(let () + (define (non-zero? x) (not (zero? x))) + (define list-of-numbers + (first-or/c null? + (couple/c number? + (recursive-contract list-of-numbers)))) + (define (short-list/less-than n) + (first-or/c null? + (couple/c (<=/c n) + (first-or/c null? + (couple/c (<=/c n) + any/c))))) + (define (short-sorted-list/less-than n) + (first-or/c null? + (couple/dc + [hd (<=/c n)] + [tl (hd) (first-or/c null? + (couple/c (<=/c hd) + any/c))]))) + + (define (sorted-list/less-than n) + (first-or/c null? + (couple/dc + [hd (<=/c n)] + [tl (hd) (sorted-list/less-than hd)]))) + + ;; for some reason, the `n' makes it harder to optimize. + ;; without it, this test isn't as good a test + (define (closure-comparison-test n) + (couple/dc + [hd any/c] + [tl (hd) any/c])) + + (,test #t contract-stronger? (couple/c any/c any/c) (couple/c any/c any/c)) + (,test #f contract-stronger? (couple/c (>=/c 2) (>=/c 3)) (couple/c (>=/c 4) (>=/c 5))) + (,test #t contract-stronger? (couple/c (>=/c 4) (>=/c 5)) (couple/c (>=/c 2) (>=/c 3))) + (,test #f contract-stronger? (couple/c (>=/c 1) (>=/c 5)) (couple/c (>=/c 5) (>=/c 1))) + (let ([ctc (couple/dc [hd any/c] [tl (hd) any/c])]) + (,test #t contract-stronger? ctc ctc)) + (let ([ctc (couple/dc [hd any/c] [tl (hd) (<=/c hd)])]) + (,test #t contract-stronger? ctc ctc)) + (,test #t contract-stronger? list-of-numbers list-of-numbers) + (,test #t contract-stronger? (short-list/less-than 4) (short-list/less-than 5)) + (,test #f contract-stronger? (short-list/less-than 5) (short-list/less-than 4)) + (,test #t contract-stronger? (short-sorted-list/less-than 4) (short-sorted-list/less-than 5)) + (,test #f contract-stronger? (short-sorted-list/less-than 5) (short-sorted-list/less-than 4)) + (,test #t contract-stronger? (sorted-list/less-than 4) (sorted-list/less-than 5)) + (,test #f contract-stronger? (sorted-list/less-than 5) (sorted-list/less-than 4)) + (,test #t contract-stronger? (closure-comparison-test 4) (closure-comparison-test 5)) + + (letrec ([mk-c + (λ (x) + (triple/dc [a (<=/c x)] + [b any/c] + [c (a b) (or/c #f (mk-c a))]))]) + (,test #t contract-stronger? (mk-c 1) (mk-c 2))))) + (contract-eval `(let () diff --git a/pkgs/racket-test/tests/racket/contract/struct-dc.rkt b/pkgs/racket-test/tests/racket/contract/struct-dc.rkt index 5da41f8604..bc510a082e 100644 --- a/pkgs/racket-test/tests/racket/contract/struct-dc.rkt +++ b/pkgs/racket-test/tests/racket/contract/struct-dc.rkt @@ -416,6 +416,22 @@ 'pos 'neg)))) 2) + + (test/spec-passed/result + 'struct/dc-12b + '(let () + (struct kons (hd tl) #:transparent) + (define (unknown-function a) (=/c a)) + (define-opt/c (f a b) + (first-or/c not + (struct/dc kons + [hd (unknown-function a)] + [tl () #:lazy (first-or/c #f (f b a))]))) + (kons-hd (kons-tl (contract (f 1 2) + (kons 1 (kons 2 #f)) + 'pos + 'neg)))) + 2) (test/spec-passed 'struct/dc-13 diff --git a/racket/collects/racket/contract/base.rkt b/racket/collects/racket/contract/base.rkt index 3992d7610a..ccb1991c26 100644 --- a/racket/collects/racket/contract/base.rkt +++ b/racket/collects/racket/contract/base.rkt @@ -50,7 +50,7 @@ check-between/c check-unary-between/c random-any/c) - symbols or/c one-of/c + symbols or/c first-or/c one-of/c flat-rec-contract provide/contract ;(for-syntax make-provide/contract-transformer) ;; not documented! diff --git a/racket/collects/racket/contract/private/opters.rkt b/racket/collects/racket/contract/private/opters.rkt index 14d849abee..0ea739207f 100644 --- a/racket/collects/racket/contract/private/opters.rkt +++ b/racket/collects/racket/contract/private/opters.rkt @@ -64,7 +64,8 @@ (define ps-optres (opt/i (opt/info-add-blame-context opt/info (λ (blame-stx) - #`(blame-add-or-context #,blame-stx))) + #`(blame-add-or-context #,blame-stx) + blame-stx)) (car ps))) (if (optres-flat ps-optres) (loop (cdr ps) diff --git a/racket/collects/racket/contract/private/orc.rkt b/racket/collects/racket/contract/private/orc.rkt index d1ee02c67f..13db533fee 100644 --- a/racket/collects/racket/contract/private/orc.rkt +++ b/racket/collects/racket/contract/private/orc.rkt @@ -7,8 +7,9 @@ "misc.rkt" (for-syntax racket/base)) -(provide symbols or/c one-of/c +(provide symbols or/c first-or/c one-of/c blame-add-or-context + blame-add-ior-context (rename-out [_flat-rec-contract flat-rec-contract])) (define/subexpression-pos-prop or/c @@ -22,7 +23,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 @@ -30,19 +31,7 @@ (loop ho-contracts (cons arg flat-contracts) (cdr args))] [else (loop (cons arg ho-contracts) flat-contracts (cdr args))]))]))) - (define pred - (cond - [(null? flat-contracts) not] - [else - (let loop ([fst (car flat-contracts)] - [rst (cdr flat-contracts)]) - (let ([fst-pred (flat-contract-predicate fst)]) - (cond - [(null? rst) fst-pred] - [else - (let ([r (loop (car rst) (cdr rst))]) - (λ (x) (or (fst-pred x) (r x))))])))])) - + (define pred (make-flat-predicate flat-contracts)) (cond [(null? ho-contracts) (make-flat-or/c pred flat-contracts)] @@ -57,6 +46,32 @@ (make-chaperone-multi-or/c name flat-contracts ho-contracts) (make-impersonator-multi-or/c name flat-contracts ho-contracts))])])) +(define/subexpression-pos-prop first-or/c + (case-lambda + [() (make-none/c '(first-or/c))] + [(x) (coerce-contract 'first-or/c x)] + [raw-args + (define args (coerce-contracts 'first-or/c raw-args)) + (cond + [(andmap flat-contract? args) + (make-flat-first-or/c (make-flat-predicate args) args)] + [(andmap chaperone-contract? args) + (make-chaperone-first-or/c args)] + [else (make-impersonator-first-or/c args)])])) + +(define (make-flat-predicate flat-contracts) + (cond + [(null? flat-contracts) not] + [else + (let loop ([fst (car flat-contracts)] + [rst (cdr flat-contracts)]) + (let ([fst-pred (flat-contract-predicate fst)]) + (cond + [(null? rst) fst-pred] + [else + (let ([r (loop (car rst) (cdr rst))]) + (λ (x) (or (fst-pred x) (r x))))])))])) + (define (single-or/c-projection ctc) (let ([c-proc (contract-projection (single-or/c-ho-ctc ctc))] [pred (single-or/c-pred ctc)]) @@ -70,16 +85,20 @@ (define (single-or/c-late-neg-projection ctc) (define c-proj (get/build-late-neg-projection (single-or/c-ho-ctc ctc))) + (define c-first-order (contract-first-order (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 neg-party) - (if (pred val) - val - (p-app val neg-party))))) + (cond + [(pred val) val] + [(c-first-order val) (p-app val neg-party)] + [else (raise-none-or-matched blame val #f)])))) (define (blame-add-or-context blame) (blame-add-context blame "a part of the or/c of")) +(define (blame-add-ior-context blame) + (blame-add-context blame "a part of the first-or/c of")) (define (single-or/c-first-order ctc) (let ([pred (single-or/c-pred ctc)] @@ -117,6 +136,7 @@ (multi-or/c-ho-ctcs ctc))] [(flat-or/c? ctc) (flat-or/c-flat-ctcs ctc)] + [(base-first-or/c? ctc) (base-first-or/c-ctcs ctc)] [else #f])) (define (or/c-exercise ho-contracts) @@ -231,7 +251,7 @@ [first-order-checks (map (λ (x) (contract-first-order x)) ho-contracts)] [predicates (map flat-contract-predicate (multi-or/c-flat-ctcs ctc))]) (λ (blame) - (define disj-blame (blame-add-context blame "a part of the or/c of")) + (define disj-blame (blame-add-or-context blame)) (define partial-contracts (for/list ([c-proc (in-list c-procs)]) (c-proc disj-blame))) @@ -249,9 +269,7 @@ [(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-none-or-matched blame val #f))] [((car checks) val) (if candidate-proc (raise-blame-error blame val @@ -298,9 +316,7 @@ [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-none-or-matched blame val neg-party)])] [((car checks) val) (if candidate-c-proj (raise-blame-error blame val #:missing-party neg-party @@ -322,6 +338,11 @@ candidate-c-proj candidate-contract)]))])))) +(define (raise-none-or-matched blame val neg-party) + (raise-blame-error blame val #:missing-party neg-party + '("none of the branches of the or/c matched" given: "~e") + val)) + (define (multi-or/c-first-order ctc) (let ([flats (map flat-contract-predicate (multi-or/c-flat-ctcs ctc))] [hos (map (λ (x) (contract-first-order x)) (multi-or/c-ho-ctcs ctc))]) @@ -392,7 +413,7 @@ #:name (λ (ctc) (apply build-compound-type-name - 'or/c + (if (flat-first-or/c? ctc) 'first-or/c 'or/c) (flat-or/c-flat-ctcs ctc))) #:stronger (λ (this that) @@ -432,6 +453,73 @@ (for/and ([c (in-list (flat-or/c-flat-ctcs ctc))]) (list-contract? c))))) +(define-struct (flat-first-or/c flat-or/c) ()) + +(define (first-or/c-proj ctc) + (define contracts (base-first-or/c-ctcs ctc)) + (define c-procs (map (λ (x) (contract-projection x)) contracts)) + (define first-order-checks (map (λ (x) (contract-first-order x)) contracts)) + (λ (blame) + (define disj-blame (blame-add-ior-context blame)) + (define partial-contracts + (for/list ([c-proc (in-list c-procs)]) + (c-proc disj-blame))) + (λ (val) + (let loop ([checks first-order-checks] + [procs partial-contracts] + [contracts contracts]) + (cond + [(null? checks) + (raise-none-ior-matched blame val #f)] + [else + (cond + [((car checks) val) + ((car procs) val)] + [else + (loop (cdr checks) + (cdr procs) + (cdr contracts))])]))))) + +(define (first-or/c-late-neg-proj ctc) + (define ho-contracts (base-first-or/c-ctcs ctc)) + (define c-projs (map get/build-late-neg-projection ho-contracts)) + (define first-order-checks (map (λ (x) (contract-first-order x)) ho-contracts)) + (λ (blame) + (define blame-w-context (blame-add-ior-context blame)) + (define c-projs+blame (map (λ (c-proj) (c-proj blame-w-context)) c-projs)) + (λ (val neg-party) + (let loop ([checks first-order-checks] + [c-projs c-projs+blame] + [contracts ho-contracts]) + (cond + [(null? checks) + (raise-none-ior-matched blame val neg-party)] + [else + (cond + [((car checks) val) + ((car c-projs) val neg-party)] + [else + (loop (cdr checks) + (cdr c-projs) + (cdr contracts))])]))))) + +(define (raise-none-ior-matched blame val neg-party) + (raise-blame-error blame val #:missing-party neg-party + '("none of the branches of the first-or/c matched" given: "~e") + val)) + +(define (first-or/c-name ctc) + (apply build-compound-type-name + 'first-or/c + (base-first-or/c-ctcs ctc))) + +(define (first-or/c-first-order ctc) + (define preds (map contract-first-order (base-first-or/c-ctcs ctc))) + (λ (x) (ormap (lambda (p?) (p? x)) preds))) + +(define (first-or/c-list-contract? c) + (for/and ([c (in-list (base-first-or/c-ctcs c))]) + (list-contract? c))) (define/final-prop (symbols s1 . s2s) (define ss (cons s1 s2s)) @@ -444,7 +532,34 @@ ss))) (apply or/c ss)) +(define-struct base-first-or/c (ctcs) + #:property prop:custom-write custom-write-property-proc + #:property prop:orc-contract + (λ (this) (base-first-or/c-ctcs this))) +(define-struct (chaperone-first-or/c base-first-or/c) () + #:property prop:chaperone-contract + (parameterize ([skip-projection-wrapper? #t]) + (build-chaperone-contract-property + #:projection first-or/c-proj + #:late-neg-projection first-or/c-late-neg-proj + #:name first-or/c-name + #:first-order first-or/c-first-order + #:stronger multi-or/c-stronger? + #:generate (λ (ctc) (or/c-generate ctc (base-first-or/c-ctcs ctc))) + #:exercise (λ (ctc) (or/c-exercise (base-first-or/c-ctcs ctc))) + #:list-contract? first-or/c-list-contract?))) +(define-struct (impersonator-first-or/c base-first-or/c) () + #:property prop:contract + (build-contract-property + #:projection first-or/c-proj + #:late-neg-projection first-or/c-late-neg-proj + #:name first-or/c-name + #:first-order first-or/c-first-order + #:stronger generic-or/c-stronger? + #:generate (λ (ctc) (or/c-generate ctc (base-first-or/c-ctcs ctc))) + #:exercise (λ (ctc) (or/c-exercise (base-first-or/c-ctcs ctc))) + #:list-contract? first-or/c-list-contract?)) (define/final-prop (one-of/c . elems) (for ([arg (in-list elems)] From dd5029947c2c8fa6cccce8e12ae81ca804aa6bc0 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 8 Nov 2015 06:42:01 -0600 Subject: [PATCH 036/369] use latex-friendly characters --- .../scribblings/reference/sequences.scrbl | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/sequences.scrbl b/pkgs/racket-doc/scribblings/reference/sequences.scrbl index c49ced9fb3..3285dc398c 100644 --- a/pkgs/racket-doc/scribblings/reference/sequences.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sequences.scrbl @@ -388,12 +388,14 @@ each element in the sequence. (code:comment @#,t{Given a directory tree:}) (code:comment @#,t{}) (code:comment @#,t{ /example}) - (code:comment @#,t{ ├── a}) - (code:comment @#,t{ │ ├── alpha}) - (code:comment @#,t{ │ └── apple}) - (code:comment @#,t{ ├── b}) - (code:comment @#,t{ │ └── beta}) - (code:comment @#,t{ └── c}) + (code:comment @#,t{ +-- a}) + (code:comment @#,t{ | +-- alpha}) + (code:comment @#,t{ | +-- apple}) + (code:comment @#,t{ |}) + (code:comment @#,t{ +-- b}) + (code:comment @#,t{ | +-- beta}) + (code:comment @#,t{ |}) + (code:comment @#,t{ +-- c}) (code:comment @#,t{}) (eval:alts (parameterize ([current-directory "/example"]) From db464d5ed2445432a38b19edc967eb988c9d28c7 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 8 Nov 2015 07:56:39 -0600 Subject: [PATCH 037/369] make a little more space and stop decoding (improvements to dd50299) --- .../scribblings/reference/sequences.scrbl | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/sequences.scrbl b/pkgs/racket-doc/scribblings/reference/sequences.scrbl index 3285dc398c..bc7398b19c 100644 --- a/pkgs/racket-doc/scribblings/reference/sequences.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sequences.scrbl @@ -385,18 +385,20 @@ each element in the sequence. a sequence. @examples[ - (code:comment @#,t{Given a directory tree:}) - (code:comment @#,t{}) - (code:comment @#,t{ /example}) - (code:comment @#,t{ +-- a}) - (code:comment @#,t{ | +-- alpha}) - (code:comment @#,t{ | +-- apple}) - (code:comment @#,t{ |}) - (code:comment @#,t{ +-- b}) - (code:comment @#,t{ | +-- beta}) - (code:comment @#,t{ |}) - (code:comment @#,t{ +-- c}) - (code:comment @#,t{}) + (code:comment "Given a directory tree:") + (code:comment "") + (code:comment " /example") + (code:comment " +-- a") + (code:comment " | |") + (code:comment " | +-- alpha") + (code:comment " | +-- apple") + (code:comment " |") + (code:comment " +-- b") + (code:comment " | |") + (code:comment " | +-- beta") + (code:comment " |") + (code:comment " +-- c") + (code:comment "") (eval:alts (parameterize ([current-directory "/example"]) (for ([p (in-directory)]) From 2ed6c01e569c3c26768042a21f9954e522381999 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 7 Nov 2015 18:39:38 -0700 Subject: [PATCH 038/369] fix space-safety annotation for nested `if`s Closes PR 15176 --- pkgs/racket-test-core/tests/racket/will.rktl | 19 +++++++++++ racket/src/racket/src/sfs.c | 34 ++++++++++++++++++-- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/will.rktl b/pkgs/racket-test-core/tests/racket/will.rktl index a10573e4cc..d43dd1c4fb 100644 --- a/pkgs/racket-test-core/tests/racket/will.rktl +++ b/pkgs/racket-test-core/tests/racket/will.rktl @@ -293,6 +293,25 @@ (if (car p) (add1 n) n)))) (test #t < fraction-retained 1/2))) +;; ---------------------------------------- +;; Check space safety conversion for nested `if`s + +(let ([ht (make-weak-hasheq)]) + (letrec ([f (lambda (false long-vector values n) + (begin + (if false + (if (random) 7 (length long-vector)) + 'long-vector-not-cleared-here) + (if (zero? n) + (begin + (collect-garbage) + (hash-count ht)) + (let ([vec (make-vector 1000)]) + (hash-set! ht vec #t) + (values (f false vec values (sub1 n)))))))]) + (set! f f) + (test #t < (f #f #f values 100) 33))) + ;; ---------------------------------------- (report-errs) diff --git a/racket/src/racket/src/sfs.c b/racket/src/racket/src/sfs.c index 8196415d0b..e2f93aeb71 100644 --- a/racket/src/racket/src/sfs.c +++ b/racket/src/racket/src/sfs.c @@ -424,13 +424,14 @@ static Scheme_Object *sfs_one_branch(SFS_Info *info, int ip, SFS_LOG(printf(" |%d %d %d\n", i + t_min_t, n, info->max_nontail)); info->max_used[i + t_min_t] = n; info->max_calls[i + t_min_t] = info->max_nontail; - } + } else + SCHEME_VEC_ELS(t_vec)[i] = scheme_false; } } } /* If the other branch has last use for something not used in this branch, and if there's a non-tail call in this branch - of later, then we'll have to start with explicit clears. + or later, then we'll have to start with explicit clears. Note that it doesn't matter whether the other branch actually clears them (i.e., the relevant non-tail call might be only in this branch). */ @@ -456,7 +457,7 @@ static Scheme_Object *sfs_one_branch(SFS_Info *info, int ip, n = SCHEME_INT_VAL(o); pos = i + t_min_t; at_ip = info->max_used[pos]; - SFS_LOG(printf(" ?%d %d %d\n", pos, n, at_ip)); + SFS_LOG(printf(" ?%d[%d] %d %d\n", pos, i, n, at_ip)); /* is last use in other branch? */ if (((!delta && (at_ip == ip)) || (delta && (at_ip == n)))) { @@ -526,6 +527,25 @@ static Scheme_Object *sfs_one_branch(SFS_Info *info, int ip, return tbranch; } +static void sfs_restore_one_branch(SFS_Info *info, int ip, + Scheme_Object *vec, int delta) +{ + int t_min_t, t_cnt, i; + Scheme_Object *t_vec; + + t_vec = SCHEME_VEC_ELS(vec)[(delta * SFS_BRANCH_W) + 1]; + + if (SCHEME_FALSEP(t_vec)) return; + + t_min_t = SCHEME_INT_VAL(SCHEME_VEC_ELS(vec)[delta * SFS_BRANCH_W]); + t_cnt = SCHEME_VEC_SIZE(t_vec); + + for (i = 0; i < t_cnt; i++) { + if (SCHEME_TRUEP(SCHEME_VEC_ELS(t_vec)[i])) + info->max_used[i + t_min_t] = ip; + } +} + static Scheme_Object *sfs_branch(Scheme_Object *o, SFS_Info *info) { Scheme_Branch_Rec *b; @@ -579,6 +599,14 @@ static Scheme_Object *sfs_branch(Scheme_Object *o, SFS_Info *info) info->max_nontail = ip + 1; } + if (info->pass) { + /* Restore "outside" view for both branches, so that + the numbers after `if` for the second pass match + the numbers after the first pass: */ + sfs_restore_one_branch(info, ip, vec, 0); + sfs_restore_one_branch(info, ip, vec, 1); + } + SFS_LOG(printf(" done if: %d %d\n", min_t, max_t)); info->min_touch = min_t; From 611899764f29608f09cee35ced1a115b36baadd4 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 8 Nov 2015 09:06:49 -0600 Subject: [PATCH 039/369] pass along neg-party closes #1126 --- racket/collects/racket/contract/private/orc.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/racket/contract/private/orc.rkt b/racket/collects/racket/contract/private/orc.rkt index 13db533fee..1dca65b0f3 100644 --- a/racket/collects/racket/contract/private/orc.rkt +++ b/racket/collects/racket/contract/private/orc.rkt @@ -93,7 +93,7 @@ (cond [(pred val) val] [(c-first-order val) (p-app val neg-party)] - [else (raise-none-or-matched blame val #f)])))) + [else (raise-none-or-matched blame val neg-party)])))) (define (blame-add-or-context blame) (blame-add-context blame "a part of the or/c of")) From a8f748abeb72d105f77859bc394fda0580765d63 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 8 Nov 2015 15:41:03 -0600 Subject: [PATCH 040/369] clarify some invariants of make-contract and friends --- .../scribblings/reference/contracts.scrbl | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index 6b92ebb301..6ddd1022d9 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -1960,11 +1960,12 @@ contracts is @racketresult[anonymous-chaperone-contract], and for flat contracts is @racketresult[anonymous-flat-contract]. The first-order predicate @racket[test] can be used to determine which values -the contract applies to; usually, this is the set of values for which the +the contract applies to; this must be the set of values for which the contract fails immediately without any higher-order wrapping. This test is used -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. +by @racket[contract-first-order-passes?], and indirectly by @racket[or/c] + and @racket[from-or/c] to determine which higher-order contract to wrap a + value with when there are multiple higher-order contracts to choose from. + The default test accepts any value. 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 @@ -1986,6 +1987,11 @@ 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. +The projection arguments (@racket[late-neg-proj], @racket[proj], and + @racket[val-first-proj]) must be in sync with the @racket[test] argument. + In particular, if the test argument returns @racket[#f] for some value, + then the projections must raise a blame error for that value. + Projections for chaperone contracts must produce a value that passes @racket[chaperone-of?] when compared with the original, uncontracted value. Projections for flat contracts must fail precisely when the first-order test From 023e2de5be560b3ba43a1310deb4b509d358d197 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 8 Nov 2015 19:37:24 -0600 Subject: [PATCH 041/369] Go back to using the nicer unicode picture of the directory now that Matthew added support for those characters to Scribble This reverts commit db464d5ed2445432a38b19edc967eb988c9d28c7. This reverts commit dd5029947c2c8fa6cccce8e12ae81ca804aa6bc0. --- .../scribblings/reference/sequences.scrbl | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/sequences.scrbl b/pkgs/racket-doc/scribblings/reference/sequences.scrbl index bc7398b19c..c49ced9fb3 100644 --- a/pkgs/racket-doc/scribblings/reference/sequences.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sequences.scrbl @@ -385,20 +385,16 @@ each element in the sequence. a sequence. @examples[ - (code:comment "Given a directory tree:") - (code:comment "") - (code:comment " /example") - (code:comment " +-- a") - (code:comment " | |") - (code:comment " | +-- alpha") - (code:comment " | +-- apple") - (code:comment " |") - (code:comment " +-- b") - (code:comment " | |") - (code:comment " | +-- beta") - (code:comment " |") - (code:comment " +-- c") - (code:comment "") + (code:comment @#,t{Given a directory tree:}) + (code:comment @#,t{}) + (code:comment @#,t{ /example}) + (code:comment @#,t{ ├── a}) + (code:comment @#,t{ │ ├── alpha}) + (code:comment @#,t{ │ └── apple}) + (code:comment @#,t{ ├── b}) + (code:comment @#,t{ │ └── beta}) + (code:comment @#,t{ └── c}) + (code:comment @#,t{}) (eval:alts (parameterize ([current-directory "/example"]) (for ([p (in-directory)]) From 54be64ad31c99679ec9243b745354a735fa8c281 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Sun, 8 Nov 2015 22:20:56 -0500 Subject: [PATCH 042/369] Restore permissive error message from `permissive/c`. Thanks to @rbfindler for the suggestion. --- racket/collects/xml/private/structures.rkt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/racket/collects/xml/private/structures.rkt b/racket/collects/xml/private/structures.rkt index cbd46deda3..c276c40d0b 100644 --- a/racket/collects/xml/private/structures.rkt +++ b/racket/collects/xml/private/structures.rkt @@ -51,8 +51,7 @@ (raise-blame-error blame v "not in permissive mode")))) #:first-order - (lambda (v) - (permissive-xexprs)))) + (lambda (v) #t))) ; content? : TST -> Bool (define content/c From 3d31d86bf541ba76e85329c22559b455e44f279f Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 10 Nov 2015 08:56:45 -0600 Subject: [PATCH 043/369] fix (-> any/c boolean?) for the case of an impersonated struct predicate closes #1129 --- pkgs/racket-test/tests/racket/contract/arrow.rkt | 7 +++++++ .../collects/racket/contract/private/arrow-val-first.rkt | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test/tests/racket/contract/arrow.rkt b/pkgs/racket-test/tests/racket/contract/arrow.rkt index 7d822464b7..9d436e3bcc 100644 --- a/pkgs/racket-test/tests/racket/contract/arrow.rkt +++ b/pkgs/racket-test/tests/racket/contract/arrow.rkt @@ -386,6 +386,13 @@ (test/pos-blame 'predicate/c13 '(contract (-> any/c boolean?) (λ (x #:y y) #t) 'pos 'neg)) + (test/pos-blame + 'predicate/c14 + '(contract (-> any/c boolean?) + (let () + (struct s ()) + ((impersonate-procedure s? (λ (x) (values (λ (r) "") x))) 11)) + '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 84bf657b79..931eeee516 100644 --- a/racket/collects/racket/contract/private/arrow-val-first.rkt +++ b/racket/collects/racket/contract/private/arrow-val-first.rkt @@ -1289,7 +1289,9 @@ given: "~e") f)) (cond - [(struct-predicate-procedure? f) #f] + [(and (struct-predicate-procedure? f) + (not (impersonator? f))) + #f] [(and (equal? (procedure-arity f) 1) (let-values ([(required mandatory) (procedure-keywords f)]) (and (null? required) From 4c6750286a487a988bec24275e1570ae64ff9093 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 9 Nov 2015 20:04:50 -0700 Subject: [PATCH 044/369] net/http-client: avoid race between EOF and collection close The race condition can result in an "input port is closed" error when a connection is used again. --- racket/collects/net/http-client.rkt | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/racket/collects/net/http-client.rkt b/racket/collects/net/http-client.rkt index b243241944..79d7de5ddf 100644 --- a/racket/collects/net/http-client.rkt +++ b/racket/collects/net/http-client.rkt @@ -184,9 +184,7 @@ (define (http-conn-response-port/chunked! hc #:close? [close? #f]) (define (http-pipe-chunk ip op) - (define (done) - (flush-output op) - (close-output-port op)) + (define (done) (void)) (define crlf-bytes (make-bytes 2)) (let loop ([last-bytes #f]) (define in-v (read-line ip eol-type)) @@ -248,11 +246,12 @@ (or (equal? method-bss #"HEAD") (equal? method-bss "HEAD") (equal? method-bss 'HEAD))) - (define raw-response-port + (define-values (raw-response-port wait-for-close?) (cond - [head? (open-input-bytes #"")] + [head? (values (open-input-bytes #"") #f)] [(regexp-member #rx#"^(?i:Transfer-Encoding: +chunked)$" headers) - (http-conn-response-port/chunked! hc #:close? #t)] + (values (http-conn-response-port/chunked! hc #:close? #t) + #t)] [(ormap (λ (h) (match (regexp-match #rx#"^(?i:Content-Length:) +(.+)$" h) [#f #f] @@ -262,9 +261,10 @@ headers) => (λ (count) - (http-conn-response-port/length! hc count #:close? close?))] + (values (http-conn-response-port/length! hc count #:close? close?) + close?))] [else - (http-conn-response-port/rest! hc)])) + (values (http-conn-response-port/rest! hc) #t)])) (define decoded-response-port (cond [head? raw-response-port] @@ -276,9 +276,13 @@ (thread (λ () (gunzip-through-ports raw-response-port out)))) - (thread + (thread (λ () (thread-wait gunzip-t) + (when wait-for-close? + ;; Wait for an EOF from the raw port before we + ;; send an output on the decoding pipe: + (copy-port raw-response-port (open-output-nowhere))) (close-output-port out))) in] [else From 596b05146c3940ad5a16f1ce5e7de0bde6b14f0e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 10 Nov 2015 10:40:01 -0700 Subject: [PATCH 045/369] file/tar: add `#:follow-links?` option --- pkgs/racket-doc/file/scribblings/tar.scrbl | 17 ++++++++++++----- racket/collects/file/tar.rkt | 21 +++++++++++++-------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/pkgs/racket-doc/file/scribblings/tar.scrbl b/pkgs/racket-doc/file/scribblings/tar.scrbl index 3f2232f65a..76d4d78d9e 100644 --- a/pkgs/racket-doc/file/scribblings/tar.scrbl +++ b/pkgs/racket-doc/file/scribblings/tar.scrbl @@ -11,12 +11,13 @@ directories, files, and symbolic links, and owner information is not preserved; the owner that is stored in the archive is always ``root.'' -Symbolic links (on Unix and Mac OS X) are not followed, and the path +Symbolic links (on Unix and Mac OS X) are not followed by default, and the path in a link must be less than 100 bytes.} @defproc[(tar [tar-file path-string?] [path path-string?] ... + [#:follow-links? follow-links? any/c #f] [#:exists-ok? exists-ok? any/c #f] [#:path-prefix path-prefix (or/c #f path-string?) #f] [#:get-timestamp get-timestamp @@ -32,7 +33,8 @@ relative paths for existing directories and files (i.e., relative to the current directory). If a nested path is provided as a @racket[path], its ancestor directories are also added to the resulting tar file, up to the current directory (using -@racket[pathlist-closure]). +@racket[pathlist-closure]). If @racket[follow-links?] is false, then +symbolic links are included in the resulting tar file as links. If @racket[exists-ok?] is @racket[#f], then an exception is raised if @racket[tar-file] exists already. If @racket[exists-ok?] is true, then @@ -45,11 +47,13 @@ The @racket[get-timestamp] function is used to obtain the modification date to record in the archive for each file or directory. @history[#:changed "6.0.0.3" @elem{Added the @racket[#:get-timestamp] argument.} - #:changed "6.1.1.1" @elem{Added the @racket[#:exists-ok?] argument.}]} + #:changed "6.1.1.1" @elem{Added the @racket[#:exists-ok?] argument.} + #:changed "6.3.0.3" @elem{Added the @racket[#:follow-links?] argument.}]} @defproc[(tar->output [paths (listof path?)] [out output-port? (current-output-port)] + [#:follow-links? follow-links? any/c #f] [#:path-prefix path-prefix (or/c #f path-string?) #f] [#:get-timestamp get-timestamp (path? . -> . exact-integer?) @@ -64,11 +68,13 @@ archive that is written directly to the @racket[out]. The specified content is not automatically added, and nested directories are added without parent directories. -@history[#:changed "6.0.0.3" @elem{Added the @racket[#:get-timestamp] argument.}]} +@history[#:changed "6.0.0.3" @elem{Added the @racket[#:get-timestamp] argument.} + #:changed "6.3.0.3" @elem{Added the @racket[#:follow-links?] argument.}]} @defproc[(tar-gzip [tar-file path-string?] [paths path-string?] ... + [#:follow-links? follow-links? any/c #f] [#:exists-ok? exists-ok? any/c #f] [#:path-prefix path-prefix (or/c #f path-string?) #f] [#:get-timestamp get-timestamp @@ -81,4 +87,5 @@ without parent directories. Like @racket[tar], but compresses the resulting file with @racket[gzip]. @history[#:changed "6.0.0.3" @elem{Added the @racket[#:get-timestamp] argument.} - #:changed "6.1.1.1" @elem{Added the @racket[#:exists-ok?] argument.}]} + #:changed "6.1.1.1" @elem{Added the @racket[#:exists-ok?] argument.} + #:changed "6.3.0.3" @elem{Added the @racket[#:follow-links?] argument.}]} diff --git a/racket/collects/file/tar.rkt b/racket/collects/file/tar.rkt index 14b9c7e79b..e0b1dde501 100644 --- a/racket/collects/file/tar.rkt +++ b/racket/collects/file/tar.rkt @@ -43,8 +43,8 @@ (define 0-byte (char->integer #\0)) -(define ((tar-one-entry buf prefix get-timestamp) path) - (let* ([link? (link-exists? path)] +(define ((tar-one-entry buf prefix get-timestamp follow-links?) path) + (let* ([link? (and (not follow-links?) (link-exists? path))] [dir? (and (not link?) (directory-exists? path))] [size (if (or dir? link?) 0 (file-size path))] [p 0] ; write pointer @@ -139,9 +139,10 @@ (provide tar->output) (define (tar->output files [out (current-output-port)] #:get-timestamp [get-timestamp file-or-directory-modify-seconds] - #:path-prefix [prefix #f]) + #:path-prefix [prefix #f] + #:follow-links? [follow-links? #f]) (parameterize ([current-output-port out]) - (let* ([buf (new-block)] [entry (tar-one-entry buf prefix get-timestamp)]) + (let* ([buf (new-block)] [entry (tar-one-entry buf prefix get-timestamp follow-links?)]) (for-each entry files) ;; two null blocks end-marker (write-bytes buf) (write-bytes buf)))) @@ -151,20 +152,23 @@ (define (tar tar-file #:exists-ok? [exists-ok? #f] #:path-prefix [prefix #f] + #:follow-links? [follow-links? #f] #:get-timestamp [get-timestamp file-or-directory-modify-seconds] . paths) (when (null? paths) (error 'tar "no paths specified")) (with-output-to-file tar-file #:exists (if exists-ok? 'truncate/replace 'error) - (lambda () (tar->output (pathlist-closure paths #:follow-links? #f) - #:get-timestamp get-timestamp - #:path-prefix prefix)))) + (lambda () (tar->output (pathlist-closure paths #:follow-links? follow-links?) + #:get-timestamp get-timestamp + #:path-prefix prefix + #:follow-links? follow-links?)))) ;; tar-gzip : output-file paths -> (provide tar-gzip) (define (tar-gzip tgz-file #:exists-ok? [exists-ok? #f] #:path-prefix [prefix #f] + #:follow-links? [follow-links? #f] #:get-timestamp [get-timestamp file-or-directory-modify-seconds] . paths) (when (null? paths) (error 'tar-gzip "no paths specified")) @@ -173,8 +177,9 @@ (lambda () (let-values ([(i o) (make-pipe (* 1024 1024 32))]) (thread (lambda () - (tar->output (pathlist-closure paths #:follow-links? #f) o + (tar->output (pathlist-closure paths #:follow-links? follow-links?) o #:path-prefix prefix + #:follow-links? follow-links? #:get-timestamp get-timestamp) (close-output-port o))) (gzip-through-ports From 04c0c59d2749939e2ea1507ec5f1b43d69282538 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Tue, 10 Nov 2015 13:34:45 -0500 Subject: [PATCH 046/369] Yet another try at ensuring that this concurrency works. --- pkgs/racket-test/tests/pkg/tests-locking.rkt | 29 +++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/pkgs/racket-test/tests/pkg/tests-locking.rkt b/pkgs/racket-test/tests/pkg/tests-locking.rkt index 768b0ce615..a3bcf6ea54 100644 --- a/pkgs/racket-test/tests/pkg/tests-locking.rkt +++ b/pkgs/racket-test/tests/pkg/tests-locking.rkt @@ -14,38 +14,41 @@ ;; 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)) - (define okay-to-quit?-sema (make-semaphore)) + + (define succeed-catalog (make-channel)) + (define fail-catalog (make-channel)) + (thread (λ () (serve/servlet (pkg-index/basic (λ (pkg-name) - (semaphore-post okay-to-start?-sema) - (semaphore-wait okay-to-respond?-sema) + (channel-put fail-catalog 'go) + (sync fail-catalog) ;; => 'continue (define r (hash-ref *index-ht-1* pkg-name #f)) r) (λ () *index-ht-1*)) #:command-line? #t #:servlet-regexp #rx"" - #:port 9967) - (semaphore-wait okay-to-quit?-sema) - (semaphore-wait okay-to-quit?-sema))) + #:port 9967))) ;; Step 2: Assign it as our server $ "raco pkg config --set catalogs http://localhost:9967" + $ "raco pkg show pkg-test1" + ;; Step 3: Start an installation request in the background (thread (λ () (shelly-begin - $ "raco pkg install pkg-test1") - (semaphore-post okay-to-quit?-sema))) - (semaphore-wait okay-to-start?-sema) + $ "raco pkg install pkg-test1" + $ "raco pkg show pkg-test1") + (channel-put succeed-catalog 'done))) + (sync fail-catalog) ;; => 'go ;; Step 4: Start the installation request that will fail $ "raco pkg install pkg-test1" =exit> 1 ;; Step 5: Free the other one - (semaphore-post okay-to-respond?-sema) - (semaphore-post okay-to-quit?-sema)))) + (channel-put fail-catalog 'continue) + (sync succeed-catalog) ;; => 'done + ))) From b5e2ae030b285cddc6b91a483b123657e8f82d80 Mon Sep 17 00:00:00 2001 From: John Clements Date: Mon, 9 Nov 2015 01:33:14 -0800 Subject: [PATCH 047/369] net/head: better error message for bytes/string mismatch --- racket/collects/net/head.rkt | 50 ++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/racket/collects/net/head.rkt b/racket/collects/net/head.rkt index 8365326c82..e229816aa4 100644 --- a/racket/collects/net/head.rkt +++ b/racket/collects/net/head.rkt @@ -81,29 +81,35 @@ (define (extract-field field header) (if (bytes? header) - (let ([m (regexp-match-positions (make-field-start-regexp/bytes field) - header)]) - (and m - (let ([s (subbytes header - (cdaddr m) - (bytes-length header))]) - (let ([m (regexp-match-positions #rx#"[\r][\n][^: \r\n\"]*:" s)]) - (if m - (subbytes s 0 (caar m)) - ;; Rest of header is this field, but strip trailing CRLFCRLF: - (regexp-replace #rx#"\r\n\r\n$" s "")))))) + (cond + [(bytes? field) + (let ([m (regexp-match-positions (make-field-start-regexp/bytes field) + header)]) + (and m + (let ([s (subbytes header + (cdaddr m) + (bytes-length header))]) + (let ([m (regexp-match-positions #rx#"[\r][\n][^: \r\n\"]*:" s)]) + (if m + (subbytes s 0 (caar m)) + ;; Rest of header is this field, but strip trailing CRLFCRLF: + (regexp-replace #rx#"\r\n\r\n$" s ""))))))] + [else (raise-argument-error 'extract-field "bytes field for bytes header" 0 field header)]) ;; otherwise header & field should be strings: - (let ([m (regexp-match-positions (make-field-start-regexp field) - header)]) - (and m - (let ([s (substring header - (cdaddr m) - (string-length header))]) - (let ([m (regexp-match-positions #rx"[\r][\n][^: \r\n\"]*:" s)]) - (if m - (substring s 0 (caar m)) - ;; Rest of header is this field, but strip trailing CRLFCRLF: - (regexp-replace #rx"\r\n\r\n$" s "")))))))) + (cond + [(string? field) + (let ([m (regexp-match-positions (make-field-start-regexp field) + header)]) + (and m + (let ([s (substring header + (cdaddr m) + (string-length header))]) + (let ([m (regexp-match-positions #rx"[\r][\n][^: \r\n\"]*:" s)]) + (if m + (substring s 0 (caar m)) + ;; Rest of header is this field, but strip trailing CRLFCRLF: + (regexp-replace #rx"\r\n\r\n$" s ""))))))] + [else (raise-argument-error 'extract-field "string field for string header" 0 field header)]))) (define (replace-field field data header) (if (bytes? header) From a053c78c30ba97272da00abdb8d2431bb2ba0145 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 12 Nov 2015 14:01:58 -0700 Subject: [PATCH 048/369] fix re-export of shadowing binding Mishandling of the `require`-binding table could cause `racket/private/pre-base` to export `andmap` as syntax, for example, instead of as a variable. The syntax-versus-variable distinction doesn't usually matter, but it affects the order of exports in bytecode form. --- racket/src/racket/src/module.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index ba5ef57854..cdda0b464c 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -7672,7 +7672,10 @@ static void check_require_name(Scheme_Object *id, Scheme_Object *self_modidx, && prep_required_id(vec) && scheme_stx_bound_eq(SCHEME_VEC_ELS(vec)[6], id, phase)) { /* can override; first, remove old binding mapping: */ - scheme_hash_set(required, binding, NULL); + if (SCHEME_SYMBOLP(binding)) + scheme_hash_set(required, binding, scheme_false); + else + scheme_hash_set(required, binding, NULL); /* construct overriding `binding`: */ binding = scheme_make_vector(4, NULL); vec = scheme_module_resolve(modidx, 0); From 825902f8e6d853b60842a640a795659c6ab71b3a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 12 Nov 2015 19:01:18 -0700 Subject: [PATCH 049/369] Windows: adjust `raco ctool --c-mods ... --runtime ...` to copy libs When gathering runtime files, include the "longdouble.dll" and "libiconv-2.dll" libraries that are referenced by the runtime system. --- racket/collects/compiler/distribute.rkt | 96 +++++++++++++------------ 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/racket/collects/compiler/distribute.rkt b/racket/collects/compiler/distribute.rkt index c235a144d4..9f854ec4ec 100644 --- a/racket/collects/compiler/distribute.rkt +++ b/racket/collects/compiler/distribute.rkt @@ -105,8 +105,7 @@ (make-directory* collects-dir) (make-directory* exts-dir) ;; Copy libs into place - (when executables? - (install-libs lib-dir types)) + (install-libs lib-dir types (not executables?)) ;; Copy collections into place (for-each (lambda (dir) (for-each (lambda (f) @@ -154,7 +153,7 @@ ;; Done! (void)))))) - (define (install-libs lib-dir types) + (define (install-libs lib-dir types extras-only?) (case (cross-system-type) [(windows) (let ([copy-dll (lambda (name) @@ -169,52 +168,55 @@ (map copy-dll (list "libiconv-2.dll" "longdouble.dll")) - (when (or (memq 'racketcgc types) - (memq 'gracketcgc types)) - (map copy-dll - (list - (versionize "libracket~a.dll") - (versionize "libmzgc~a.dll")))) - (when (or (memq 'racket3m types) - (memq 'gracket3m types)) - (map copy-dll - (list - (versionize "libracket3m~a.dll")))))] + (unless extras-only? + (when (or (memq 'racketcgc types) + (memq 'gracketcgc types)) + (map copy-dll + (list + (versionize "libracket~a.dll") + (versionize "libmzgc~a.dll")))) + (when (or (memq 'racket3m types) + (memq 'gracket3m types)) + (map copy-dll + (list + (versionize "libracket3m~a.dll"))))))] [(macosx) - (when (or (memq 'racketcgc types) - (memq 'gracketcgc types)) - (copy-framework "Racket" #f lib-dir)) - (when (or (memq 'racket3m types) - (memq 'gracket3m types)) - (copy-framework "Racket" #t lib-dir))] + (unless extras-only? + (when (or (memq 'racketcgc types) + (memq 'gracketcgc types)) + (copy-framework "Racket" #f lib-dir)) + (when (or (memq 'racket3m types) + (memq 'gracket3m types)) + (copy-framework "Racket" #t lib-dir)))] [(unix) - (let ([lib-plt-dir (build-path lib-dir "plt")]) - (unless (directory-exists? lib-plt-dir) - (make-directory lib-plt-dir)) - (let ([copy-bin - (lambda (name variant gr?) - (copy-file* (build-path (if gr? - (find-lib-dir) - (find-console-bin-dir)) - (format "~a~a" name (variant-suffix variant #f))) - (build-path lib-plt-dir - (format "~a~a-~a" name variant (version)))))]) - (when (memq 'racketcgc types) - (copy-bin "racket" 'cgc #f)) - (when (memq 'racket3m types) - (copy-bin "racket" '3m #f)) - (when (memq 'gracketcgc types) - (copy-bin "gracket" 'cgc #t)) - (when (memq 'gracket3m types) - (copy-bin "gracket" '3m #t))) - (when (shared-libraries?) - (when (or (memq 'racketcgc types) - (memq 'gracketcgc types)) - (copy-shared-lib "racket" lib-dir) - (copy-shared-lib "mzgc" lib-dir)) - (when (or (memq 'racket3m types) - (memq 'gracket3m types)) - (copy-shared-lib "racket3m" lib-dir))))])) + (unless extras-only? + (let ([lib-plt-dir (build-path lib-dir "plt")]) + (unless (directory-exists? lib-plt-dir) + (make-directory lib-plt-dir)) + (let ([copy-bin + (lambda (name variant gr?) + (copy-file* (build-path (if gr? + (find-lib-dir) + (find-console-bin-dir)) + (format "~a~a" name (variant-suffix variant #f))) + (build-path lib-plt-dir + (format "~a~a-~a" name variant (version)))))]) + (when (memq 'racketcgc types) + (copy-bin "racket" 'cgc #f)) + (when (memq 'racket3m types) + (copy-bin "racket" '3m #f)) + (when (memq 'gracketcgc types) + (copy-bin "gracket" 'cgc #t)) + (when (memq 'gracket3m types) + (copy-bin "gracket" '3m #t))) + (when (shared-libraries?) + (when (or (memq 'racketcgc types) + (memq 'gracketcgc types)) + (copy-shared-lib "racket" lib-dir) + (copy-shared-lib "mzgc" lib-dir)) + (when (or (memq 'racket3m types) + (memq 'gracket3m types)) + (copy-shared-lib "racket3m" lib-dir)))))])) (define (search-dll dll-dir dll) (if dll-dir From fb1432e70e00355eabbfae9809d2546a87a3ccbf Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 13 Nov 2015 06:49:07 -0700 Subject: [PATCH 050/369] declare and document scheme_set_dll_path() for Windows embedding --- .../scribblings/inside/embedding.scrbl | 23 +++++++++++++++---- .../racket-doc/scribblings/inside/hooks.scrbl | 9 ++++++++ pkgs/racket-doc/scribblings/inside/utils.rkt | 6 ++++- racket/src/racket/cmdline.inc | 2 -- racket/src/racket/include/scheme.h | 3 +++ 5 files changed, 35 insertions(+), 8 deletions(-) diff --git a/pkgs/racket-doc/scribblings/inside/embedding.scrbl b/pkgs/racket-doc/scribblings/inside/embedding.scrbl index 96c0c58433..f9ace6984e 100644 --- a/pkgs/racket-doc/scribblings/inside/embedding.scrbl +++ b/pkgs/racket-doc/scribblings/inside/embedding.scrbl @@ -1,5 +1,6 @@ #lang scribble/doc -@(require "utils.rkt") +@(require "utils.rkt" + scribble/bnf) @(define cgc-v-3m "CGC versus 3m") @@ -114,16 +115,28 @@ To embed Racket CGC in a program, follow these steps: into the top-level environment. To embed a module like @racketmodname[racket/base] (along with all - its dependencies), use @exec{raco ctool --c-mods}, which generates a C file + its dependencies), use + @seclink["c-mods" #:doc raco-doc]{@exec{raco ctool --c-mods @nonterm{dest}}}, + which generates a C file @nonterm{dest} that contains modules in bytecode form as encapsulated in a static array. The generated C file defines a @cppi{declare_modules} function that takes a @cpp{Scheme_Env*}, installs the modules into the environment, and adjusts the module name resolver to access the - embedded declarations. + embedded declarations. If embedded modules refer to runtime files + that need to be carried along, supply @DFlag{runtime} to + @exec{raco ctool --c-mods} to collect the runtime files into a + directory; see @secref[#:doc raco-doc "c-mods"] for more information. - Alternately, use @cpp{scheme_set_collects_path} and + Alternatively, use @cpp{scheme_set_collects_path} and @cpp{scheme_init_collection_paths} to configure and install a path - for finding modules at run time.} + for finding modules at run time. + + On Windows, @exec{raco ctool --c-mods @nonterm{dest} --runtime + @nonterm{dest-dir}} includes in @nonterm{dest-dir} optional DLLs + that are referenced by the Racket library to support @tech[#:doc + reference-doc]{extflonums} and @racket[bytes-open-converter]. Call + @cpp{scheme_set_dll_path} to register @nonterm{dest-dir} so that + those DLLs can be found at run time.} @item{Access Racket through @cppi{scheme_dynamic_require}, @cppi{scheme_load}, @cppi{scheme_eval}, and/or other functions diff --git a/pkgs/racket-doc/scribblings/inside/hooks.scrbl b/pkgs/racket-doc/scribblings/inside/hooks.scrbl index eb6a5ec9c3..774312abbd 100644 --- a/pkgs/racket-doc/scribblings/inside/hooks.scrbl +++ b/pkgs/racket-doc/scribblings/inside/hooks.scrbl @@ -91,6 +91,15 @@ Like @cpp{scheme_init_collection_paths_post}, but with @racket[null] as the last argument.} +@function[(void scheme_set_dll_path + [wchar_t* path])]{ + +On Windows only, sets the path used to find optional DLLs that are used +by the runtime system: @filepath{longdouble.dll} and one of @filepath{iconv.dll}, +@filepath{libiconv.dll}, or @filepath{libiconv-2.dll}. The given @var{path} +should be an absolute path.} + + @function[(void scheme_seal_parameters)]{ Takes a snapshot of the current values of built-in parameters. These diff --git a/pkgs/racket-doc/scribblings/inside/utils.rkt b/pkgs/racket-doc/scribblings/inside/utils.rkt index 47f9341272..50e99dfbe4 100644 --- a/pkgs/racket-doc/scribblings/inside/utils.rkt +++ b/pkgs/racket-doc/scribblings/inside/utils.rkt @@ -12,6 +12,7 @@ function subfunction FormatD tech-place + reference-doc raco-doc (except-out (all-from-out scribble/manual) var) (for-label (all-from-out scheme/base))) @@ -157,8 +158,11 @@ (define mzc (exec "raco ctool")) +(define reference-doc '(lib "scribblings/reference/reference.scrbl")) +(define raco-doc '(lib "scribblings/raco/raco.scrbl")) + (define (refsecref s) - (secref #:doc '(lib "scribblings/reference/reference.scrbl") s)) + (secref #:doc reference-doc s)) (define Racket (other-manual '(lib "scribblings/reference/reference.scrbl"))) diff --git a/racket/src/racket/cmdline.inc b/racket/src/racket/cmdline.inc index 0d56b56019..ba53a222b3 100644 --- a/racket/src/racket/cmdline.inc +++ b/racket/src/racket/cmdline.inc @@ -106,8 +106,6 @@ static void (*console_printf)(char *str, ...); # define PRINTF console_printf #endif -MZ_EXTERN void scheme_set_dll_path(wchar_t *s); - static void record_dll_path(void) { if (_dlldir[_dlldir_offset] != '<') { diff --git a/racket/src/racket/include/scheme.h b/racket/src/racket/include/scheme.h index eda74a245d..cd3bc38abf 100644 --- a/racket/src/racket/include/scheme.h +++ b/racket/src/racket/include/scheme.h @@ -1946,6 +1946,9 @@ MZ_EXTERN void scheme_set_addon_dir(Scheme_Object *p); MZ_EXTERN void scheme_set_command_line_arguments(Scheme_Object *vec); MZ_EXTERN void scheme_set_compiled_file_paths(Scheme_Object *list); MZ_EXTERN void scheme_set_compiled_file_roots(Scheme_Object *list); +#ifdef DOS_FILE_SYSTEM +MZ_EXTERN void scheme_set_dll_path(wchar_t *s); +#endif MZ_EXTERN void scheme_init_collection_paths(Scheme_Env *global_env, Scheme_Object *extra_dirs); MZ_EXTERN void scheme_init_collection_paths_post(Scheme_Env *global_env, Scheme_Object *extra_dirs, Scheme_Object *extra_post_dirs); From 6343ca0826bb574930dd2a48b96932676b98ca5f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 13 Nov 2015 07:42:34 -0700 Subject: [PATCH 051/369] raco {dist,c-tool}: normalize case of paths before finding prefix --- racket/collects/compiler/distribute.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/compiler/distribute.rkt b/racket/collects/compiler/distribute.rkt index 9f854ec4ec..974fba170f 100644 --- a/racket/collects/compiler/distribute.rkt +++ b/racket/collects/compiler/distribute.rkt @@ -504,7 +504,7 @@ ;; construct-dest: (lambda (src) (when src - (set! paths (cons src paths))) + (set! paths (cons (normal-case-path src) paths))) "dummy") ;; transform-entry (lambda (new-path ext) ext) From ebd84546cae604998c76ce665a072cccd6c9e825 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 13 Nov 2015 09:53:48 -0700 Subject: [PATCH 052/369] adjust a test to accommodate Windows paths --- pkgs/racket-test-core/tests/racket/stx.rktl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-test-core/tests/racket/stx.rktl b/pkgs/racket-test-core/tests/racket/stx.rktl index 41232667cc..55b2a49253 100644 --- a/pkgs/racket-test-core/tests/racket/stx.rktl +++ b/pkgs/racket-test-core/tests/racket/stx.rktl @@ -2107,7 +2107,7 @@ (err/rt-test (apply raise-syntax-error #f "oops" a0 a1 args) (lambda (exn) (and (exn:fail:syntax? exn) - (regexp-match? (format "^[^:\n]*:~a:~a:" + (regexp-match? (format "^([a-zA-Z]:)?[^:\n]*:~a:~a:" (or (syntax-line a1) (syntax-line a0)) (or (syntax-column a1) From 8ec17deed1a0dd237ffd20913c7d3341b93f79b2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 13 Nov 2015 14:53:36 -0700 Subject: [PATCH 053/369] avoid Linux stack correction on non-main thread --- racket/src/racket/src/eval.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index e7aa77c07a..7836194b31 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -518,7 +518,7 @@ scheme_handle_stack_overflow(Scheme_Object *(*k)(void)) } #ifdef LINUX_FIND_STACK_BASE -static uintptr_t adjust_stack_base(uintptr_t bnd) { +static uintptr_t adjust_stack_base(uintptr_t bnd, uintptr_t lim) { if (bnd == scheme_get_primordial_thread_stack_base()) { /* The address `base' might be far from the actual stack base if Exec Shield is enabled (in some versions)? Use @@ -553,7 +553,11 @@ static uintptr_t adjust_stack_base(uintptr_t bnd) { break; } /* printf("%p vs. %p: %d\n", (void*)bnd, (void*)p, p - bnd); */ - bnd = p; + if ((p > bnd) && ((p - lim) < bnd)) { + bnd = p; + } else { + /* bnd is too far from the expected range; on another thread? */ + } break; } } @@ -717,16 +721,16 @@ void scheme_init_stack_check() getrlimit(RLIMIT_STACK, &rl); -# ifdef LINUX_FIND_STACK_BASE - bnd = adjust_stack_base(bnd); -# endif - lim = (uintptr_t)rl.rlim_cur; # ifdef UNIX_STACK_MAXIMUM if (lim > UNIX_STACK_MAXIMUM) lim = UNIX_STACK_MAXIMUM; # endif +# ifdef LINUX_FIND_STACK_BASE + bnd = adjust_stack_base(bnd, lim); +# endif + if (stack_grows_up) bnd += (lim - STACK_SAFETY_MARGIN); else From e3d78e44cc7b7ddbe0e0e598e4264c4828144a68 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 14 Nov 2015 08:31:23 -0700 Subject: [PATCH 054/369] avoid excessive path retention in `raco dist` output This change builds on 5c909cca0d, but it better handles files that are installed in "lib" or "share" instead of residing in a package. --- racket/collects/compiler/distribute.rkt | 70 ++++++++++++++++++------- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/racket/collects/compiler/distribute.rkt b/racket/collects/compiler/distribute.rkt index 974fba170f..e486817b1c 100644 --- a/racket/collects/compiler/distribute.rkt +++ b/racket/collects/compiler/distribute.rkt @@ -513,7 +513,10 @@ exts-dir relative-exts-dir relative->binary-relative) (unless (null? paths) - ;; Determine the shared path prefix among paths within a package: + ;; Determine the shared path prefix among paths within a package, + ;; "collects" directory, or other root. That way, relative path references + ;; can work, but we don't keep excessive path information from the + ;; build machine. (let* ([root-table (make-hash)] [root->path-element (lambda (root) (hash-ref root-table @@ -522,42 +525,73 @@ (let ([v (format "r~a" (hash-count root-table))]) (hash-set! root-table root v) v))))] + [alt-paths (map explode-path + (map normal-case-path + (list* (find-system-path 'addon-dir) + (find-share-dir) + (append (get-lib-search-dirs) + (get-include-search-dirs)))))] [explode (lambda (src) + ;; Sort the path into a root, and keep the root plus + ;; the part of the path relative to that root: (define-values (pkg subpath) (path->pkg+subpath src #:cache pkg-path-cache)) (define main (and (not pkg) (path->main-collects-relative src))) + (define other (and (not pkg) + (not (pair? main)) + (let ([e (explode-path src)]) + (for/or ([d (in-list alt-paths)] + [i (in-naturals)]) + (define len (length d)) + (and ((length e) . > . len) + (equal? d (take e len)) + (cons i len)))))) (reverse (let loop ([src (cond [pkg subpath] [(pair? main) (apply build-path (map bytes->path-element (cdr main)))] + [other (apply build-path + (list-tail (explode-path src) (cdr other)))] [else src])]) (let-values ([(base name dir?) (split-path src)]) (cond [(path? base) (cons name (loop base))] + [(or pkg + (and (pair? main) + 'collects) + (and other (car other))) + => (lambda (r) + (list name (root->path-element r)))] [else - (list (root->path-element (or pkg - (and (pair? main) - 'collects) - name)))])))))] + (list (root->path-element name))])))))] ;; In reverse order, so we can pick off the paths ;; in the second pass: - [exploded (reverse (map explode paths))] - [max-len (apply max 0 (map length exploded))] - [common-len (let loop ([cnt 0]) - (cond - [((add1 cnt) . = . max-len) cnt] - [(andmap (let ([i (list-ref (car exploded) cnt)]) - (lambda (e) - (equal? (list-ref e cnt) i))) - exploded) - (loop (add1 cnt))] - [else cnt]))]) - + [exploded (reverse (let ([exploded (map explode paths)]) + ;; For paths that share the same root, + ;; drop any common "prefix" after the root. + (define roots-common + (for/fold ([ht (hash)]) ([e (in-list exploded)]) + (define l (hash-ref ht (car e) #f)) + (hash-set ht (car e) + (if (not l) + (cdr e) + (let loop ([l l] [l2 (cdr e)]) + (cond + [(or (null? l) (null? l2)) null] + [(or (null? l) (null? l2)) null] + [(equal? (car l) (car l2)) + (cons (car l) (loop (cdr l) (cdr l2)))] + [else null])))))) + ;; Drop common parts out, but deefinitely keep the last + ;; element: + (for/list ([e (in-list exploded)]) + (define l (hash-ref roots-common (car e) null)) + (cons (car e) (list-tail (cdr e) (max 0 (sub1 (length l))))))))]) ;; Pass 2: change all the paths (copy-and-patch-binaries #t #rx#"rUnTiMe-paths[)]" @@ -569,7 +603,7 @@ (lambda (src) (and src (begin0 - (apply build-path (list-tail (car exploded) common-len)) + (apply build-path (car exploded)) (set! exploded (cdr exploded))))) ;; transform-entry (lambda (new-path ext) From 0e16ce4bea27444a3055e79e0919af1e62c87c71 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 14 Nov 2015 21:27:14 -0700 Subject: [PATCH 055/369] add `internal-definition-context-{binding-identifier,track}` When an internal-definition context is used with `local-expand`, the any binding added to the context affect expansion, but the binding do not appear in the expansion. As a result, Check Syntax was unable to draw an arrow from the `s` use to its binding in (class object% (define-struct s ()) s) The general solution is to add the internal-definition context's bindings to the expansion as a 'disappeared-bindings property. The new `internal-definitionc-context-track` function does that using a new `internal-definition-context-binding-identifier` primitive. --- pkgs/base/info.rkt | 2 +- .../scribblings/reference/stx-trans.scrbl | 24 +- .../syntax/scribblings/intdef.scrbl | 22 + .../syntax/scribblings/syntax.scrbl | 2 + .../racket-test-core/tests/racket/object.rktl | 47 + racket/collects/racket/block.rkt | 17 +- .../racket/private/class-internal.rkt | 31 +- racket/collects/racket/unit.rkt | 5 +- racket/collects/syntax/intdef.rkt | 14 + racket/src/racket/src/cstartup.inc | 3054 +++++++++-------- racket/src/racket/src/env.c | 12 + racket/src/racket/src/eval.c | 20 + racket/src/racket/src/schminc.h | 2 +- racket/src/racket/src/schpriv.h | 2 + racket/src/racket/src/schvers.h | 4 +- 15 files changed, 1706 insertions(+), 1552 deletions(-) create mode 100644 pkgs/racket-doc/syntax/scribblings/intdef.scrbl create mode 100644 racket/collects/syntax/intdef.rkt diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index 3b90eb63e3..348a1bf681 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.3.0.3") +(define version "6.3.0.4") (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 a7d5194838..b8816f82f5 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl @@ -5,7 +5,8 @@ racket/require-syntax racket/provide-transform racket/provide-syntax - racket/keyword-transform)) + racket/keyword-transform + syntax/intdef)) @(define stx-eval (make-base-eval)) @(interaction-eval #:eval stx-eval (require (for-syntax racket/base))) @@ -298,6 +299,13 @@ context is meant to splice into an immediately enclosing context, then when @racket[syntax-local-context] produces a list, @racket[cons] the generated value onto that list. +When expressions are expanded via @racket[local-expand] with an +internal-definition context @racket[intdef-ctx], and when the expanded +expressions are incorporated into an overall form @racket[_new-stx], +then typically @racket[internal-definition-context-track] should be +applied to @racket[intdef-ctx] and @racket[_new-stx] to provide +expansion history to external tools. + @transform-time[] @examples[#:eval stx-eval @@ -456,6 +464,18 @@ match the number of identifiers, otherwise the @transform-time[]} +@defproc[(internal-definition-context-binding-identifiers + [intdef-ctx internal-definition-context?]) + (listof identifier?)]{ + +Returns a list of all binding identifiers registered for +@racket[intdef-ctx] through @racket[syntax-local-bind-syntaxes]. Each +identifier in the returned list includes the @tech{internal-definition +context}'s @tech{scope}. + +@history[#:added "6.3.0.4"]} + + @defproc[(internal-definition-context-introduce [intdef-ctx internal-definition-context?] [stx syntax?] [mode (or/c 'flip 'add 'remove) 'flip]) @@ -489,6 +509,8 @@ 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 diff --git a/pkgs/racket-doc/syntax/scribblings/intdef.scrbl b/pkgs/racket-doc/syntax/scribblings/intdef.scrbl new file mode 100644 index 0000000000..696bd4509e --- /dev/null +++ b/pkgs/racket-doc/syntax/scribblings/intdef.scrbl @@ -0,0 +1,22 @@ +#lang scribble/doc +@(require "common.rkt" (for-label syntax/intdef)) + +@title[#:tag "intdef"]{Internal-Definition Context Helpers} + +@defmodule[syntax/intdef] + +@history[#:added "6.3.0.4"] + +@defproc[(internal-definition-context-track + [intdef-ctx internal-definition-context?] + [stx syntax?]) + syntax?]{ + +Adjusts the @tech[#:doc refman]{syntax properties} of @racket[stx] to +record that parts of @racket[stx] were expanded via +@racket[intdef-ctx]. + +Specifically, the identifiers produced by +@racket[(internal-definition-context-binding-identifiers intdef-ctx)] +are added to the @racket['disappeared-bindings] property of +@racket[stx].} diff --git a/pkgs/racket-doc/syntax/scribblings/syntax.scrbl b/pkgs/racket-doc/syntax/scribblings/syntax.scrbl index 72458c85c8..dfc3018e8d 100644 --- a/pkgs/racket-doc/syntax/scribblings/syntax.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/syntax.scrbl @@ -35,4 +35,6 @@ @include-section["macro-testing.scrbl"] +@include-section["intdef.scrbl"] + @index-section[] diff --git a/pkgs/racket-test-core/tests/racket/object.rktl b/pkgs/racket-test-core/tests/racket/object.rktl index 1a7d6941e4..db12dd35cf 100644 --- a/pkgs/racket-test-core/tests/racket/object.rktl +++ b/pkgs/racket-test-core/tests/racket/object.rktl @@ -2153,6 +2153,53 @@ (class c% (super-new) (field [x 0]))) exn:fail?) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check for Check-Syntax support for a `struct` +;; form in `class`, which depends on proper handling +;; of bindings from an internal-definition context + +(let () + (define binds null) + (define refs null) + + (define (inspect stx) + (when (and (identifier? stx) + (eq? 's (syntax-e stx))) + (set! refs (cons stx refs))) + (cond + [(syntax? stx) + (check stx 'disappeared-binding) + (inspect (syntax-e stx)) + (inspect (syntax-property stx 'origin))] + [(pair? stx) + (inspect (car stx)) + (inspect (cdr stx))])) + + (define (check stx prop) + (define v (syntax-property stx prop)) + (when (and v (get-s v)) + (set! binds (cons (get-s v) binds)))) + + (define (get-s e) + (or (and (identifier? e) + (eq? 's (syntax-e e)) + e) + (and (pair? e) + (or (get-s (car e)) + (get-s (cdr e)))) + (and (syntax? e) + (get-s (syntax-e e))))) + + (inspect (expand #'(module m racket/base + (require racket/class) + (class object% + (define-struct s ()) + s)))) + + (for ([r (in-list refs)]) + (test #t 'has-binding-match? (for/or ([b (in-list binds)]) + (free-identifier=? r b))))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/racket/collects/racket/block.rkt b/racket/collects/racket/block.rkt index 5355969605..88326603e3 100644 --- a/racket/collects/racket/block.rkt +++ b/racket/collects/racket/block.rkt @@ -4,7 +4,8 @@ "private/stx.rkt" "private/small-scheme.rkt" "private/stxcase-scheme.rkt" - "private/qqstx.rkt")) + "private/qqstx.rkt" + syntax/intdef)) (#%provide block) @@ -59,12 +60,14 @@ [prev-exprs null]) (cond [(null? exprs) - #`(letrec-syntaxes+values - #,(map stx-cdr (reverse prev-stx-defns)) - #,(map stx-cdr (reverse prev-defns)) - #,@(if (null? prev-exprs) - (list #'(void)) - (reverse prev-exprs)))] + (internal-definition-context-track + def-ctx + #`(letrec-syntaxes+values + #,(map stx-cdr (reverse prev-stx-defns)) + #,(map stx-cdr (reverse prev-defns)) + #,@(if (null? prev-exprs) + (list #'(void)) + (reverse prev-exprs))))] [(and (stx-pair? (car exprs)) (identifier? (stx-car (car exprs))) (free-identifier=? #'define-syntaxes (stx-car (car exprs)))) diff --git a/racket/collects/racket/private/class-internal.rkt b/racket/collects/racket/private/class-internal.rkt index 083f7c9589..73fa1e50cd 100644 --- a/racket/collects/racket/private/class-internal.rkt +++ b/racket/collects/racket/private/class-internal.rkt @@ -19,6 +19,7 @@ syntax/flatten-begin syntax/private/boundmap syntax/parse + syntax/intdef "classidmap.rkt")) (define insp (current-inspector)) ; for all opaque structures @@ -958,23 +959,25 @@ ;; of a class). It doesn't use syntax-track-origin because there is ;; no residual code that it would make sense to be the result of expanding ;; those away. So, instead we only look at a few properties (as below). + ;; Also, add 'disappeared-binding properties from `ctx`. (define (add-decl-props stx) - (for/fold ([stx stx]) - ([decl (in-list (append inspect-decls decls))]) - (define (copy-prop src dest stx) - (syntax-property - stx - dest - (cons (syntax-property decl src) - (syntax-property stx dest)))) - (copy-prop - 'origin 'disappeared-use + (internal-definition-context-track + def-ctx + (for/fold ([stx stx]) + ([decl (in-list (append inspect-decls decls))]) + (define (copy-prop src dest stx) + (syntax-property + stx + dest + (cons (syntax-property decl src) + (syntax-property stx dest)))) (copy-prop - 'disappeared-use 'disappeared-use + 'origin 'disappeared-use (copy-prop - 'disappeared-binding 'disappeared-binding - stx))))) - + 'disappeared-use 'disappeared-use + (copy-prop + 'disappeared-binding 'disappeared-binding + stx)))))) ;; At most one inspect: (unless (or (null? inspect-decls) (null? (cdr inspect-decls))) diff --git a/racket/collects/racket/unit.rkt b/racket/collects/racket/unit.rkt index 3bf4e8b180..6ac935188d 100644 --- a/racket/collects/racket/unit.rkt +++ b/racket/collects/racket/unit.rkt @@ -12,6 +12,7 @@ racket/struct-info syntax/stx syntax/location + syntax/intdef "private/unit-contract-syntax.rkt" "private/unit-compiletime.rkt" "private/unit-syntax.rkt")) @@ -1203,7 +1204,9 @@ (apply append (map do-one ids tmps))))] [else (list defn-or-expr)])) expanded-body))]) - #'(block defn-or-expr ...)))))))) + (internal-definition-context-track + def-ctx + #'(block defn-or-expr ...))))))))) (define-for-syntax (redirect-imports/exports import?) (lambda (table-stx diff --git a/racket/collects/syntax/intdef.rkt b/racket/collects/syntax/intdef.rkt new file mode 100644 index 0000000000..1c97e9ad61 --- /dev/null +++ b/racket/collects/syntax/intdef.rkt @@ -0,0 +1,14 @@ +(module intdef '#%kernel + (#%provide internal-definition-context-track) + + (define-values (internal-definition-context-track) + (lambda (intdef stx) + (if (internal-definition-context? intdef) + (if (syntax? stx) + (let-values ([(ids) (internal-definition-context-binding-identifiers intdef)]) + (if (null? ids) + stx + (let-values ([(v) (syntax-property stx 'disappeared-binding)]) + (syntax-property stx 'disappeared-binding (if v (cons ids v) ids))))) + (raise-argument-error 'internal-definition-context-track "syntax?" 1 intdef stx)) + (raise-argument-error 'internal-definition-context-track "internal-definition-context?" 0 intdef stx))))) diff --git a/racket/src/racket/src/cstartup.inc b/racket/src/racket/src/cstartup.inc index 116af35bcd..8c1e01fb40 100644 --- a/racket/src/racket/src/cstartup.inc +++ b/racket/src/racket/src/cstartup.inc @@ -1,1172 +1,1173 @@ { - 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,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, -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,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,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,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, -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,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,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,165, -20,199,250,22,90,2,21,248,22,90,248,22,81,199,250,22,91,2,9,248,22, -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,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,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,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,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,7,54,46,51,46,48,46,52,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,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,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,165,20,193,249,22, +157,4,80,143,42,39,251,22,90,2,19,248,22,165,20,199,249,22,80,2,4, +248,22,166,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,165, +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,165,20,201,251,22,90,2,19,2,22,2,22,249,22, +80,2,11,248,22,166,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,166,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,165,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,165,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,165,20,201,248,22, +166,20,198,27,248,22,164,4,194,249,22,80,248,22,90,248,22,81,196,248,22, +166,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,166,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,166,20,199,250,22,90,2,7,248,22, +90,248,22,81,199,250,22,91,2,8,248,22,166,20,201,248,22,166,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,166,20,199,250, +22,90,2,21,248,22,90,248,22,81,199,250,22,91,2,9,248,22,166,20,201, +248,22,166,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,166,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,165,20,199,250,22,91,2,5,249,22, +90,2,26,249,22,90,248,22,111,203,2,26,248,22,166,20,202,251,22,90,2, +19,28,249,22,169,9,248,22,158,4,248,22,165,20,200,66,101,108,115,101,10, +248,22,165,20,197,250,22,91,2,21,9,248,22,166,20,200,249,22,80,2,5, +248,22,166,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,165,20,199,248,22,102,198,27, +248,22,158,4,248,22,165,20,197,250,22,90,2,27,248,22,90,248,22,81,197, +250,22,91,2,24,248,22,166,20,199,248,22,166,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, 2090); } { - 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, -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,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, -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,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,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,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,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,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,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,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,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,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,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, -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,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, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,48,46,52,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,91,6,121,6,212,9,235,9, +252,9,176,11,23,12,37,12,241,12,217,14,226,14,235,14,249,14,3,15,23, +16,126,16,239,16,56,17,129,17,233,17,6,18,77,18,215,18,30,19,243,19, +105,20,118,20,236,20,249,20,88,21,155,21,168,21,179,21,75,22,193,22,237, +22,92,23,170,25,194,25,56,26,138,27,145,27,197,27,210,27,200,28,216,28, +71,29,230,29,237,29,114,31,191,31,208,31,108,32,128,32,188,32,195,32,55, +33,109,33,128,33,79,34,95,34,56,35,45,36,82,36,91,36,178,37,23,40, +39,40,106,40,127,40,147,40,167,40,224,40,197,43,163,44,179,44,150,45,208, +45,241,45,117,46,20,47,36,47,133,47,150,47,228,49,23,52,39,52,13,54, +201,54,203,54,230,54,246,54,6,55,103,55,170,56,102,57,118,57,127,57,134, +57,200,58,10,60,128,60,174,63,48,64,180,64,125,66,75,67,117,67,225,67, +0,0,173,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,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,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,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,86,94,23,195,1,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,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,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,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,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,86,94,23, +194,1,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,86,94,23,194,1,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,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,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,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,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, +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,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,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,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,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,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,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,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,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, -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,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,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,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, +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,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,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,166,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,166,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,166,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,166,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,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,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,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,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,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,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,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, -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,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,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,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,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,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,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,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,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,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,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,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, -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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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, +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,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,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,166,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,166,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,166,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,166,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,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,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,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,184,15,195,195,86,95,23, +195,1,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,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,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,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,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,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,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,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,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,165,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,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,166,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,165,20,23,197,2,27,248,22,166,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, +165,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22,166,20,23,198, +1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1,248,22,166,20, +23,198,1,249,22,94,23,199,2,27,248,22,166,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,165,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22,166,20,23, +198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1,248,22,166, +20,23,198,1,249,22,94,23,196,2,27,248,22,166,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,165,20,23,197,2,27,248,22,166,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,165, +20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22,166,20,23,198,1, +249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1,248,22,166,20,23, +198,1,249,22,94,23,199,2,27,248,22,166,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, +165,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22,166,20,23,198, +1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1,248,22,166,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,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,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,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,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,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,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,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,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,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,176,14,39,248,22,166,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,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,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,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,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,165,20,195, +10,249,22,169,9,2,65,248,22,165,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,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,165,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,142,16,23, +196,1,28,249,22,169,9,248,22,165,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,165,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,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,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,166,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,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, +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,86,94,23,193,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,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,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,86,94,23,193,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,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,165,20,23, +197,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22,165,20,23,204, +2,23,202,2,9,250,22,158,2,248,22,165,20,23,202,2,11,9,27,248,22, +166,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,165,20,23,195,2,250,22,94,249,22,2,22,129,2,250, +22,158,2,248,22,165,20,23,202,2,23,206,2,9,250,22,158,2,248,22,165, +20,23,200,2,11,9,249,80,144,48,8,48,42,23,203,1,248,22,166,20,23, +199,1,27,248,80,144,45,8,30,42,248,22,165,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,166,20,23,200,1,249,22,94,247,22,156, +16,249,80,144,47,8,48,42,23,202,1,248,22,166,20,23,198,1,27,248,80, +144,41,8,30,42,248,22,165,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,166,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,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,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,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,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,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,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,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,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,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,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, -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,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,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,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,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,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,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, +248,22,165,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248, +22,165,20,23,202,2,23,207,2,9,250,22,158,2,248,22,165,20,23,200,2, +11,9,249,80,144,49,8,48,42,23,204,1,248,22,166,20,23,199,1,27,248, +80,144,46,8,30,42,248,22,165,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,166,20,23,200,1,249,22,94,247,22,156,16,249,80,144, +48,8,48,42,23,203,1,248,22,166,20,23,198,1,249,22,94,247,22,156,16, +27,248,22,166,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,165,20,23,195,2,250,22,94,249,22,2,22, +129,2,250,22,158,2,248,22,165,20,23,202,2,23,205,2,9,250,22,158,2, +248,22,165,20,23,200,2,11,9,249,80,144,47,8,48,42,23,202,1,248,22, +166,20,23,199,1,27,248,80,144,44,8,30,42,248,22,165,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,166,20,23,200,1,249,22,94, +247,22,156,16,249,80,144,46,8,48,42,23,201,1,248,22,166,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,165,20,195,28,248,22,175,15,193,248, +22,179,15,193,192,250,22,91,27,248,22,165,20,23,198,2,28,248,22,175,15, +193,248,22,179,15,193,192,2,67,248,2,150,2,248,22,166,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, +165,20,23,197,2,249,2,154,2,23,197,1,248,22,166,20,23,199,1,249,2, +154,2,23,195,1,248,22,166,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,86,95, +23,201,1,23,198,1,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,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,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,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,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,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,165,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,86,94,23,195,1,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, +166,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,166,20,23,19,23,19,26,8,80,144,49,8, +49,42,203,204,205,206,23,15,23,16,248,22,166,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,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, +165,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22,165, +20,23,202,2,23,203,2,9,250,22,158,2,248,22,165,20,23,200,2,11,9, +249,80,144,49,8,48,42,23,200,1,248,22,166,20,23,199,1,27,248,80,144, +46,8,30,42,248,22,165,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,166,20,23,200,1,249,22,94,247,22,156,16,249,80,144,48,8, +48,42,23,199,1,248,22,166,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,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,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,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,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,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, +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,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,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,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, +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,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,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, +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,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,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,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,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,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, -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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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, -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,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,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,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, +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,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,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,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,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,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,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,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,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,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,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,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,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, -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, +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,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,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,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,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,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,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,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,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, +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,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,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,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,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,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,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,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, +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,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,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,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,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,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,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,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,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,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,166,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,50,42,248,22,166,20,23,198,1,86,94,23,193,1,248, +80,144,45,8,50,42,248,22,166,20,23,196,1,86,94,23,193,1,27,248,22, +166,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,166,20,23,198,1,86, +94,23,193,1,248,80,144,43,8,50,42,248,22,166,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,166,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,166,20,23,198, +1,86,94,23,193,1,248,80,144,45,8,51,42,248,22,166,20,23,196,1,86, +94,23,193,1,27,248,22,166,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,51,42,248, +22,166,20,23,198,1,86,94,23,193,1,248,80,144,43,8,51,42,248,22,166, +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,166,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,166,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,139,16,249,22,137,16,23,198,1,247,22,153,16,248,80,144,51, +8,53,42,248,22,166,20,23,198,1,86,94,23,193,1,248,80,144,49,8,53, +42,248,22,166,20,23,196,1,86,94,23,193,1,27,248,22,166,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,139,16,249,22,137,16,23,198,1,247,22,153, +16,248,80,144,49,8,53,42,248,22,166,20,23,198,1,86,94,23,193,1,248, +80,144,47,8,53,42,248,22,166,20,23,196,1,86,94,23,193,1,27,248,22, +166,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,166,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,139,16,249,22,137,16,23,198,1,247,22,153,16,248,80,144,49,8, +53,42,248,22,166,20,23,198,1,86,94,23,193,1,248,80,144,47,8,53,42, +248,22,166,20,23,196,1,86,94,23,193,1,27,248,22,166,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,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,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,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,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, +248,80,144,47,8,53,42,248,22,166,20,23,198,1,86,94,23,193,1,248,80, +144,45,8,53,42,248,22,166,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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); +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,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,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, +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,166,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, +139,16,249,22,137,16,23,198,1,247,22,153,16,248,80,144,57,8,53,42,248, +22,166,20,23,198,1,86,94,23,193,1,248,80,144,55,8,53,42,248,22,166, +20,23,196,1,86,94,23,193,1,27,248,22,166,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,139,16,249,22,137,16,23,198,1,247,22,153,16,248,80,144, +55,8,53,42,248,22,166,20,23,198,1,86,94,23,193,1,248,80,144,53,8, +53,42,248,22,166,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,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,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,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,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,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, 19799); } { - 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,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, -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,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,7,54,46,51,46,48,46,52,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,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,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,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, 576); } { - 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, -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,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, -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,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,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, -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,147,16,196,11,32,0,88,148, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,48,46,52,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,29,11,59,11,110,11,185,11,201,11,217, +11,231,11,247,11,66,12,82,12,98,12,114,12,189,12,96,13,112,13,187,13, +182,14,62,15,137,15,44,16,57,16,210,16,138,17,181,17,7,18,140,18,201, +18,209,18,220,18,254,19,101,20,129,20,142,20,63,21,70,21,230,21,250,21, +94,22,116,22,126,22,140,22,178,22,21,23,25,23,32,23,238,23,157,32,210, +32,234,32,2,33,0,0,51,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,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,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,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,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,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,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,57,8,129,3,9,226,5,4,3,6,33,44,23,199,1, +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,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,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,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,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,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,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,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,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, +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,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,165,20,23,197,2,249, +22,4,22,64,248,22,166,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,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,175,15,23,197,2,23,196,1,86,94,23,196,1,247,22,153,16, +249,247,22,175,5,248,22,165,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,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,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,95,23,200,1,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,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, @@ -1174,401 +1175,404 @@ 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, -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,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, -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,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, -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,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, -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,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,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,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, -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, +2,86,94,23,197,1,23,196,2,248,22,167,9,23,198,1,86,94,23,197,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,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,202,193,11,11,11,86,94,23,198,1,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,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,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,175,15,23, +208,2,23,207,1,86,94,23,207,1,247,22,153,16,249,247,22,175,5,248,22, +165,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,97,23, +209,1,23,204,1,23,203,1,23,199,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,175,15,23,209,2,23,208,1,86,94,23,208,1,247,22,153,16,249,247,22, +175,5,248,22,165,20,23,196,1,23,221,1,86,96,23,216,1,23,215,1,23, +193,1,28,28,248,22,78,23,220,2,248,22,165,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,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,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,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,61,23,196,4,196,248,22,181,3,198,28,249, +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,61,23,196,4,23,197,1,39,2,27,248,22,181,3,23, +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,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,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,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,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, -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,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,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,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,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,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,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,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,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, -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,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,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,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,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,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, -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,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,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, -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,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,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,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,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,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,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,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,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,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,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,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, -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,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, -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,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, -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,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,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,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,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,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,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,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, -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,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,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,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,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,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,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,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,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); +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,165,20,23,196,1,90,144,41,11,89,146,41,39,11,27,248,22,166,20,23, +197,2,28,248,22,88,248,22,82,23,195,2,249,22,7,9,248,22,165,20,195, +90,144,41,11,89,146,41,39,11,27,248,22,166,20,196,28,248,22,88,248,22, +82,23,195,2,249,22,7,9,248,22,165,20,195,90,144,41,11,89,146,41,39, +11,248,2,70,248,22,166,20,196,249,22,7,249,22,80,248,22,165,20,199,196, +195,249,22,7,249,22,80,248,22,165,20,199,196,195,249,22,7,249,22,80,248, +22,165,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,165,20,23,196,1,27,248,22,166,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,165,20,23,198,1,27,248,22,166,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,165,20,197,90,144,41,11,89,146,41,39,11,248,2,70,248,22,166, +20,198,249,22,7,249,22,80,248,22,165,20,201,196,195,249,22,7,249,22,80, +248,22,165,20,23,203,1,196,195,249,22,7,249,22,80,248,22,165,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,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,165,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,86, +94,23,195,1,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,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,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,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,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,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,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,166,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,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,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,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,166,20,200,251,2,82,196,197,249,22,80, +248,22,165,20,202,200,248,22,166,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,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,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,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,179,15,248,22,103,23,198,2,248,2,90,248,22,166, +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,165,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,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,165,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,179,15,23,202,1,28,23,204,2,28, +250,22,158,2,248,22,165,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,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,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,165,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,165,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,165,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,165,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,165,20,23,197,2,23,196,2,27,28,249,22,171, +9,248,22,102,23,203,2,2,35,248,22,166,20,200,248,22,104,200,28,248,22, +78,23,198,2,249,22,94,248,22,166,20,199,194,192,28,28,248,22,78,23,196, +2,249,22,169,9,248,22,165,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, +165,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,165,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,165,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,165,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,166,20,23,202,1,248,22,104,23,202,1,28,248,22,78,23,195,2, +249,2,81,248,22,165,20,23,197,2,249,22,94,248,22,166,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,166,20,23,202,1,248,22,104,23,202,1, +28,248,22,78,193,248,22,166,20,193,11,86,94,23,198,1,11,86,94,23,198, +1,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,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,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, +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,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,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,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,166,20,23,199,1, +23,199,1,10,86,94,23,196,1,28,249,22,169,9,248,22,165,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,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,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,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,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,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,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,86,96,23,211,1,23,204,1,23,194,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,165,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,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,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,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, 9765); } { - 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,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, -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,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); + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,48,46,52,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,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,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,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, 531); } diff --git a/racket/src/racket/src/env.c b/racket/src/racket/src/env.c index c68ae63652..2cdffe3023 100644 --- a/racket/src/racket/src/env.c +++ b/racket/src/racket/src/env.c @@ -102,6 +102,7 @@ static Scheme_Object *local_make_intdef_context(int argc, Scheme_Object *argv[]) static Scheme_Object *intdef_context_seal(int argc, Scheme_Object *argv[]); static Scheme_Object *intdef_context_intro(int argc, Scheme_Object *argv[]); static Scheme_Object *intdef_context_p(int argc, Scheme_Object *argv[]); +static Scheme_Object *intdef_context_ids(int argc, Scheme_Object *argv[]); static Scheme_Object *id_intdef_remove(int argc, Scheme_Object *argv[]); static Scheme_Object *local_introduce(int argc, Scheme_Object *argv[]); static Scheme_Object *local_get_shadower(int argc, Scheme_Object *argv[]); @@ -781,6 +782,7 @@ static void make_kernel_env(void) GLOBAL_PRIM_W_ARITY("internal-definition-context-seal", intdef_context_seal, 1, 1, env); GLOBAL_PRIM_W_ARITY("internal-definition-context-introduce", intdef_context_intro, 2, 3, env); GLOBAL_PRIM_W_ARITY("internal-definition-context?", intdef_context_p, 1, 1, env); + GLOBAL_PRIM_W_ARITY("internal-definition-context-binding-identifiers", intdef_context_ids, 1, 1, env); GLOBAL_PRIM_W_ARITY("identifier-remove-from-definition-context", id_intdef_remove, 2, 2, env); GLOBAL_PRIM_W_ARITY("syntax-local-get-shadower", local_get_shadower, 1, 2, env); GLOBAL_PRIM_W_ARITY("syntax-local-introduce", local_introduce, 1, 1, env); @@ -2564,6 +2566,16 @@ id_intdef_remove(int argc, Scheme_Object *argv[]) return res; } +static Scheme_Object *intdef_context_ids(int argc, Scheme_Object *argv[]) +{ + if (!SAME_TYPE(SCHEME_TYPE(argv[0]), scheme_intdef_context_type)) + scheme_wrong_contract("internal-definition-context-binding-identifiers", + "internal-definition-context?", + 0, argc, argv); + + return scheme_intdef_bind_identifiers(argv[0]); +} + static Scheme_Object * local_introduce(int argc, Scheme_Object *argv[]) { diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index 7836194b31..917192591c 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -5894,6 +5894,26 @@ local_eval(int argc, Scheme_Object **argv) return scheme_void; } +Scheme_Object *scheme_intdef_bind_identifiers(Scheme_Object *intdef) +{ + Scheme_Comp_Env *stx_env, *init_env; + Scheme_Object *l = scheme_null; + int i; + + update_intdef_chain(intdef); + stx_env = (Scheme_Comp_Env *)((void **)SCHEME_PTR1_VAL(intdef))[0]; + init_env = (Scheme_Comp_Env *)((void **)SCHEME_PTR1_VAL(intdef))[3]; + + while (stx_env != init_env) { + for (i = stx_env->num_bindings; i--; ) { + l = scheme_make_pair(stx_env->binders[i], l); + } + stx_env = stx_env->next; + } + + return l; +} + /*========================================================================*/ /* cloning prefix information */ /*========================================================================*/ diff --git a/racket/src/racket/src/schminc.h b/racket/src/racket/src/schminc.h index 3f0adea467..77de7800a8 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 1135 +#define EXPECTED_PRIM_COUNT 1136 #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 2171018ac8..867a918645 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -2979,6 +2979,8 @@ Scheme_Native_Closure_Data *scheme_generate_case_lambda(Scheme_Case_Lambda *cl); void scheme_delay_load_closure(Scheme_Closure_Data *data); +Scheme_Object *scheme_intdef_bind_identifiers(Scheme_Object *intdef); + #define scheme_add_good_binding(i,v,f) (f->values[i] = v) Scheme_Object *scheme_compiled_void(void); diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index bf329bf946..c76e71db12 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.3" +#define MZSCHEME_VERSION "6.3.0.4" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 3 #define MZSCHEME_VERSION_Z 0 -#define MZSCHEME_VERSION_W 3 +#define MZSCHEME_VERSION_W 4 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From d3f2bd6dace0005d22f2feefe4ad5edfa1408d9d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 15 Nov 2015 16:46:07 -0700 Subject: [PATCH 056/369] fix broken abort handling related to module-registry lock --- .../racket-test-core/tests/racket/module.rktl | 28 +++++++++++++++++++ racket/src/racket/src/module.c | 17 +++++++---- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/module.rktl b/pkgs/racket-test-core/tests/racket/module.rktl index 1be29de2c8..dab843cf3f 100644 --- a/pkgs/racket-test-core/tests/racket/module.rktl +++ b/pkgs/racket-test-core/tests/racket/module.rktl @@ -1642,6 +1642,34 @@ case of module-leve bindings; it doesn't cover local bindings. (#%require (submod ".." ma)) (foo))))) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Make sure that shutting down a custodian +;; releases a lock as it should + +(parameterize ([current-custodian (make-custodian)]) + (thread-wait + (thread + (lambda () + (parameterize ([current-namespace (make-base-namespace)]) + (eval '(module m racket/base + (require (for-syntax racket/base)) + (begin-for-syntax + #;(log-error "nested") + ;; Using an environment variable to communicate across phases: + (when (getenv "PLT_ready_to_end") + #;(log-error "adios") + (custodian-shutdown-all (current-custodian)))))) + (eval '(module n racket/base + (require (for-syntax racket/base)) + (begin-for-syntax + #;(log-error "outer") + (dynamic-require ''m 0) + (eval #f)))) + (putenv "PLT_ready_to_end" "yes") + (dynamic-require ''n 0) + #;(log-error "go") + (eval #f)))))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index cdda0b464c..238f0d266d 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -4932,9 +4932,11 @@ static void lock_registry(Scheme_Env *env) static void unlock_registry(Scheme_Env *env) { Scheme_Object *lock; - lock = scheme_hash_get(env->module_registry->loaded, scheme_false); - scheme_post_sema(SCHEME_CAR(lock)); - scheme_hash_set(env->module_registry->loaded, scheme_false, NULL); + if (env) { + lock = scheme_hash_get(env->module_registry->loaded, scheme_false); + scheme_post_sema(SCHEME_CAR(lock)); + scheme_hash_set(env->module_registry->loaded, scheme_false, NULL); + } } XFORM_NONGCING static intptr_t make_key(int base_phase, int eval_exp, int eval_run) @@ -5742,7 +5744,7 @@ static void start_module(Scheme_Module *m, Scheme_Env *env, int restart, static void do_prepare_compile_env(Scheme_Env *env, int base_phase, int pos) { Scheme_Object *v, *prev; - Scheme_Env *menv; + Scheme_Env *menv, *uenv; int need_lock; need_lock = wait_registry(env); @@ -5763,14 +5765,17 @@ static void do_prepare_compile_env(Scheme_Env *env, int base_phase, int pos) } v = prev; - if (need_lock) + if (need_lock) { lock_registry(env); + uenv = env; + } else + uenv = NULL; while (SCHEME_NAMESPACEP(v)) { menv = (Scheme_Env *)v; v = menv->available_next[pos]; menv->available_next[pos] = NULL; - BEGIN_ESCAPEABLE(unlock_registry, env); + BEGIN_ESCAPEABLE(unlock_registry, uenv); start_module(menv->module, menv->instance_env, 0, NULL, 1, 0, base_phase, scheme_null, 1); From 912f1fe603f6cbf3e2c70d6218a921fae0e6cd66 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Sun, 15 Nov 2015 16:15:24 -0500 Subject: [PATCH 057/369] add macro-debugger event on expand opaque expression --- racket/src/racket/src/compile.c | 1 + 1 file changed, 1 insertion(+) diff --git a/racket/src/racket/src/compile.c b/racket/src/racket/src/compile.c index 08411a061b..4500c8fa1e 100644 --- a/racket/src/racket/src/compile.c +++ b/racket/src/racket/src/compile.c @@ -4819,6 +4819,7 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, form = scheme_stx_track(SCHEME_PTR1_VAL(var), form, NULL); if (!rec[drec].comp) { /* Already fully expanded. */ + SCHEME_EXPAND_OBSERVE_OPAQUE_EXPR(env->observer, form); return form; } } else { From 6099a70c526fa150814f32e98ebef68208574aab Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 16 Nov 2015 12:53:17 -0700 Subject: [PATCH 058/369] fix relative-path discovery for case-normalized paths --- pkgs/racket-test/tests/setup/path-to-relative.rkt | 2 ++ racket/collects/setup/path-relativize.rkt | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test/tests/setup/path-to-relative.rkt b/pkgs/racket-test/tests/setup/path-to-relative.rkt index 453eb17fef..98695247df 100644 --- a/pkgs/racket-test/tests/setup/path-to-relative.rkt +++ b/pkgs/racket-test/tests/setup/path-to-relative.rkt @@ -10,3 +10,5 @@ (path->relative-string/library (path-only (collection-file-path "base.rkt" "racket")))) (check-equal? "/racket/base.rkt" (path->relative-string/library (collection-file-path "base.rkt" "racket"))) +(check-equal? "/racket/base.rkt" + (path->relative-string/library (normal-case-path (collection-file-path "base.rkt" "racket")))) diff --git a/racket/collects/setup/path-relativize.rkt b/racket/collects/setup/path-relativize.rkt index ade83d09ac..1a05be5a7b 100644 --- a/racket/collects/setup/path-relativize.rkt +++ b/racket/collects/setup/path-relativize.rkt @@ -44,7 +44,8 @@ ;; `path1', but that messes up the xform compilation somehow, by ;; having # vaules written into dep files. [(null? path) path0] - [(equal? (car path) (car root)) (loop (cdr path) (cdr root))] + [(equal? (normal-case-path (car path)) (normal-case-path (car root))) + (loop (cdr path) (cdr root))] [else path0]))) (define root-or-orig From 76e27da8bacf4b43573e4e4d6e08f085277457c4 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Mon, 16 Nov 2015 23:12:46 -0500 Subject: [PATCH 059/369] Fix blame error for listof contract --- racket/collects/racket/contract/private/misc.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index 7477a0e1aa..a702633c58 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -630,7 +630,7 @@ (raise-blame-error blame #:missing-party neg-party val '(expected: "~s" given: "~e") (if empty-ok? - "list?" + 'list? (format "~s" `(and/c list? pair?))) val)) From 0b1d0610f2fab45a5eed0e39915fe8e19983345a Mon Sep 17 00:00:00 2001 From: Tim Brown Date: Thu, 19 Nov 2015 10:30:28 -0700 Subject: [PATCH 060/369] support [plt_]{http,no}_proxy environment variables The `current-proxy-servers` and `current-no-proxy-servers` parameters are initialized on-demand from environment variables. --- racket/collects/net/url.rkt | 121 +++++++++++++++++++++++++++++------- 1 file changed, 98 insertions(+), 23 deletions(-) diff --git a/racket/collects/net/url.rkt b/racket/collects/net/url.rkt index 9564806d8b..94ca5650ea 100644 --- a/racket/collects/net/url.rkt +++ b/racket/collects/net/url.rkt @@ -4,6 +4,7 @@ racket/contract/base racket/list racket/match + racket/promise (prefix-in hc: "http-client.rkt") (only-in "url-connect.rkt" current-https-protocol) "uri-codec.rkt" @@ -23,27 +24,95 @@ ;; "impure" = they have text waiting ;; "pure" = the MIME headers have been read -(define current-proxy-servers - (make-parameter null - (lambda (v) - (unless (and (list? v) - (andmap (lambda (v) - (and (list? v) - (= 3 (length v)) - (equal? (car v) "http") - (string? (car v)) - (exact-integer? (caddr v)) - (<= 1 (caddr v) 65535))) - v)) - (raise-type-error - 'current-proxy-servers - "list of list of scheme, string, and exact integer in [1,65535]" +(define proxiable-url-schemes '("http")) + +(define (env->c-p-s-entries envars) + (if (null? envars) + null + (match (getenv (car envars)) + [#f (env->c-p-s-entries (cdr envars))] + ["" null] + [(app string->url + (url (and scheme "http") #f (? string? host) (? integer? port) + _ (list) (list) #f)) + (list (list scheme host port))] + [(app string->url + (url (and scheme "http") _ (? string? host) (? integer? port) + _ _ _ _)) + (log-net/url-error "~s contains somewhat invalid proxy URL format" (car envars)) + (list (list scheme host port))] + [inv (log-net/url-error "~s contained invalid proxy URL format: ~s" + (car envars) inv) + null]))) + +(define current-proxy-servers-promise + (make-parameter (delay (env->c-p-s-entries '("plt_http_proxy" "http_proxy"))))) + +(define (proxy-servers-guard v) + (unless (and (list? v) + (andmap (lambda (v) + (and (list? v) + (= 3 (length v)) + (equal? (car v) "http") + (string? (car v)) + (exact-integer? (caddr v)) + (<= 1 (caddr v) 65535))) v)) - (map (lambda (v) - (list (string->immutable-string (car v)) - (string->immutable-string (cadr v)) - (caddr v))) - v)))) + (raise-type-error + 'current-proxy-servers + "list of list of scheme, string, and exact integer in [1,65535]" + v)) + (map (lambda (v) + (list (string->immutable-string (car v)) + (string->immutable-string (cadr v)) + (caddr v))) + v)) + +(define current-proxy-servers + (make-derived-parameter current-proxy-servers-promise + (λ (v) (let ((guarded (proxy-servers-guard v))) + (delay guarded))) + force)) + +(define (env->n-p-s-entries envars) + (if (null? envars) + null + (match (getenv (car envars)) + [#f (env->n-p-s-entries (cdr envars))] + ["" null] + [hostnames (string-split hostnames ",")]))) + +(define current-no-proxy-servers-promise + (make-parameter (delay (no-proxy-servers-guard (env->n-p-s-entries '("plt_no_proxy" "no_proxy")))))) + +(define (no-proxy-servers-guard v) + (unless (and (list? v) + (andmap (lambda (v) + (or (string? v) + (regexp? v))) + v)) + (raise-type-error 'current-no-proxy-servers + "list of string or regexp" + v)) + (map (match-lambda + [(? regexp? re) re] + [(regexp "^(\\..*)$" (list _ m)) + (regexp (string-append ".*" (regexp-quote m)))] + [(? string? s) (regexp (string-append "^"(regexp-quote s)"$"))]) + v)) + +(define current-no-proxy-servers + (make-derived-parameter current-no-proxy-servers-promise + (λ (v) + (let ((guarded (no-proxy-servers-guard v))) + (delay guarded))) + force)) + +(define (proxy-server-for url-schm (dest-host-name #f)) + (let ((rv (assoc url-schm (current-proxy-servers)))) + (cond [(not dest-host-name) rv] + [(memf (lambda (np) (regexp-match np dest-host-name)) (current-no-proxy-servers)) #f] + [else rv]))) (define (url-error fmt . args) (raise (make-url-exception @@ -58,6 +127,7 @@ (cond [(not scheme) 80] [(string=? scheme "http") 80] [(string=? scheme "https") 443] + [(string=? scheme "git") 9418] [else (url-error "URL scheme ~s not supported" scheme)]))) ;; make-ports : url -> hc @@ -76,7 +146,7 @@ ;; -> hc (define (http://getpost-impure-port get? url post-data strings make-ports 1.1?) - (define proxy (assoc (url-scheme url) (current-proxy-servers))) + (define proxy (proxy-server-for (url-scheme url) (url-host url))) (define hc (make-ports url proxy)) (define access-string (ensure-non-empty @@ -326,7 +396,7 @@ [(get) "GET"] [(post) "POST"] [(head) "HEAD"] [(put) "PUT"] [(delete) "DELETE"] [(options) "OPTIONS"] [else (url-error "unsupported method: ~a" method)])] - [proxy (assoc (url-scheme url) (current-proxy-servers))] + [proxy (proxy-server-for (url-scheme url) (url-host url))] [hc (make-ports url proxy)] [access-string (ensure-non-empty @@ -387,7 +457,12 @@ (listof string?) any))) (current-proxy-servers - (parameter/c (or/c false/c (listof (list/c string? string? number?)))))) + (parameter/c (or/c false/c (listof (list/c string? string? number?))))) + (current-no-proxy-servers + (parameter/c (or/c false/c (listof (or/c string? regexp?))))) + (proxy-server-for (->* (string?) ((or/c false/c string?)) + (or/c false/c (list/c string? string? number?)))) + (proxiable-url-schemes (listof string?))) (define (http-sendrecv/url u #:method [method-bss #"GET"] From 877264c63b42138df17bf87df6228291aaadf356 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 20 Nov 2015 06:17:52 -0700 Subject: [PATCH 061/369] fix `net/url` delays to be thread-safe --- racket/collects/net/url.rkt | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/racket/collects/net/url.rkt b/racket/collects/net/url.rkt index 94ca5650ea..2a18b5db7a 100644 --- a/racket/collects/net/url.rkt +++ b/racket/collects/net/url.rkt @@ -46,7 +46,7 @@ null]))) (define current-proxy-servers-promise - (make-parameter (delay (env->c-p-s-entries '("plt_http_proxy" "http_proxy"))))) + (make-parameter (delay/sync (env->c-p-s-entries '("plt_http_proxy" "http_proxy"))))) (define (proxy-servers-guard v) (unless (and (list? v) @@ -70,8 +70,7 @@ (define current-proxy-servers (make-derived-parameter current-proxy-servers-promise - (λ (v) (let ((guarded (proxy-servers-guard v))) - (delay guarded))) + proxy-servers-guard force)) (define (env->n-p-s-entries envars) @@ -83,7 +82,7 @@ [hostnames (string-split hostnames ",")]))) (define current-no-proxy-servers-promise - (make-parameter (delay (no-proxy-servers-guard (env->n-p-s-entries '("plt_no_proxy" "no_proxy")))))) + (make-parameter (delay/sync (no-proxy-servers-guard (env->n-p-s-entries '("plt_no_proxy" "no_proxy")))))) (define (no-proxy-servers-guard v) (unless (and (list? v) @@ -103,9 +102,7 @@ (define current-no-proxy-servers (make-derived-parameter current-no-proxy-servers-promise - (λ (v) - (let ((guarded (no-proxy-servers-guard v))) - (delay guarded))) + no-proxy-servers-guard force)) (define (proxy-server-for url-schm (dest-host-name #f)) From c257d6dc646205c9d89edd2d84bc32fa190a5dad Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Fri, 2 Oct 2015 15:49:13 -0400 Subject: [PATCH 062/369] tagged brackets and braces --- racket/src/racket/include/scheme.h | 2 ++ racket/src/racket/src/read.c | 58 +++++++++++++++++++++++++++--- racket/src/racket/src/schminc.h | 2 +- racket/src/racket/src/schvers.h | 2 +- 4 files changed, 58 insertions(+), 6 deletions(-) diff --git a/racket/src/racket/include/scheme.h b/racket/src/racket/include/scheme.h index cd3bc38abf..bfc781f4b0 100644 --- a/racket/src/racket/include/scheme.h +++ b/racket/src/racket/include/scheme.h @@ -1365,6 +1365,8 @@ enum { MZCONFIG_CASE_SENS, MZCONFIG_SQUARE_BRACKETS_ARE_PARENS, MZCONFIG_CURLY_BRACES_ARE_PARENS, + MZCONFIG_SQUARE_BRACKETS_ARE_TAGGED, + MZCONFIG_CURLY_BRACES_ARE_TAGGED, MZCONFIG_ERROR_PRINT_WIDTH, MZCONFIG_ERROR_PRINT_CONTEXT_LENGTH, diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index da264e0c24..417b795f9b 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -93,6 +93,8 @@ ROSYM static Scheme_Object *tainted_uninterned_symbol; static Scheme_Object *read_case_sensitive(int, Scheme_Object *[]); static Scheme_Object *read_bracket_as_paren(int, Scheme_Object *[]); static Scheme_Object *read_brace_as_paren(int, Scheme_Object *[]); +static Scheme_Object *read_bracket_with_tag(int, Scheme_Object *[]); +static Scheme_Object *read_brace_with_tag(int, Scheme_Object *[]); static Scheme_Object *read_accept_graph(int, Scheme_Object *[]); static Scheme_Object *read_accept_compiled(int, Scheme_Object *[]); static Scheme_Object *read_accept_box(int, Scheme_Object *[]); @@ -171,6 +173,8 @@ typedef struct ReadParams { char case_sensitive; char square_brackets_are_parens; char curly_braces_are_parens; + char square_brackets_are_tagged; + char curly_braces_are_tagged; char read_decimal_inexact; char can_read_dot; char can_read_infix_dot; @@ -516,6 +520,8 @@ void scheme_init_read(Scheme_Env *env) GLOBAL_PARAMETER("read-case-sensitive", read_case_sensitive, MZCONFIG_CASE_SENS, env); GLOBAL_PARAMETER("read-square-bracket-as-paren", read_bracket_as_paren, MZCONFIG_SQUARE_BRACKETS_ARE_PARENS, env); GLOBAL_PARAMETER("read-curly-brace-as-paren", read_brace_as_paren, MZCONFIG_CURLY_BRACES_ARE_PARENS, env); + GLOBAL_PARAMETER("read-square-bracket-with-tag", read_bracket_with_tag, MZCONFIG_SQUARE_BRACKETS_ARE_TAGGED, env); + GLOBAL_PARAMETER("read-curly-brace-with-tag", read_brace_with_tag, MZCONFIG_CURLY_BRACES_ARE_TAGGED, env); GLOBAL_PARAMETER("read-accept-graph", read_accept_graph, MZCONFIG_CAN_READ_GRAPH, env); GLOBAL_PARAMETER("read-accept-compiled", read_accept_compiled, MZCONFIG_CAN_READ_COMPILED, env); GLOBAL_PARAMETER("read-accept-box", read_accept_box, MZCONFIG_CAN_READ_BOX, env); @@ -607,6 +613,18 @@ read_brace_as_paren(int argc, Scheme_Object *argv[]) DO_CHAR_PARAM("read-curly-brace-as-paren", MZCONFIG_CURLY_BRACES_ARE_PARENS); } +static Scheme_Object * +read_bracket_with_tag(int argc, Scheme_Object *argv[]) +{ + DO_CHAR_PARAM("read-square-bracket-with-tag", MZCONFIG_SQUARE_BRACKETS_ARE_TAGGED); +} + +static Scheme_Object * +read_brace_with_tag(int argc, Scheme_Object *argv[]) +{ + DO_CHAR_PARAM("read-curly-brace-with-tag", MZCONFIG_CURLY_BRACES_ARE_TAGGED); +} + static Scheme_Object * read_accept_graph(int argc, Scheme_Object *argv[]) { @@ -1070,13 +1088,13 @@ read_inner_inner(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table * case '(': return read_list(port, stxsrc, line, col, pos, ch, ')', mz_shape_cons, 0, ht, indentation, params, table); case '[': - if (!params->square_brackets_are_parens) { + if (!params->square_brackets_are_parens && !params->square_brackets_are_tagged) { scheme_read_err(port, stxsrc, line, col, pos, 1, 0, indentation, "read: illegal use of open square bracket"); return NULL; } else return read_list(port, stxsrc, line, col, pos, ch, ']', mz_shape_cons, 0, ht, indentation, params, table); case '{': - if (!params->curly_braces_are_parens) { + if (!params->curly_braces_are_parens && !params->curly_braces_are_tagged) { scheme_read_err(port, stxsrc, line, col, pos, 1, 0, indentation, "read: illegal use of open curly brace"); return NULL; } else @@ -2325,6 +2343,10 @@ _internal_read(Scheme_Object *port, Scheme_Object *stxsrc, int crc, int cant_fai params.square_brackets_are_parens = SCHEME_TRUEP(v); v = scheme_get_param(config, MZCONFIG_CURLY_BRACES_ARE_PARENS); params.curly_braces_are_parens = SCHEME_TRUEP(v); + v = scheme_get_param(config, MZCONFIG_SQUARE_BRACKETS_ARE_TAGGED); + params.square_brackets_are_tagged = SCHEME_TRUEP(v); + v = scheme_get_param(config, MZCONFIG_CURLY_BRACES_ARE_TAGGED); + params.curly_braces_are_tagged = SCHEME_TRUEP(v); v = scheme_get_param(config, MZCONFIG_READ_DECIMAL_INEXACT); params.read_decimal_inexact = SCHEME_TRUEP(v); v = scheme_get_param(config, MZCONFIG_CAN_READ_QUASI); @@ -2496,6 +2518,11 @@ static Scheme_Object *attach_shape_property(Scheme_Object *list, ReadParams *params, int closer); +static Scheme_Object *attach_shape_tag(Scheme_Object *list, + Scheme_Object *stxsrc, + ReadParams *params, + int closer); + static int next_is_delim(Scheme_Object *port, ReadParams *params, int brackets, @@ -2642,8 +2669,8 @@ read_list(Scheme_Object *port, { Scheme_Object *list = NULL, *last = NULL, *car, *cdr, *pair, *infixed = NULL, *prefetched = NULL; int ch = 0, got_ch_already = 0, effective_ch; - int brackets = params->square_brackets_are_parens; - int braces = params->curly_braces_are_parens; + int brackets = params->square_brackets_are_parens || params->square_brackets_are_tagged; + int braces = params->curly_braces_are_parens || params->curly_braces_are_tagged; intptr_t start, startcol, startline, dotpos, dotcol, dotline, dot2pos, dot2line, dot2col, init_span; scheme_tell_all(port, &startline, &startcol, &start); @@ -2713,6 +2740,7 @@ read_list(Scheme_Object *port, ? scheme_make_stx_w_offset(list, line, col, pos, SPAN(port, pos), stxsrc, STX_SRCTAG) : list); list = attach_shape_property(list, stxsrc, params, closer); + list = attach_shape_tag(list, stxsrc, params, closer); return list; } @@ -2809,6 +2837,7 @@ read_list(Scheme_Object *port, ? scheme_make_stx_w_offset(list, line, col, pos, SPAN(port, pos), stxsrc, STX_SRCTAG) : list); list = attach_shape_property(list, stxsrc, params, closer); + list = attach_shape_tag(list, stxsrc, params, closer); return list; } else if (params->can_read_dot && (effective_ch == '.') @@ -2890,6 +2919,7 @@ read_list(Scheme_Object *port, ? scheme_make_stx_w_offset(list, line, col, pos, SPAN(port, pos), stxsrc, STX_SRCTAG) : list); list = attach_shape_property(list, stxsrc, params, closer); + list = attach_shape_tag(list, stxsrc, params, closer); return list; } } else { @@ -2948,6 +2978,26 @@ static Scheme_Object *attach_shape_property(Scheme_Object *list, return list; } +static Scheme_Object *attach_shape_tag(Scheme_Object *list, + Scheme_Object *stxsrc, + ReadParams *params, + int closer) +{ + Scheme_Object *tag_symbol; + + if (params->square_brackets_are_tagged && closer == ']') { + tag_symbol = scheme_intern_symbol("#%brackets"); + list = scheme_make_pair(tag_symbol, list); + return list; + } else if (params->curly_braces_are_tagged && closer == '}') { + tag_symbol = scheme_intern_symbol("#%braces"); + list = scheme_make_pair(tag_symbol, list); + return list; + } else { + return list; + } +} + static Scheme_Object *read_flonum(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table **ht, diff --git a/racket/src/racket/src/schminc.h b/racket/src/racket/src/schminc.h index 77de7800a8..85f7fb9a60 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 1136 +#define EXPECTED_PRIM_COUNT 1137 #define EXPECTED_UNSAFE_COUNT 106 #define EXPECTED_FLFXNUM_COUNT 69 #define EXPECTED_EXTFL_COUNT 45 diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index c76e71db12..8f27de7232 100644 --- a/racket/src/racket/src/schvers.h +++ b/racket/src/racket/src/schvers.h @@ -13,7 +13,7 @@ consistently.) */ -#define MZSCHEME_VERSION "6.3.0.4" +#define MZSCHEME_VERSION "6.3.0.5" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 3 From 23beaa4793822777b9fa32aec882d8ba8e510151 Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Fri, 2 Oct 2015 18:47:28 -0400 Subject: [PATCH 063/369] comments re mflatt --- pkgs/base/info.rkt | 2 +- racket/src/racket/src/read.c | 42 ++++++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index 348a1bf681..3c80fdb375 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.3.0.4") +(define version "6.3.0.5") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index 417b795f9b..64847c9da6 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -82,6 +82,8 @@ 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 *brackets_symbol; +ROSYM static Scheme_Object *braces_symbol; ROSYM static Scheme_Object *terminating_macro_symbol; ROSYM static Scheme_Object *non_terminating_macro_symbol; ROSYM static Scheme_Object *dispatch_macro_symbol; @@ -419,6 +421,9 @@ void scheme_init_read(Scheme_Env *env) REGISTER_SO(unsyntax_splicing_symbol); REGISTER_SO(quasisyntax_symbol); + REGISTER_SO(brackets_symbol); + REGISTER_SO(braces_symbol); + REGISTER_SO(unresolved_uninterned_symbol); REGISTER_SO(tainted_uninterned_symbol); REGISTER_SO(terminating_macro_symbol); @@ -435,6 +440,9 @@ void scheme_init_read(Scheme_Env *env) unsyntax_splicing_symbol = scheme_intern_symbol("unsyntax-splicing"); quasisyntax_symbol = scheme_intern_symbol("quasisyntax"); + brackets_symbol = scheme_intern_symbol("#%brackets"); + braces_symbol = scheme_intern_symbol("#%braces"); + unresolved_uninterned_symbol = scheme_make_symbol("unresolved"); tainted_uninterned_symbol = scheme_make_symbol("tainted"); @@ -2518,7 +2526,8 @@ static Scheme_Object *attach_shape_property(Scheme_Object *list, ReadParams *params, int closer); -static Scheme_Object *attach_shape_tag(Scheme_Object *list, +static Scheme_Object *attach_shape_tag(Scheme_Object *list, + intptr_t line, intptr_t col, intptr_t pos, intptr_t span, Scheme_Object *stxsrc, ReadParams *params, int closer); @@ -2736,11 +2745,11 @@ read_list(Scheme_Object *port, } if (!list) list = scheme_null; pop_indentation(indentation); + list = attach_shape_tag(list, line, col, pos, SPAN(port, pos), stxsrc, params, closer); list = (stxsrc ? scheme_make_stx_w_offset(list, line, col, pos, SPAN(port, pos), stxsrc, STX_SRCTAG) : list); list = attach_shape_property(list, stxsrc, params, closer); - list = attach_shape_tag(list, stxsrc, params, closer); return list; } @@ -2833,11 +2842,11 @@ read_list(Scheme_Object *port, } pop_indentation(indentation); + list = attach_shape_tag(list, line, col, pos, SPAN(port, pos), stxsrc, params, closer); list = (stxsrc ? scheme_make_stx_w_offset(list, line, col, pos, SPAN(port, pos), stxsrc, STX_SRCTAG) : list); list = attach_shape_property(list, stxsrc, params, closer); - list = attach_shape_tag(list, stxsrc, params, closer); return list; } else if (params->can_read_dot && (effective_ch == '.') @@ -2915,11 +2924,11 @@ read_list(Scheme_Object *port, /* Assert: infixed is NULL (otherwise we raised an exception above) */ pop_indentation(indentation); + list = attach_shape_tag(list, line, col, pos, SPAN(port, pos), stxsrc, params, closer); list = (stxsrc ? scheme_make_stx_w_offset(list, line, col, pos, SPAN(port, pos), stxsrc, STX_SRCTAG) : list); list = attach_shape_property(list, stxsrc, params, closer); - list = attach_shape_tag(list, stxsrc, params, closer); return list; } } else { @@ -2978,24 +2987,29 @@ static Scheme_Object *attach_shape_property(Scheme_Object *list, return list; } -static Scheme_Object *attach_shape_tag(Scheme_Object *list, +static Scheme_Object *attach_shape_tag(Scheme_Object *list, + intptr_t line, intptr_t col, intptr_t pos, intptr_t span, Scheme_Object *stxsrc, ReadParams *params, int closer) { - Scheme_Object *tag_symbol; + Scheme_Object *tag; + tag = NULL; if (params->square_brackets_are_tagged && closer == ']') { - tag_symbol = scheme_intern_symbol("#%brackets"); - list = scheme_make_pair(tag_symbol, list); - return list; + tag = brackets_symbol; } else if (params->curly_braces_are_tagged && closer == '}') { - tag_symbol = scheme_intern_symbol("#%braces"); - list = scheme_make_pair(tag_symbol, list); - return list; - } else { - return list; + tag = braces_symbol; } + + if (tag) { + if (stxsrc) { + tag = scheme_make_stx_w_offset(tag, line, col, pos, span, stxsrc, STX_SRCTAG); + } + list = scheme_make_pair(tag, list); + } + + return list; } static Scheme_Object *read_flonum(Scheme_Object *port, From 35aa2c2398f1e66a6fad7fe4d1f5fb25f7d9f1c4 Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Fri, 2 Oct 2015 19:50:38 -0400 Subject: [PATCH 064/369] first version of read_cdot --- racket/src/racket/include/scheme.h | 1 + racket/src/racket/src/read.c | 79 ++++++++++++++++++++++++++++-- racket/src/racket/src/schminc.h | 2 +- 3 files changed, 76 insertions(+), 6 deletions(-) diff --git a/racket/src/racket/include/scheme.h b/racket/src/racket/include/scheme.h index bfc781f4b0..c9419db4e1 100644 --- a/racket/src/racket/include/scheme.h +++ b/racket/src/racket/include/scheme.h @@ -1348,6 +1348,7 @@ enum { MZCONFIG_CAN_READ_READER, MZCONFIG_CAN_READ_LANG, MZCONFIG_READ_DECIMAL_INEXACT, + MZCONFIG_READ_CDOT, MZCONFIG_PRINT_GRAPH, MZCONFIG_PRINT_STRUCT, diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index 64847c9da6..74f0a6355b 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -84,6 +84,7 @@ ROSYM static Scheme_Object *unsyntax_splicing_symbol; ROSYM static Scheme_Object *quasisyntax_symbol; ROSYM static Scheme_Object *brackets_symbol; ROSYM static Scheme_Object *braces_symbol; +ROSYM static Scheme_Object *dot_symbol; ROSYM static Scheme_Object *terminating_macro_symbol; ROSYM static Scheme_Object *non_terminating_macro_symbol; ROSYM static Scheme_Object *dispatch_macro_symbol; @@ -97,6 +98,7 @@ static Scheme_Object *read_bracket_as_paren(int, Scheme_Object *[]); static Scheme_Object *read_brace_as_paren(int, Scheme_Object *[]); static Scheme_Object *read_bracket_with_tag(int, Scheme_Object *[]); static Scheme_Object *read_brace_with_tag(int, Scheme_Object *[]); +static Scheme_Object *read_cdot(int, Scheme_Object *[]); static Scheme_Object *read_accept_graph(int, Scheme_Object *[]); static Scheme_Object *read_accept_compiled(int, Scheme_Object *[]); static Scheme_Object *read_accept_box(int, Scheme_Object *[]); @@ -177,6 +179,7 @@ typedef struct ReadParams { char curly_braces_are_parens; char square_brackets_are_tagged; char curly_braces_are_tagged; + char read_cdot; char read_decimal_inexact; char can_read_dot; char can_read_infix_dot; @@ -423,6 +426,7 @@ void scheme_init_read(Scheme_Env *env) REGISTER_SO(brackets_symbol); REGISTER_SO(braces_symbol); + REGISTER_SO(dot_symbol); REGISTER_SO(unresolved_uninterned_symbol); REGISTER_SO(tainted_uninterned_symbol); @@ -442,6 +446,7 @@ void scheme_init_read(Scheme_Env *env) brackets_symbol = scheme_intern_symbol("#%brackets"); braces_symbol = scheme_intern_symbol("#%braces"); + dot_symbol = scheme_intern_symbol("#%dot"); unresolved_uninterned_symbol = scheme_make_symbol("unresolved"); tainted_uninterned_symbol = scheme_make_symbol("tainted"); @@ -530,6 +535,7 @@ void scheme_init_read(Scheme_Env *env) GLOBAL_PARAMETER("read-curly-brace-as-paren", read_brace_as_paren, MZCONFIG_CURLY_BRACES_ARE_PARENS, env); GLOBAL_PARAMETER("read-square-bracket-with-tag", read_bracket_with_tag, MZCONFIG_SQUARE_BRACKETS_ARE_TAGGED, env); GLOBAL_PARAMETER("read-curly-brace-with-tag", read_brace_with_tag, MZCONFIG_CURLY_BRACES_ARE_TAGGED, env); + GLOBAL_PARAMETER("read-cdot", read_cdot, MZCONFIG_READ_CDOT, env); GLOBAL_PARAMETER("read-accept-graph", read_accept_graph, MZCONFIG_CAN_READ_GRAPH, env); GLOBAL_PARAMETER("read-accept-compiled", read_accept_compiled, MZCONFIG_CAN_READ_COMPILED, env); GLOBAL_PARAMETER("read-accept-box", read_accept_box, MZCONFIG_CAN_READ_BOX, env); @@ -633,6 +639,12 @@ read_brace_with_tag(int argc, Scheme_Object *argv[]) DO_CHAR_PARAM("read-curly-brace-with-tag", MZCONFIG_CURLY_BRACES_ARE_TAGGED); } +static Scheme_Object * +read_cdot(int argc, Scheme_Object *argv[]) +{ + DO_CHAR_PARAM("read-cdot", MZCONFIG_READ_CDOT); +} + static Scheme_Object * read_accept_graph(int argc, Scheme_Object *argv[]) { @@ -818,6 +830,15 @@ read_delay_load(int argc, Scheme_Object *argv[]) #ifdef DO_STACK_CHECK +static Scheme_Object *read_inner_inner_inner(Scheme_Object *port, + Scheme_Object *stxsrc, + Scheme_Hash_Table **ht, + Scheme_Object *indentation, + ReadParams *params, + int comment_mode, + int pre_char, + Readtable *init_readtable, + int get_info); static Scheme_Object *read_inner_inner(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table **ht, @@ -845,7 +866,7 @@ static void set_need_copy(Scheme_Hash_Table **ht) scheme_hash_set(*ht, tainted_uninterned_symbol, scheme_true); } -static Scheme_Object *read_inner_inner_k(void) +static Scheme_Object *read_inner_inner_inner_k(void) { Scheme_Thread *p = scheme_current_thread; Scheme_Object *o = (Scheme_Object *)p->ku.k.p1; @@ -861,7 +882,7 @@ static Scheme_Object *read_inner_inner_k(void) p->ku.k.p4 = NULL; p->ku.k.p5 = NULL; - return read_inner_inner(o, stxsrc, ht, indentation, params, p->ku.k.i1, p->ku.k.i2, + return read_inner_inner_inner(o, stxsrc, ht, indentation, params, p->ku.k.i1, p->ku.k.i2, table, p->ku.k.i3); } #endif @@ -958,7 +979,7 @@ read_plus_minus_period_leading_number(Scheme_Object *port, Scheme_Object *stxsrc static Scheme_Object * -read_inner_inner(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table **ht, +read_inner_inner_inner(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table **ht, Scheme_Object *indentation, ReadParams *params, int comment_mode, int pre_char, Readtable *table, int get_info) @@ -994,7 +1015,7 @@ read_inner_inner(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table * p->ku.k.i1 = comment_mode; p->ku.k.i2 = pre_char; p->ku.k.i3 = get_info; - return scheme_handle_stack_overflow(read_inner_inner_k); + return scheme_handle_stack_overflow(read_inner_inner_inner_k); } } #endif @@ -1996,6 +2017,50 @@ read_inner_inner(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table * } } +static Scheme_Object * +read_inner_inner(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table **ht, + Scheme_Object *indentation, ReadParams *params, + int comment_mode, int pre_char, Readtable *table, + int get_info) +{ + intptr_t rline = 0, rcol = 0, rpos = 0; + intptr_t dline = 0, dcol = 0, dpos = 0; + Scheme_Object *ret; + int read_cdot, next, found_dot; + + read_cdot = params->read_cdot; + + scheme_tell_all(port, &rline, &rcol, &rpos); + ret = read_inner_inner_inner(port, stxsrc, ht, indentation, params, comment_mode, pre_char, table, get_info); + + if (!read_cdot) { return ret; } + + found_dot = 0; + while ( 1 ) { + next = scheme_peekc_special_ok(port); + if ( next == EOF ) { break; } + if ( scheme_isspace(next) ) { scheme_getc_special_ok(port); continue; } + if ( next == '.' ) { scheme_getc_special_ok(port); found_dot = 1; break; } + break; + } + + if ( found_dot ) { + Scheme_Object *dot, *next; + scheme_tell_all(port, &dline, &dcol, &dpos); + dot = dot_symbol; + if (stxsrc) { + dot = scheme_make_stx_w_offset(dot, dline, dcol, dpos, SPAN(port,dpos), stxsrc, STX_SRCTAG); + } + next = read_inner_inner(port, stxsrc, ht, indentation, params, comment_mode, pre_char, table, get_info); + ret = scheme_make_pair( dot, scheme_make_pair( ret, scheme_make_pair( next, scheme_null ) ) ); + if (stxsrc) { + ret = scheme_make_stx_w_offset(ret, rline, rcol, rpos, SPAN(port,rpos), stxsrc, STX_SRCTAG); + } + } + + return ret; +} + static Scheme_Object * read_inner(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table **ht, Scheme_Object *indentation, ReadParams *params, @@ -2355,6 +2420,8 @@ _internal_read(Scheme_Object *port, Scheme_Object *stxsrc, int crc, int cant_fai params.square_brackets_are_tagged = SCHEME_TRUEP(v); v = scheme_get_param(config, MZCONFIG_CURLY_BRACES_ARE_TAGGED); params.curly_braces_are_tagged = SCHEME_TRUEP(v); + v = scheme_get_param(config, MZCONFIG_READ_CDOT); + params.read_cdot = SCHEME_TRUEP(v); v = scheme_get_param(config, MZCONFIG_READ_DECIMAL_INEXACT); params.read_decimal_inexact = SCHEME_TRUEP(v); v = scheme_get_param(config, MZCONFIG_CAN_READ_QUASI); @@ -3580,6 +3647,7 @@ read_number_or_symbol(int init_ch, int skip_rt, Scheme_Object *port, intptr_t rq_pos = 0, rq_col = 0, rq_line = 0; int case_sens = params->case_sensitive; int decimal_inexact = params->read_decimal_inexact; + int read_cdot = params->read_cdot; Scheme_Object *o; int delim_ok; int ungetc_ok; @@ -3628,7 +3696,8 @@ read_number_or_symbol(int init_ch, int skip_rt, Scheme_Object *port, || (!table && !scheme_isspace(ch) && (((ch < 128) && (delim[ch] & delim_ok)) - || ((ch >= 128) && far_char_ok))) + || ((ch >= 128) && far_char_ok)) + && !(!is_float && !is_not_float && !radix_set && read_cdot && ch == '.')) || table)) { if (table) { int v; diff --git a/racket/src/racket/src/schminc.h b/racket/src/racket/src/schminc.h index 85f7fb9a60..5c5853a607 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 1137 +#define EXPECTED_PRIM_COUNT 1138 #define EXPECTED_UNSAFE_COUNT 106 #define EXPECTED_FLFXNUM_COUNT 69 #define EXPECTED_EXTFL_COUNT 45 From 4451f44ddadd306b82ad259c0d16c21a91ffdd57 Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Sat, 3 Oct 2015 16:42:47 -0400 Subject: [PATCH 065/369] use readtable if available to look up whitespace --- racket/src/racket/src/read.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index 74f0a6355b..7840bcd046 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -2039,7 +2039,9 @@ read_inner_inner(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table * while ( 1 ) { next = scheme_peekc_special_ok(port); if ( next == EOF ) { break; } - if ( scheme_isspace(next) ) { scheme_getc_special_ok(port); continue; } + if ( (table && readtable_kind(table, next, params) & READTABLE_WHITESPACE) + || (!table && scheme_isspace(next)) ) { + scheme_getc_special_ok(port); continue; } if ( next == '.' ) { scheme_getc_special_ok(port); found_dot = 1; break; } break; } From ce0aed77ea20176551a6827efb31b13771bc9b19 Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Sat, 3 Oct 2015 16:45:10 -0400 Subject: [PATCH 066/369] use readtable for detecting dot --- racket/src/racket/src/read.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index 7840bcd046..9141f63ed2 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -2042,7 +2042,9 @@ read_inner_inner(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table * if ( (table && readtable_kind(table, next, params) & READTABLE_WHITESPACE) || (!table && scheme_isspace(next)) ) { scheme_getc_special_ok(port); continue; } - if ( next == '.' ) { scheme_getc_special_ok(port); found_dot = 1; break; } + if ( (table && readtable_effective_char(table, next) == '.') + || (!table && next == '.') ) { + scheme_getc_special_ok(port); found_dot = 1; break; } break; } From 551e4d5a0d395cc04a766b9a8e1c8ed1a5418412 Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Sat, 3 Oct 2015 17:31:07 -0400 Subject: [PATCH 067/369] Adding documentation for new parameters and updating inside/params with other defs near my changes --- .../scribblings/inside/params.scrbl | 9 +++ .../scribblings/reference/read.scrbl | 25 +++++++++ .../scribblings/reference/reader.scrbl | 56 +++++++++++++++---- 3 files changed, 79 insertions(+), 11 deletions(-) diff --git a/pkgs/racket-doc/scribblings/inside/params.scrbl b/pkgs/racket-doc/scribblings/inside/params.scrbl index c0659feede..9602b8edb0 100644 --- a/pkgs/racket-doc/scribblings/inside/params.scrbl +++ b/pkgs/racket-doc/scribblings/inside/params.scrbl @@ -45,6 +45,13 @@ through the following indices: @item{@cppdef{MZCONFIG_CAN_READ_COMPILED} --- @racket[read-accept-compiled]} @item{@cppdef{MZCONFIG_CAN_READ_BOX} --- @racket[read-accept-box]} @item{@cppdef{MZCONFIG_CAN_READ_PIPE_QUOTE} --- @racket[read-accept-bar-quote]} +@item{@cppdef{MZCONFIG_CAN_READ_DOT} --- @racket[read-accept-dot]} +@item{@cppdef{MZCONFIG_CAN_READ_INFIX_DOT} --- @racket[read-accept-infix-dot]} +@item{@cppdef{MZCONFIG_CAN_READ_QUASI} --- @racket[read-accept-quasiquote]} +@item{@cppdef{MZCONFIG_CAN_READ_READER} --- @racket[read-accept-reader]} +@item{@cppdef{MZCONFIG_CAN_READ_LANG} --- @racket[read-accept-lang]} +@item{@cppdef{MZCONFIG_READ_DECIMAL_INEXACT} --- @racket[read-decimal-as-inexact]} +@item{@cppdef{MZCONFIG_READ_CDOT} --- @racket[read-cdot]} @item{@cppdef{MZCONFIG_PRINT_GRAPH} --- @racket[print-graph]} @item{@cppdef{MZCONFIG_PRINT_STRUCT} --- @racket[print-struct]} @@ -53,6 +60,8 @@ through the following indices: @item{@cppdef{MZCONFIG_CASE_SENS} --- @racket[read-case-sensitive]} @item{@cppdef{MZCONFIG_SQUARE_BRACKETS_ARE_PARENS} --- @racket[read-square-brackets-as-parens]} @item{@cppdef{MZCONFIG_CURLY_BRACES_ARE_PARENS} --- @racket[read-curly-braces-as-parens]} +@item{@cppdef{MZCONFIG_SQUARE_BRACKETS_ARE_TAGGED} --- @racket[read-square-brackets-with-tag]} +@item{@cppdef{MZCONFIG_CURLY_BRACES_ARE_TAGGED} --- @racket[read-curly-braces-with-tag]} @item{@cppdef{MZCONFIG_ERROR_PRINT_WIDTH} --- @racket[error-print-width]} diff --git a/pkgs/racket-doc/scribblings/reference/read.scrbl b/pkgs/racket-doc/scribblings/reference/read.scrbl index 635187e1aa..2b64d6b242 100644 --- a/pkgs/racket-doc/scribblings/reference/read.scrbl +++ b/pkgs/racket-doc/scribblings/reference/read.scrbl @@ -217,6 +217,23 @@ A @tech{parameter} that controls whether @litchar["{"] and @litchar["}"] are treated as parentheses. See @secref["parse-pair"] for more information.} +@defboolparam[read-square-bracket-with-tag on?]{ + +A @tech{parameter} that controls whether @litchar{[} and @litchar{]} +are treated as parentheses, but the resulting list tagged with +@racket[#%brackets]. See @secref["parse-pair"] for more information. + +@history[#:added "6.2.900.18"]} + +@defboolparam[read-curly-brace-with-tag on?]{ + +A @tech{parameter} that controls whether @litchar["{"] and +@litchar["}"] are treated as parentheses, but the resulting list +tagged with @racket[#%braces]. See @secref["parse-pair"] for more +information. + +@history[#:added "6.2.900.18"]} + @defboolparam[read-accept-box on?]{ A @tech{parameter} that controls parsing @litchar{#&} input. See @@ -256,6 +273,14 @@ information.} A @tech{parameter} that controls parsing input with two dots to trigger infix conversion. See @secref["parse-pair"] for more information.} +@defboolparam[read-cdot on?]{ + +A @tech{parameter} that controls parsing input with a dot, in a C +structure accessor style. See @secref["parse-cdot"] for more +information. + +@history[#:added "6.2.900.18"]} + @defboolparam[read-accept-quasiquote on?]{ A @tech{parameter} that controls parsing input with @litchar{`} or diff --git a/pkgs/racket-doc/scribblings/reference/reader.scrbl b/pkgs/racket-doc/scribblings/reference/reader.scrbl index 84ff9248cb..9da6e68301 100644 --- a/pkgs/racket-doc/scribblings/reference/reader.scrbl +++ b/pkgs/racket-doc/scribblings/reference/reader.scrbl @@ -388,13 +388,21 @@ elements are themselves in @racket[read-syntax] mode, so that the result is a list or pair of syntax objects that is itself wrapped as a syntax object. If the reader constructs nested pairs because the input included a single delimited @litchar{.}, then only the innermost pair -and outermost pair are wrapped as syntax objects. Whether wrapping a -pair or list, if the pair or list was formed with @litchar{[} and -@litchar{]}, then a @indexed-racket['paren-shape] property is attached -to the result with the value @racket[#\[]; if the list or pair was -formed with @litchar["{"] and @litchar["}"], then a -@racket['paren-shape] property is attached to the result with the -value @racket[#\{]. +and outermost pair are wrapped as syntax objects. + +Whether wrapping a pair or list, if the pair or list was formed with +@litchar{[} and @litchar{]}, then a @indexed-racket['paren-shape] +property is attached to the result with the value @racket[#\[]. If the +@racket[read-square-bracket-with-tag] @tech{parameter} is set to +@racket[#t], then the resulting pair or list is wrapped by the +equivalent of @racket[(cons '#%brackets _pair-or-list)]. + +Similarly, if the list or pair was formed with @litchar["{"] and +@litchar["}"], then a @racket['paren-shape] property is attached to +the result with the value @racket[#\{]. If the +@racket[read-curly-brace-with-tag] @tech{parameter} is set to +@racket[#t], then the resulting pair or list is wrapped by the +equivalent of @racket[(cons '#%braces _pair-or-list)]. If a delimited @litchar{.} appears in any other configuration, then the @exnraise[exn:fail:read]. Similarly, if the reader encounters a @@ -412,12 +420,14 @@ being parsed, then the @exnraise[exn:fail:read]. "(1 . 2 . 3)" ] -If the @racket[read-square-bracket-as-paren] @tech{parameter} is set to +If the @racket[read-square-bracket-as-paren] and +@racket[read-square-bracket-with-tag] @tech{parameter}s are set to @racket[#f], then when the reader encounters @litchar{[} and @litchar{]}, the @exnraise{exn:fail:read}. Similarly, if the -@racket[read-curly-brace-as-paren] @tech{parameter} is set to @racket[#f], -then when the reader encounters @litchar["{"] and @litchar["}"], the -@exnraise{exn:fail:read}. +@racket[read-curly-brace-as-paren] and +@racket[read-curly-brace-with-tag] @tech{parameter}s are set to +@racket[#f], then when the reader encounters @litchar["{"] and +@litchar["}"], the @exnraise{exn:fail:read}. If the @racket[read-accept-dot] @tech{parameter} is set to @racket[#f], then a delimited @litchar{.} triggers an @@ -931,6 +941,30 @@ If the @racket[read-accept-reader] or @racket[read-accept-lang] @tech{parameter} is set to @racket[#f], then if the reader encounters @litchar{#lang} or equivalent @litchar{#!}, the @exnraise[exn:fail:read]. +@section[#:tag "parse-cdot"]{Reading with C-style infix dot notation} + +When the @racket[read-cdot] @tech{parameter} is set to @racket[#t], +then a variety of changes occur in the reader. + +First, symbols can no longer include the character @litchar{.}, unless +the entire symbol is quoted with @litchar{|}. + +Second, numbers can no longer include the character @litchar{.}, +unless the number is prefixed with @litchar{#e} or @litchar{#i}, or an +equivalent prefix as discussed in @secref["parse-number"]. If these +numbers are followed by a @litchar{.} intended to be read as a C-style +infix dot, then there must be separating whitespace. + +Finally, after reading any value, @racket[_x], the reader will seek +over whitespace until it reaches a non-whitespace character. If the +character is not @litchar{.}, then the value, @racket[_x], is returned +as usual. If the character is @litchar{.}, then another value, +@racket[_y], is read and the result @racket[(list '#%dot _x _y)] is +returned. In @racket[read-syntax] mode, the @racket['#%dot] symbol has +the source location information of the @litchar{.} character and the +entire list has the source location information spanning from the +start of @racket[_x] to the end of @racket[_y]. + @subsection{S-Expression Reader Language} @defmodulelang[s-exp] From bbf03997bb0cb8424e7ec39e48760cfca961d40d Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Sat, 3 Oct 2015 19:27:59 -0400 Subject: [PATCH 068/369] correct dot cancelling under readtable --- racket/src/racket/src/read.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index 9141f63ed2..c0cf873d22 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -3702,7 +3702,8 @@ read_number_or_symbol(int init_ch, int skip_rt, Scheme_Object *port, && (((ch < 128) && (delim[ch] & delim_ok)) || ((ch >= 128) && far_char_ok)) && !(!is_float && !is_not_float && !radix_set && read_cdot && ch == '.')) - || table)) { + || (table + && !(!is_float && !is_not_float && !radix_set && read_cdot && readtable_effective_char(table, ch) == '.')))) { if (table) { int v; v = readtable_kind(table, ch, params); From ec713a22c319f84cdb08bb65759e4976258e987d Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Sun, 4 Oct 2015 13:03:22 -0400 Subject: [PATCH 069/369] Ensurce new parameters have false defaults everywhere --- racket/collects/racket/file.rkt | 3 +++ racket/src/racket/src/portfun.c | 3 +++ racket/src/racket/src/startup.inc | 6 +++++- racket/src/racket/src/startup.rktl | 3 +++ racket/src/racket/src/thread.c | 4 ++++ 5 files changed, 18 insertions(+), 1 deletion(-) diff --git a/racket/collects/racket/file.rkt b/racket/collects/racket/file.rkt index 206c85fdc4..aca31018d3 100644 --- a/racket/collects/racket/file.rkt +++ b/racket/collects/racket/file.rkt @@ -244,11 +244,14 @@ (parameterize ([read-case-sensitive #f] [read-square-bracket-as-paren #t] [read-curly-brace-as-paren #t] + [read-square-bracket-with-tag #f] + [read-curly-brace-with-tag #f] [read-accept-box #t] [read-accept-compiled #f] [read-accept-bar-quote #t] [read-accept-graph #t] [read-decimal-as-inexact #t] + [read-cdot #f] [read-accept-dot #t] [read-accept-infix-dot #t] [read-accept-quasiquote #t] diff --git a/racket/src/racket/src/portfun.c b/racket/src/racket/src/portfun.c index ca962a45bc..0f6c4b0c13 100644 --- a/racket/src/racket/src/portfun.c +++ b/racket/src/racket/src/portfun.c @@ -4844,6 +4844,9 @@ static Scheme_Object *default_load(int argc, Scheme_Object *argv[]) config = scheme_extend_config(config, MZCONFIG_CAN_READ_LANG, scheme_true); config = scheme_extend_config(config, MZCONFIG_READ_DECIMAL_INEXACT, scheme_true); config = scheme_extend_config(config, MZCONFIG_READTABLE, scheme_false); + config = scheme_extend_config(config, MZCONFIG_READ_CDOT, scheme_false); + config = scheme_extend_config(config, MZCONFIG_SQUARE_BRACKETS_ARE_TAGGED, scheme_false); + config = scheme_extend_config(config, MZCONFIG_CURLY_BRACES_ARE_TAGGED, scheme_false); } else { config = scheme_extend_config(config, MZCONFIG_CAN_READ_COMPILED, scheme_true); config = scheme_extend_config(config, MZCONFIG_CAN_READ_READER, scheme_true); diff --git a/racket/src/racket/src/startup.inc b/racket/src/racket/src/startup.inc index a8da4cf8ae..5191bd96c0 100644 --- a/racket/src/racket/src/startup.inc +++ b/racket/src/racket/src/startup.inc @@ -331,11 +331,14 @@ "(parameterize((read-case-sensitive #t)" "(read-square-bracket-as-paren #t)" "(read-curly-brace-as-paren #t)" +"(read-square-bracket-with-tag #f)" +"(read-curly-brace-with-tag #f)" "(read-accept-box #t)" "(read-accept-compiled #f)" "(read-accept-bar-quote #t)" "(read-accept-graph #t)" "(read-decimal-as-inexact #t)" +"(read-cdot #f)" "(read-accept-dot #t)" "(read-accept-infix-dot #t)" "(read-accept-quasiquote #t)" @@ -527,7 +530,8 @@ "(not(car a)))))" "(define-values(get-linked-collections)" "(lambda(links-path)" -"(call-with-escape-continuation (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 d830a9998c..79320b2e43 100644 --- a/racket/src/racket/src/startup.rktl +++ b/racket/src/racket/src/startup.rktl @@ -391,11 +391,14 @@ (parameterize ([read-case-sensitive #t] [read-square-bracket-as-paren #t] [read-curly-brace-as-paren #t] + [read-square-bracket-with-tag #f] + [read-curly-brace-with-tag #f] [read-accept-box #t] [read-accept-compiled #f] [read-accept-bar-quote #t] [read-accept-graph #t] [read-decimal-as-inexact #t] + [read-cdot #f] [read-accept-dot #t] [read-accept-infix-dot #t] [read-accept-quasiquote #t] diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index 8957fe383b..3fedeaea0c 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -7977,6 +7977,10 @@ static void make_initial_config(Scheme_Thread *p) init_param(cells, paramz, MZCONFIG_CURLY_BRACES_ARE_PARENS, (scheme_curly_braces_are_parens ? scheme_true : scheme_false)); + init_param(cells, paramz, MZCONFIG_SQUARE_BRACKETS_ARE_TAGGED, scheme_false); + init_param(cells, paramz, MZCONFIG_CURLY_BRACES_ARE_TAGGED, scheme_false); + init_param(cells, paramz, MZCONFIG_READ_CDOT, scheme_false); + init_param(cells, paramz, MZCONFIG_ERROR_PRINT_WIDTH, scheme_make_integer(256)); init_param(cells, paramz, MZCONFIG_ERROR_PRINT_CONTEXT_LENGTH, scheme_make_integer(16)); init_param(cells, paramz, MZCONFIG_ERROR_PRINT_SRCLOC, scheme_true); From fff7bcfb0303208cfd689aaec7d7bef62377781c Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Sun, 4 Oct 2015 13:32:19 -0400 Subject: [PATCH 070/369] initialize new params in read_escape_from_string --- racket/src/racket/src/read.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index c0cf873d22..fb354cd3f2 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -4730,6 +4730,9 @@ static Scheme_Object *read_escape_from_string(char *s, intptr_t len, params.case_sensitive = scheme_case_sensitive; params.square_brackets_are_parens = 1; params.curly_braces_are_parens = 1; + params.square_brackets_are_tagged = 0; + params.curly_braces_are_tagged = 0; + params.read_cdot = 0; params.read_decimal_inexact = 1; params.can_read_dot = 1; params.can_read_infix_dot = 1; From 8c08d221970db7288cf8afb10fb7b67ae9a4c5fe Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Fri, 20 Nov 2015 10:22:36 -0500 Subject: [PATCH 071/369] update cstartup --- racket/src/racket/src/cstartup.inc | 1932 ++++++++++++++-------------- 1 file changed, 967 insertions(+), 965 deletions(-) diff --git a/racket/src/racket/src/cstartup.inc b/racket/src/racket/src/cstartup.inc index 8c1e01fb40..498d29e8fc 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,7,54,46,51,46,48,46,52,84,0,0,0,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,48,46,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, @@ -29,50 +29,50 @@ 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,165,20,193,249,22, -157,4,80,143,42,39,251,22,90,2,19,248,22,165,20,199,249,22,80,2,4, -248,22,166,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,165, +20,14,144,40,39,40,28,248,22,88,248,22,82,194,248,22,168,20,193,249,22, +157,4,80,143,42,39,251,22,90,2,19,248,22,168,20,199,249,22,80,2,4, +248,22,169,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,168, 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,165,20,201,251,22,90,2,19,2,22,2,22,249,22, -80,2,11,248,22,166,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,166,20,195,27,248,22, +248,22,90,2,22,248,22,168,20,201,251,22,90,2,19,2,22,2,22,249,22, +80,2,11,248,22,169,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,169,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,165,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,165,20,23, +22,90,249,22,90,248,22,90,248,22,168,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,168,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,165,20,201,248,22, -166,20,198,27,248,22,164,4,194,249,22,80,248,22,90,248,22,81,196,248,22, -166,20,195,27,248,22,82,248,22,164,4,23,197,1,249,22,157,4,80,143,42, +148,8,36,40,50,11,9,222,33,44,248,22,164,4,248,22,168,20,201,248,22, +169,20,198,27,248,22,164,4,194,249,22,80,248,22,90,248,22,81,196,248,22, +169,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,166,20,198,27,248,22,82,248,22,164, +46,248,22,164,4,248,22,81,201,248,22,169,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,166,20,199,250,22,90,2,7,248,22, -90,248,22,81,199,250,22,91,2,8,248,22,166,20,201,248,22,166,20,202,27, +22,88,195,250,22,91,2,21,9,248,22,169,20,199,250,22,90,2,7,248,22, +90,248,22,81,199,250,22,91,2,8,248,22,169,20,201,248,22,169,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,166,20,199,250, -22,90,2,21,248,22,90,248,22,81,199,250,22,91,2,9,248,22,166,20,201, -248,22,166,20,202,27,248,22,82,248,22,164,4,23,197,1,27,249,22,1,22, +80,143,43,39,28,248,22,88,195,250,22,91,2,21,9,248,22,169,20,199,250, +22,90,2,21,248,22,90,248,22,81,199,250,22,91,2,9,248,22,169,20,201, +248,22,169,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,166,20,204,27,248,22,82,248,22,164,4,196,28,248,22,88,193,20,14,144, +22,169,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,165,20,199,250,22,91,2,5,249,22, -90,2,26,249,22,90,248,22,111,203,2,26,248,22,166,20,202,251,22,90,2, -19,28,249,22,169,9,248,22,158,4,248,22,165,20,200,66,101,108,115,101,10, -248,22,165,20,197,250,22,91,2,21,9,248,22,166,20,200,249,22,80,2,5, -248,22,166,20,202,18,143,94,10,66,118,111,105,100,2,28,27,248,22,82,248, +22,90,249,22,90,21,93,2,26,248,22,168,20,199,250,22,91,2,5,249,22, +90,2,26,249,22,90,248,22,111,203,2,26,248,22,169,20,202,251,22,90,2, +19,28,249,22,169,9,248,22,158,4,248,22,168,20,200,66,101,108,115,101,10, +248,22,168,20,197,250,22,91,2,21,9,248,22,169,20,200,249,22,80,2,5, +248,22,169,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,165,20,199,248,22,102,198,27, -248,22,158,4,248,22,165,20,197,250,22,90,2,27,248,22,90,248,22,81,197, -250,22,91,2,24,248,22,166,20,199,248,22,166,20,202,145,39,9,20,121,145, +22,81,197,250,22,90,2,27,248,22,90,248,22,168,20,199,248,22,102,198,27, +248,22,158,4,248,22,168,20,197,250,22,90,2,27,248,22,90,248,22,81,197, +250,22,91,2,24,248,22,169,20,199,248,22,169,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, @@ -102,7 +102,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 2090); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,48,46,52,84,0,0,0,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,48,46,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,1,145,1, @@ -113,16 +113,16 @@ 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,91,6,121,6,212,9,235,9, 252,9,176,11,23,12,37,12,241,12,217,14,226,14,235,14,249,14,3,15,23, -16,126,16,239,16,56,17,129,17,233,17,6,18,77,18,215,18,30,19,243,19, -105,20,118,20,236,20,249,20,88,21,155,21,168,21,179,21,75,22,193,22,237, -22,92,23,170,25,194,25,56,26,138,27,145,27,197,27,210,27,200,28,216,28, -71,29,230,29,237,29,114,31,191,31,208,31,108,32,128,32,188,32,195,32,55, -33,109,33,128,33,79,34,95,34,56,35,45,36,82,36,91,36,178,37,23,40, -39,40,106,40,127,40,147,40,167,40,224,40,197,43,163,44,179,44,150,45,208, -45,241,45,117,46,20,47,36,47,133,47,150,47,228,49,23,52,39,52,13,54, -201,54,203,54,230,54,246,54,6,55,103,55,170,56,102,57,118,57,127,57,134, -57,200,58,10,60,128,60,174,63,48,64,180,64,125,66,75,67,117,67,225,67, -0,0,173,75,0,0,3,1,5,105,110,115,112,48,69,35,37,117,116,105,108, +16,126,16,251,16,68,17,141,17,245,17,18,18,89,18,227,18,42,19,255,19, +117,20,130,20,248,20,5,21,112,21,179,21,192,21,203,21,99,22,217,22,5, +23,116,23,194,25,218,25,80,26,162,27,169,27,221,27,234,27,224,28,240,28, +95,29,254,29,5,30,138,31,215,31,232,31,132,32,152,32,212,32,219,32,79, +33,133,33,152,33,103,34,119,34,80,35,81,36,118,36,127,36,214,37,59,40, +75,40,142,40,163,40,183,40,203,40,4,41,233,43,199,44,215,44,186,45,244, +45,21,46,153,46,56,47,72,47,169,47,186,47,8,50,59,52,75,52,49,54, +237,54,239,54,10,55,26,55,42,55,139,55,206,56,138,57,154,57,163,57,170, +57,236,58,46,60,164,60,210,63,84,64,216,64,161,66,111,67,153,67,5,68, +0,0,209,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, @@ -185,870 +185,872 @@ 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,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, +248,22,178,15,194,28,192,192,28,248,22,153,7,194,27,248,22,137,16,195,28, +192,192,248,22,138,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,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, +86,94,28,28,248,22,179,15,23,195,2,10,28,248,22,178,15,23,195,2,10, +28,248,22,153,7,23,195,2,28,248,22,137,16,23,195,2,10,248,22,138,16, +23,195,2,11,12,250,22,182,11,2,41,2,42,23,197,2,28,28,248,22,179, +15,23,195,2,249,22,169,9,248,22,180,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,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,86,94,23,195,1,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, +8,248,22,183,15,23,197,2,28,249,22,175,16,2,79,23,195,2,28,248,22, +153,7,195,248,22,186,15,195,194,86,94,23,195,1,27,248,22,128,8,23,195, +1,249,22,187,15,248,22,168,8,250,22,183,16,2,80,28,249,22,175,16,2, +81,23,201,2,23,199,1,250,22,183,16,2,82,23,202,1,2,44,80,144,47, +40,41,2,43,28,248,22,153,7,194,248,22,186,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,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, +92,92,92,34,86,95,28,28,28,248,22,178,15,23,195,2,10,28,248,22,153, +7,23,195,2,28,248,22,137,16,23,195,2,10,248,22,138,16,23,195,2,11, +10,248,22,179,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,178,15,23,196,2,10,28,248,22,153,7,23,196, +2,28,248,22,137,16,23,196,2,10,248,22,138,16,23,196,2,11,10,248,22, +179,15,23,196,2,12,252,22,182,11,2,6,2,45,40,23,199,2,23,200,2, +27,28,248,22,179,15,23,196,2,248,22,180,15,23,196,2,247,22,181,15,86, +95,28,28,248,22,139,16,23,196,2,10,249,22,169,9,247,22,181,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,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, +110,118,101,110,116,105,111,110,32,116,121,112,101,247,22,181,15,28,249,22,169, +9,28,248,22,179,15,23,199,2,248,22,180,15,23,199,2,247,22,181,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,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, +97,116,104,23,202,2,27,27,248,22,143,16,28,248,22,139,16,23,199,2,23, +198,1,248,22,140,16,23,199,1,86,94,28,28,248,22,179,15,23,194,2,10, +28,248,22,178,15,23,194,2,10,28,248,22,153,7,23,194,2,28,248,22,137, +16,23,194,2,10,248,22,138,16,23,194,2,11,12,250,22,182,11,2,41,2, +42,23,196,2,28,28,248,22,179,15,23,194,2,249,22,169,9,248,22,180,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,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,86,94,23, -194,1,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, +23,195,2,23,194,2,248,22,165,8,248,22,183,15,23,196,2,28,249,22,175, +16,2,79,23,195,2,28,248,22,153,7,194,248,22,186,15,194,193,86,94,23, +194,1,27,248,22,128,8,23,195,1,249,22,187,15,248,22,168,8,250,22,183, +16,2,80,28,249,22,175,16,2,81,23,201,2,23,199,1,250,22,183,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,86,94,23,194,1,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, +186,15,193,192,27,248,22,183,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,179,15,198,197,248, +22,186,15,198,249,22,132,16,199,249,22,187,15,249,22,153,8,248,22,183,15, +200,40,198,86,94,23,194,1,28,249,22,169,9,23,197,2,2,43,249,22,132, +16,23,200,1,249,22,187,15,28,249,22,175,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,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, +153,8,202,45,28,249,22,175,16,2,84,23,199,2,249,22,154,8,2,47,249, +22,153,8,200,43,28,249,22,175,16,2,84,23,199,2,249,22,154,8,2,47, +249,22,153,8,200,43,28,249,22,175,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,172,16,0,12,35,114,120,34,94,91,97,45,122,93, +153,8,200,41,28,249,22,175,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,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,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,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, +27,248,22,141,16,23,196,2,28,249,22,171,9,23,195,2,23,197,1,11,28, +248,22,137,16,23,194,2,27,249,22,132,16,23,197,1,23,196,1,28,23,197, +2,90,144,42,11,89,146,42,39,11,248,22,135,16,23,197,2,86,95,23,195, +1,23,194,1,27,28,23,202,2,27,248,22,141,16,23,199,2,28,249,22,171, +9,23,195,2,23,200,2,11,28,248,22,137,16,23,194,2,250,2,86,23,205, +2,23,206,2,249,22,132,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,178, +15,23,196,2,27,249,22,132,16,23,198,2,23,205,2,28,28,248,22,191,15, +193,10,248,22,190,15,193,192,11,11,28,23,193,2,192,86,94,23,193,1,28, +23,203,2,11,27,248,22,141,16,23,200,2,28,249,22,171,9,194,23,201,1, +11,28,248,22,137,16,193,250,2,86,205,206,249,22,132,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, +11,248,22,135,16,23,197,2,86,95,23,195,1,23,194,1,27,28,23,201,2, +27,248,22,141,16,23,199,2,28,249,22,171,9,23,195,2,23,200,2,11,28, +248,22,137,16,23,194,2,250,2,86,23,204,2,23,205,2,249,22,132,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, +2,192,86,94,23,193,1,27,28,248,22,178,15,23,196,2,27,249,22,132,16, +23,198,2,23,204,2,28,28,248,22,191,15,193,10,248,22,190,15,193,192,11, +11,28,23,193,2,192,86,94,23,193,1,28,23,202,2,11,27,248,22,141,16, +23,200,2,28,249,22,171,9,194,23,201,1,11,28,248,22,137,16,193,250,2, +86,204,205,249,22,132,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,135,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,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, +2,11,28,23,193,2,192,86,94,23,193,1,27,28,248,22,178,15,195,27,249, +22,132,16,197,200,28,28,248,22,191,15,193,10,248,22,190,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,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,166,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,166,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,166,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,166,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, +60,11,2,50,222,33,91,28,248,22,88,23,197,2,11,27,249,22,132,16,248, +22,140,16,248,22,81,23,201,2,23,196,2,28,248,22,190,15,23,194,2,250, +2,86,197,198,195,86,94,23,193,1,27,248,22,169,20,23,199,1,28,248,22, +88,23,194,2,11,27,249,22,132,16,248,22,140,16,248,22,81,23,198,2,23, +198,2,28,248,22,190,15,23,194,2,250,2,86,199,200,195,86,94,23,193,1, +27,248,22,169,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,132,16, +248,22,140,16,248,22,81,23,198,2,23,200,2,28,248,22,190,15,23,194,2, +250,2,86,201,202,195,86,94,23,193,1,27,248,22,169,20,23,196,1,28,248, +22,88,23,194,2,11,27,249,22,132,16,248,22,140,16,248,22,81,197,201,28, +248,22,190,15,193,250,2,86,203,204,195,251,2,90,203,204,205,248,22,169,20, +198,86,95,28,28,248,22,178,15,23,195,2,10,28,248,22,153,7,23,195,2, +28,248,22,137,16,23,195,2,10,248,22,138,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,178,15,23,196, +2,10,28,248,22,153,7,23,196,2,28,248,22,137,16,23,196,2,10,248,22, +138,16,23,196,2,11,248,22,137,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,169,9,194,2,49, +112,97,116,104,63,41,41,23,198,2,28,28,248,22,137,16,23,195,2,90,144, +42,11,89,146,42,39,11,248,22,135,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,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,166,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,166,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,166,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,166,20,198,27,248,22,137,16,23,196,1,28,248,22,187,15,193,250, +27,28,249,22,169,9,247,22,180,8,2,43,249,22,80,248,22,187,15,5,1, +46,23,196,1,23,194,1,28,248,22,88,23,194,2,11,27,249,22,132,16,248, +22,140,16,248,22,81,23,198,2,23,200,2,28,248,22,190,15,23,194,2,250, +2,86,201,202,195,86,94,23,193,1,27,248,22,169,20,23,196,1,28,248,22, +88,23,194,2,11,27,249,22,132,16,248,22,140,16,248,22,81,23,198,2,23, +202,2,28,248,22,190,15,23,194,2,250,2,86,203,204,195,86,94,23,193,1, +27,248,22,169,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,132,16, +248,22,140,16,248,22,81,23,198,2,23,204,2,28,248,22,190,15,23,194,2, +250,2,86,205,206,195,86,94,23,193,1,27,248,22,169,20,23,196,1,28,248, +22,88,23,194,2,11,27,249,22,132,16,248,22,140,16,248,22,81,197,205,28, +248,22,190,15,193,250,2,86,23,15,23,16,195,251,2,90,23,15,23,16,23, +17,248,22,169,20,198,27,248,22,140,16,23,196,1,28,248,22,190,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,168,16,23,197,2,23,198,2,28,23,193,2, +120,35,34,92,34,34,27,249,22,171,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,168,16,23,201,2,23,196,2,28,23,193,2,86,94,23,194,1,27,248, +249,22,171,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,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, +249,22,169,9,247,22,180,8,2,43,250,22,183,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,187,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,184,15,195,195,86,95,23, -195,1,23,193,1,27,28,249,22,169,9,247,22,180,8,2,43,250,22,180,16, +43,250,22,183,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,187,15,195,9,27,28,249,22,169,9,247, +22,180,8,2,43,250,22,183,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,187,15,195,195,86,95,23, +195,1,23,193,1,27,28,249,22,169,9,247,22,180,8,2,43,250,22,183,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, +249,22,80,248,22,187,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,175,15,196,11,12,250,22,182,11,2,8,6,14,14,40,108,105,115, +22,4,22,178,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,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,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,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,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,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,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,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,165,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,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,166,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,165,20,23,197,2,27,248,22,166,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, -165,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22,166,20,23,198, -1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1,248,22,166,20, -23,198,1,249,22,94,23,199,2,27,248,22,166,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,165,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22,166,20,23, -198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1,248,22,166, -20,23,198,1,249,22,94,23,196,2,27,248,22,166,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,165,20,23,197,2,27,248,22,166,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,165, -20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22,166,20,23,198,1, -249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1,248,22,166,20,23, -198,1,249,22,94,23,199,2,27,248,22,166,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, -165,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22,166,20,23,198, -1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1,248,22,166,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,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,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,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,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,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,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,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,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,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,176,14,39,248,22,166,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,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,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,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,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,165,20,195, -10,249,22,169,9,2,65,248,22,165,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,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,165,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,142,16,23, -196,1,28,249,22,169,9,248,22,165,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,165,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,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,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,166,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,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, -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,86,94,23,193,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,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,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,86,94,23,193,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,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,165,20,23, -197,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22,165,20,23,204, -2,23,202,2,9,250,22,158,2,248,22,165,20,23,202,2,11,9,27,248,22, -166,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,165,20,23,195,2,250,22,94,249,22,2,22,129,2,250, -22,158,2,248,22,165,20,23,202,2,23,206,2,9,250,22,158,2,248,22,165, -20,23,200,2,11,9,249,80,144,48,8,48,42,23,203,1,248,22,166,20,23, -199,1,27,248,80,144,45,8,30,42,248,22,165,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,166,20,23,200,1,249,22,94,247,22,156, -16,249,80,144,47,8,48,42,23,202,1,248,22,166,20,23,198,1,27,248,80, -144,41,8,30,42,248,22,165,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,166,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,165,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248, -22,165,20,23,202,2,23,207,2,9,250,22,158,2,248,22,165,20,23,200,2, -11,9,249,80,144,49,8,48,42,23,204,1,248,22,166,20,23,199,1,27,248, -80,144,46,8,30,42,248,22,165,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,166,20,23,200,1,249,22,94,247,22,156,16,249,80,144, -48,8,48,42,23,203,1,248,22,166,20,23,198,1,249,22,94,247,22,156,16, -27,248,22,166,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,165,20,23,195,2,250,22,94,249,22,2,22, -129,2,250,22,158,2,248,22,165,20,23,202,2,23,205,2,9,250,22,158,2, -248,22,165,20,23,200,2,11,9,249,80,144,47,8,48,42,23,202,1,248,22, -166,20,23,199,1,27,248,80,144,44,8,30,42,248,22,165,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,166,20,23,200,1,249,22,94, -247,22,156,16,249,80,144,46,8,48,42,23,201,1,248,22,166,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,165,20,195,28,248,22,175,15,193,248, -22,179,15,193,192,250,22,91,27,248,22,165,20,23,198,2,28,248,22,175,15, -193,248,22,179,15,193,192,2,67,248,2,150,2,248,22,166,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, -165,20,23,197,2,249,2,154,2,23,197,1,248,22,166,20,23,199,1,249,2, -154,2,23,195,1,248,22,166,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,86,95, -23,201,1,23,198,1,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,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,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,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,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,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,165,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,86,94,23,195,1,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, -166,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,166,20,23,19,23,19,26,8,80,144,49,8, -49,42,203,204,205,206,23,15,23,16,248,22,166,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,175,15,195,248,22,179,15,195,194,27,27,247,22,157,16,28, +39,11,20,13,144,80,144,39,46,40,26,35,80,144,8,35,47,40,249,22,31, +11,80,144,8,37,46,40,22,145,15,10,22,146,15,10,22,147,15,10,22,148, +15,11,22,149,15,11,22,153,15,10,22,152,15,11,22,154,15,10,22,151,15, +10,22,155,15,10,22,150,15,11,22,156,15,10,22,157,15,10,22,158,15,10, +22,159,15,11,22,160,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,178,15,23,195,2,10,28,248,22, +153,7,23,195,2,28,248,22,137,16,23,195,2,10,248,22,138,16,23,195,2, +11,12,250,22,182,11,23,196,2,2,48,23,197,2,28,248,22,137,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,178,15,23,195,2,10,28,248,22,153,7,23,195,2,28,248,22,137,16,23, +195,2,10,248,22,138,16,23,195,2,11,12,250,22,182,11,23,196,2,2,48, +23,197,2,28,248,22,137,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,178,15,23,195,2,10,28,248, +22,153,7,23,195,2,28,248,22,137,16,23,195,2,10,248,22,138,16,23,195, +2,11,12,250,22,182,11,23,196,2,2,48,23,197,2,28,248,22,137,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,182,11,23,196,1,2,54,23,197,1,86,94,28,28,248,22,178,15,23, +194,2,10,28,248,22,153,7,23,194,2,28,248,22,137,16,23,194,2,10,248, +22,138,16,23,194,2,11,12,250,22,182,11,2,15,2,48,23,196,2,28,248, +22,137,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,178,15,23,196,2,10,28,248,22,153,7,23, +196,2,28,248,22,137,16,23,196,2,10,248,22,138,16,23,196,2,11,12,250, +22,182,11,2,15,2,48,23,198,2,28,248,22,137,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,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,178,15,23,194, +2,10,28,248,22,153,7,23,194,2,28,248,22,137,16,23,194,2,10,248,22, +138,16,23,194,2,11,12,250,22,182,11,2,17,2,48,23,196,2,28,248,22, +137,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,178,15,23,197,2,10,28,248,22,153,7,23,197,2,28, +248,22,137,16,23,197,2,10,248,22,138,16,23,197,2,11,12,250,22,182,11, +2,17,2,48,23,199,2,28,248,22,137,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,178,15,23,198,2, +10,28,248,22,153,7,23,198,2,28,248,22,137,16,23,198,2,10,248,22,138, +16,23,198,2,11,12,250,22,182,11,2,17,2,48,23,200,2,28,248,22,137, +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,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,155,16,2,55,28,248,22,139,16,23,194,2,248,22,142,16,23, +194,1,28,248,22,138,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22, +135,16,249,22,140,16,250,80,144,49,43,42,248,22,155,16,2,56,11,11,248, +22,155,16,2,57,86,95,23,195,1,23,194,1,248,22,142,16,249,22,140,16, +23,199,1,23,196,1,27,250,80,144,44,43,42,248,22,155,16,2,56,23,197, +1,10,28,23,193,2,248,22,142,16,23,194,1,11,249,80,144,41,55,40,39, +80,144,41,8,40,42,27,248,22,155,16,2,58,28,248,22,139,16,23,194,2, +248,22,142,16,23,194,1,28,248,22,138,16,23,194,2,90,144,42,11,89,146, +42,39,11,248,22,135,16,249,22,140,16,250,80,144,49,43,42,248,22,155,16, +2,56,11,11,248,22,155,16,2,57,86,95,23,195,1,23,194,1,248,22,142, +16,249,22,140,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22,155, +16,2,56,23,197,1,10,28,23,193,2,248,22,142,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, +35,80,144,8,36,47,40,249,22,31,11,80,144,8,38,46,40,22,145,15,10, +22,146,15,10,22,147,15,10,22,148,15,11,22,149,15,11,22,153,15,10,22, +152,15,11,22,154,15,10,22,151,15,10,22,155,15,10,22,150,15,11,22,156, +15,10,22,157,15,10,22,158,15,10,22,159,15,11,22,160,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,132, +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,190,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,186,15,23,196,1,28,248,22,139,16,23, +194,2,192,249,22,140,16,23,195,1,27,247,80,144,43,54,42,28,23,193,2, +192,86,94,23,193,1,247,22,156,16,28,248,22,142,8,23,195,2,27,248,22, +187,15,23,196,1,28,248,22,139,16,23,194,2,192,249,22,140,16,23,195,1, +27,247,80,144,43,54,42,28,23,193,2,192,86,94,23,193,1,247,22,156,16, +28,248,22,178,15,23,195,2,28,248,22,139,16,23,195,2,193,249,22,140,16, +23,196,1,27,247,80,144,42,54,42,28,23,193,2,192,86,94,23,193,1,247, +22,156,16,193,27,248,22,155,16,2,55,28,248,22,139,16,23,194,2,248,22, +142,16,23,194,1,28,248,22,138,16,23,194,2,90,144,42,11,89,146,42,39, +11,248,22,135,16,249,22,140,16,250,80,144,49,43,42,248,22,155,16,2,56, +11,11,248,22,155,16,2,57,86,95,23,195,1,23,194,1,248,22,142,16,249, +22,140,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22,155,16,2, +56,23,197,1,10,28,23,193,2,248,22,142,16,23,194,1,11,28,248,22,139, +16,23,195,2,193,249,22,140,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,156,16,28,248, +22,139,16,23,195,2,248,22,142,16,23,195,1,28,248,22,138,16,23,195,2, +90,144,42,11,89,146,42,39,11,248,22,135,16,249,22,140,16,250,80,144,48, +43,42,248,22,155,16,2,56,11,11,248,22,155,16,2,57,86,95,23,195,1, +23,194,1,248,22,142,16,249,22,140,16,23,200,1,23,196,1,27,250,80,144, +43,43,42,248,22,155,16,2,56,23,198,1,10,28,23,193,2,248,22,142,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,168,20,23,199,2,28,248,22,153,7,23,194,2,27,248,22,186, +15,23,195,1,28,248,22,139,16,23,194,2,192,249,22,140,16,23,195,1,27, +247,80,144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22,156,16,28, +248,22,142,8,23,194,2,27,248,22,187,15,23,195,1,28,248,22,139,16,23, +194,2,192,249,22,140,16,23,195,1,27,247,80,144,46,54,42,28,23,193,2, +192,86,94,23,193,1,247,22,156,16,28,248,22,178,15,23,194,2,28,248,22, +139,16,23,194,2,192,249,22,140,16,23,195,1,27,247,80,144,45,54,42,28, +23,193,2,192,86,94,23,193,1,247,22,156,16,192,27,248,22,169,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,168,20,23,197,2,27,248,22,169,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,168,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22,169, +20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1,248, +22,169,20,23,198,1,249,22,94,23,199,2,27,248,22,169,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,168,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22, +169,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1, +248,22,169,20,23,198,1,249,22,94,23,196,2,27,248,22,169,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,168,20,23,197,2,27,248,22,169,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,168,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22,169,20, +23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1,248,22, +169,20,23,198,1,249,22,94,23,199,2,27,248,22,169,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,168,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22,169, +20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1,248, +22,169,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,155,16,2,58,28,248,22,139,16, +23,194,2,248,22,142,16,23,194,1,28,248,22,138,16,23,194,2,90,144,42, +11,89,146,42,39,11,248,22,135,16,249,22,140,16,250,80,144,49,43,42,248, +22,155,16,2,56,11,11,248,22,155,16,2,57,86,95,23,195,1,23,194,1, +248,22,142,16,249,22,140,16,23,199,1,23,196,1,27,250,80,144,44,43,42, +248,22,155,16,2,56,23,197,1,10,28,23,193,2,248,22,142,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,132,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,132, +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,186,15,23,195,1,28,248,22,139,16,23,194,2,192,249,22,140, +16,23,195,1,27,247,80,144,47,54,42,28,23,193,2,192,86,94,23,193,1, +247,22,156,16,28,248,22,142,8,23,194,2,27,248,22,187,15,23,195,1,28, +248,22,139,16,23,194,2,192,249,22,140,16,23,195,1,27,247,80,144,47,54, +42,28,23,193,2,192,86,94,23,193,1,247,22,156,16,28,248,22,178,15,23, +194,2,28,248,22,139,16,23,194,2,192,249,22,140,16,23,195,1,27,247,80, +144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22,156,16,192,250,22, +94,248,22,90,11,28,247,22,163,16,28,247,22,164,16,248,22,90,250,22,132, +16,248,22,155,16,2,61,250,22,158,2,23,204,2,2,59,247,22,171,8,2, +60,9,9,28,247,22,164,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,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,135,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,178,15,23, +194,2,28,248,22,191,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,135,16, +23,197,1,86,95,23,195,1,23,194,1,28,248,22,178,15,23,194,2,28,248, +22,191,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,135,16,23,197,1,86, +95,23,195,1,23,194,1,28,248,22,178,15,23,194,2,28,248,22,191,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,135,16,23,197,1,86,95,23,195,1, +23,194,1,28,248,22,178,15,23,194,2,28,248,22,191,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,135,16,23,198,2,86,95,23,195,1,23,194,1,28,248,22,178,15,23, +194,2,28,248,22,191,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,135,16, +23,197,1,86,95,23,195,1,23,194,1,28,248,22,178,15,23,194,2,28,248, +22,191,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,135,16,23,197,1,86, +95,23,195,1,23,194,1,28,248,22,178,15,23,194,2,28,248,22,191,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,135,16,23,197,1,86,95,23,195,1, +23,194,1,28,248,22,178,15,23,194,2,28,248,22,191,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,190,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,176,14,39,248,22,169,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,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,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,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,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, +168,20,195,10,249,22,169,9,2,65,248,22,168,20,195,28,27,248,22,102,194, +28,248,22,178,15,193,10,28,248,22,153,7,193,28,248,22,137,16,193,10,248, +22,138,16,193,11,27,248,22,88,248,22,104,195,28,192,192,248,22,184,16,248, +22,111,195,11,11,11,11,28,248,22,191,15,249,22,132,16,23,196,2,23,198, +2,27,248,22,68,248,22,182,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,175,16,248,22,111,23,198,2,247,22,171, +8,27,248,22,142,16,249,22,140,16,248,22,102,23,200,2,23,198,1,28,249, +22,169,9,248,22,168,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, +145,16,23,196,1,28,249,22,169,9,248,22,168,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,168,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,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,135,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,169,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,35,80,144,8,40,47,40,249,22,31,11,80,144,8,42,46, +40,22,145,15,10,22,146,15,10,22,147,15,10,22,148,15,11,22,149,15,11, +22,153,15,10,22,152,15,11,22,154,15,10,22,151,15,10,22,155,15,10,22, +150,15,11,22,156,15,10,22,157,15,10,22,158,15,10,22,159,15,11,22,160, +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,49,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,173,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, +86,94,23,193,1,249,22,7,23,197,1,23,198,1,90,144,42,11,89,146,42, +39,11,248,22,135,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,173,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,86,94,23,193,1,249,22,7,23,197,1,23,196,1,90,144,42,11,89, +146,42,39,11,248,22,135,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,168,20,23,197,2,250,22,94,249, +22,2,22,129,2,250,22,158,2,248,22,168,20,23,204,2,23,202,2,9,250, +22,158,2,248,22,168,20,23,202,2,11,9,27,248,22,169,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, -165,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22,165, -20,23,202,2,23,203,2,9,250,22,158,2,248,22,165,20,23,200,2,11,9, -249,80,144,49,8,48,42,23,200,1,248,22,166,20,23,199,1,27,248,80,144, -46,8,30,42,248,22,165,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,166,20,23,200,1,249,22,94,247,22,156,16,249,80,144,48,8, -48,42,23,199,1,248,22,166,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,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,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,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,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,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, -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,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,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,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, -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, +168,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22,168, +20,23,202,2,23,206,2,9,250,22,158,2,248,22,168,20,23,200,2,11,9, +249,80,144,48,8,48,42,23,203,1,248,22,169,20,23,199,1,27,248,80,144, +45,8,30,42,248,22,168,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,169,20,23,200,1,249,22,94,247,22,159,16,249,80,144,47,8, +48,42,23,202,1,248,22,169,20,23,198,1,27,248,80,144,41,8,30,42,248, +22,168,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,169,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,168,20,23,195, +2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22,168,20,23,202,2, +23,207,2,9,250,22,158,2,248,22,168,20,23,200,2,11,9,249,80,144,49, +8,48,42,23,204,1,248,22,169,20,23,199,1,27,248,80,144,46,8,30,42, +248,22,168,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, +169,20,23,200,1,249,22,94,247,22,159,16,249,80,144,48,8,48,42,23,203, +1,248,22,169,20,23,198,1,249,22,94,247,22,159,16,27,248,22,169,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,168,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2, +248,22,168,20,23,202,2,23,205,2,9,250,22,158,2,248,22,168,20,23,200, +2,11,9,249,80,144,47,8,48,42,23,202,1,248,22,169,20,23,199,1,27, +248,80,144,44,8,30,42,248,22,168,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,169,20,23,200,1,249,22,94,247,22,159,16,249,80, +144,46,8,48,42,23,201,1,248,22,169,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,168,20,195,28,248,22,178,15,193,248,22,182,15,193,192,250, +22,91,27,248,22,168,20,23,198,2,28,248,22,178,15,193,248,22,182,15,193, +192,2,67,248,2,150,2,248,22,169,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,168,20,23,197,2,249, +2,154,2,23,197,1,248,22,169,20,23,199,1,249,2,154,2,23,195,1,248, +22,169,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,132,16,202,199,200,86,95,23,201,1,23,198,1, +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,178,15,23,202,2,248,22,182,15,23,202,1, +23,201,1,250,22,176,7,28,248,22,178,15,23,205,2,248,22,182,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,159,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,159,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,178,15,23,195,2,249,22, +132,16,23,196,1,23,199,2,248,22,132,2,23,195,1,28,28,248,22,178,15, +248,22,168,20,23,204,2,248,22,191,15,23,194,2,10,27,250,22,1,22,132, +16,23,197,1,23,202,2,28,28,248,22,88,23,200,2,10,248,22,191,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,178,15,202,248,22,182,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,86,94,23,195,1,11,28,23,193,2,250,80,144,48,8,32,42, +198,23,196,1,23,15,11,2,28,200,249,22,132,16,194,202,192,26,8,80,144, +50,8,49,42,204,205,206,23,15,23,16,23,17,248,22,169,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,169,20,23,19,23,19,26,8,80,144,49,8,49,42,203,204,205,206, +23,15,23,16,248,22,169,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,178, +15,195,248,22,182,15,195,194,27,27,247,22,160,16,28,248,22,88,23,194,2, +9,28,248,22,81,23,194,2,28,248,22,149,2,248,22,168,20,23,195,2,250, +22,94,249,22,2,22,129,2,250,22,158,2,248,22,168,20,23,202,2,23,203, +2,9,250,22,158,2,248,22,168,20,23,200,2,11,9,249,80,144,49,8,48, +42,23,200,1,248,22,169,20,23,199,1,27,248,80,144,46,8,30,42,248,22, +168,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,169,20, +23,200,1,249,22,94,247,22,159,16,249,80,144,48,8,48,42,23,199,1,248, +22,169,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,188,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,184,11,2,37, +2,69,2,70,202,192,28,248,22,179,15,198,248,22,180,15,198,247,22,181,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,188,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,184,11,2,37,2,69,2,70,202,192,28,248,22,179,15,198,248, +22,180,15,198,247,22,181,15,250,2,158,2,196,197,195,248,22,190,15,27,250, +22,132,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,137,16,23,196,2,249,22,132,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,190,15,249,22,132,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,184,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,179, +15,195,249,22,132,16,196,194,192,27,247,22,161,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,162,16,11,86,95,28,28,248,22,179,15,23,194,2,10,28,248, +22,178,15,23,194,2,10,28,248,22,153,7,23,194,2,28,248,22,137,16,23, +194,2,10,248,22,138,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,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,135,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,188,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,184,11,2,37,2,69,2,70,201,192,28,248,22,179,15,197,248,22,180, +15,197,247,22,181,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,188,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, +184,11,2,37,2,69,2,70,204,192,28,248,22,179,15,200,248,22,180,15,200, +247,22,181,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,188, +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,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,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,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,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, +94,23,193,1,251,22,184,11,2,37,2,69,2,70,204,192,28,248,22,179,15, +200,248,22,180,15,200,247,22,181,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,188,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,184,11,2,37,2,69,2,70,205,192,28,248,22, +179,15,201,248,22,180,15,201,247,22,181,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,188,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,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,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, +70,205,192,28,248,22,179,15,201,248,22,180,15,201,247,22,181,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,179,15, +23,199,2,10,28,248,22,178,15,23,199,2,10,28,248,22,153,7,23,199,2, +28,248,22,137,16,23,199,2,10,248,22,138,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,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,135,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,184,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,188,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,184,11,2, +37,2,69,2,70,23,17,192,28,248,22,179,15,205,248,22,180,15,205,247,22, +181,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,188,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,184,11,2,37,2,69,2,70,23,17,192,28,248,22,179,15,205, +248,22,180,15,205,247,22,181,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,179,15,195,249,22,132,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,188,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,184,11,2,37,2,69,2,70,202,192,28,248,22,179,15,198,248,22, +180,15,198,247,22,181,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,188,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,166,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,50,42,248,22,166,20,23,198,1,86,94,23,193,1,248, -80,144,45,8,50,42,248,22,166,20,23,196,1,86,94,23,193,1,27,248,22, -166,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,166,20,23,198,1,86, -94,23,193,1,248,80,144,43,8,50,42,248,22,166,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,166,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,166,20,23,198, -1,86,94,23,193,1,248,80,144,45,8,51,42,248,22,166,20,23,196,1,86, -94,23,193,1,27,248,22,166,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,51,42,248, -22,166,20,23,198,1,86,94,23,193,1,248,80,144,43,8,51,42,248,22,166, -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,166,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,166,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,139,16,249,22,137,16,23,198,1,247,22,153,16,248,80,144,51, -8,53,42,248,22,166,20,23,198,1,86,94,23,193,1,248,80,144,49,8,53, -42,248,22,166,20,23,196,1,86,94,23,193,1,27,248,22,166,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,139,16,249,22,137,16,23,198,1,247,22,153, -16,248,80,144,49,8,53,42,248,22,166,20,23,198,1,86,94,23,193,1,248, -80,144,47,8,53,42,248,22,166,20,23,196,1,86,94,23,193,1,27,248,22, -166,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,166,20,23,198,1,28,248,22,88,23,194, +11,2,37,2,69,2,70,202,192,28,248,22,179,15,198,248,22,180,15,198,247, +22,181,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,188,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,184,11,2,37,2,69,2,70,203,192, +28,248,22,179,15,199,248,22,180,15,199,247,22,181,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,188,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,184,11,2,37,2,69,2,70,203,192,28,248,22,179, +15,199,248,22,180,15,199,247,22,181,15,251,2,169,2,198,199,200,196,90,144, +41,11,89,146,41,39,11,86,95,28,28,248,22,179,15,23,196,2,10,28,248, +22,178,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248,22,137,16,23, +196,2,10,248,22,138,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,135,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, +184,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,179,15,195,249,22,132,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,188,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,184,11,2,37,2,69,2,70,200,192,28,248,22,179,15,196,248, +22,180,15,196,247,22,181,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,188,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,184,11,2,37,2,69,2,70,202,192,28,248,22,179,15,198,248,22, +180,15,198,247,22,181,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,188,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,184,11,2,37,2,69,2,70,202,192,28,248,22, +179,15,198,248,22,180,15,198,247,22,181,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,179,15,23,196,2,10,28,248,22,178,15, +23,196,2,10,28,248,22,153,7,23,196,2,28,248,22,137,16,23,196,2,10, +248,22,138,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,135,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,184,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,179,15,195,249,22,132,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,139,16,23,194,2,248,22,142,16,23,194,1,28,248,22,138,16,23, +194,2,90,144,42,11,89,146,42,39,11,248,22,135,16,249,22,140,16,250,80, +144,50,43,42,248,22,155,16,2,56,11,11,248,22,155,16,2,57,86,95,23, +195,1,23,194,1,248,22,142,16,249,22,140,16,23,199,1,23,196,1,27,250, +80,144,45,43,42,248,22,155,16,2,56,23,197,1,10,28,23,193,2,248,22, +142,16,23,194,1,11,28,23,193,2,249,22,80,248,22,142,16,249,22,140,16, +23,198,1,247,22,156,16,27,248,22,169,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,142,16,249,22,140,16,23,198,1,247,22,156,16,248,80,144,47,8, +50,42,248,22,169,20,23,198,1,86,94,23,193,1,248,80,144,45,8,50,42, +248,22,169,20,23,196,1,86,94,23,193,1,27,248,22,169,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,142,16,249,22,140,16,23,198,1,247,22,156,16, +248,80,144,45,8,50,42,248,22,169,20,23,198,1,86,94,23,193,1,248,80, +144,43,8,50,42,248,22,169,20,23,196,1,28,248,22,88,23,195,2,9,27, +27,248,22,81,23,197,2,28,248,22,139,16,23,194,2,248,22,142,16,23,194, +1,28,248,22,138,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,135, +16,249,22,140,16,250,80,144,50,43,42,248,22,155,16,2,56,11,11,248,22, +155,16,2,57,86,95,23,195,1,23,194,1,248,22,142,16,249,22,140,16,23, +199,1,23,196,1,27,250,80,144,45,43,42,248,22,155,16,2,56,23,197,1, +10,28,23,193,2,248,22,142,16,23,194,1,11,28,23,193,2,249,22,80,248, +22,142,16,249,22,140,16,23,198,1,247,22,156,16,27,248,22,169,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,142,16,249,22,140,16,23,198,1,247,22, +156,16,248,80,144,47,8,51,42,248,22,169,20,23,198,1,86,94,23,193,1, +248,80,144,45,8,51,42,248,22,169,20,23,196,1,86,94,23,193,1,27,248, +22,169,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,142,16,249,22,140,16, +23,198,1,247,22,156,16,248,80,144,45,8,51,42,248,22,169,20,23,198,1, +86,94,23,193,1,248,80,144,43,8,51,42,248,22,169,20,23,196,1,27,248, +22,155,16,2,58,28,248,22,139,16,23,194,2,248,22,142,16,23,194,1,28, +248,22,138,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,135,16,249, +22,140,16,250,80,144,49,43,42,248,22,155,16,2,56,11,11,248,22,155,16, +2,57,86,95,23,195,1,23,194,1,248,22,142,16,249,22,140,16,23,199,1, +23,196,1,27,250,80,144,44,43,42,248,22,155,16,2,56,23,197,1,10,28, +23,193,2,248,22,142,16,23,194,1,11,28,248,22,88,23,195,2,9,27,27, +248,22,81,23,197,2,28,248,22,139,16,23,194,2,248,22,142,16,23,194,1, +28,248,22,138,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,135,16, +249,22,140,16,250,80,144,50,43,42,248,22,155,16,2,56,11,11,248,22,155, +16,2,57,86,95,23,195,1,23,194,1,248,22,142,16,249,22,140,16,23,199, +1,23,196,1,27,250,80,144,45,43,42,248,22,155,16,2,56,23,197,1,10, +28,23,193,2,248,22,142,16,23,194,1,11,28,23,193,2,249,22,80,248,22, +142,16,249,22,140,16,23,198,1,247,22,156,16,27,248,22,169,20,23,199,1, +28,248,22,88,23,194,2,9,27,27,248,22,81,23,196,2,28,248,22,139,16, +23,194,2,248,22,142,16,23,194,1,28,248,22,138,16,23,194,2,90,144,42, +11,89,146,42,39,11,248,22,135,16,249,22,140,16,250,80,144,54,43,42,248, +22,155,16,2,56,11,11,248,22,155,16,2,57,86,95,23,195,1,23,194,1, +248,22,142,16,249,22,140,16,23,199,1,23,196,1,27,250,80,144,49,43,42, +248,22,155,16,2,56,23,197,1,10,28,23,193,2,248,22,142,16,23,194,1, +11,28,23,193,2,249,22,80,248,22,142,16,249,22,140,16,23,198,1,247,22, +156,16,27,248,22,169,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,142,16, +249,22,140,16,23,198,1,247,22,156,16,248,80,144,51,8,53,42,248,22,169, +20,23,198,1,86,94,23,193,1,248,80,144,49,8,53,42,248,22,169,20,23, +196,1,86,94,23,193,1,27,248,22,169,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,139,16,249,22,137,16,23,198,1,247,22,153,16,248,80,144,49,8, -53,42,248,22,166,20,23,198,1,86,94,23,193,1,248,80,144,47,8,53,42, -248,22,166,20,23,196,1,86,94,23,193,1,27,248,22,166,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,139,16,249,22,137,16,23,198,1,247,22,153,16, -248,80,144,47,8,53,42,248,22,166,20,23,198,1,86,94,23,193,1,248,80, -144,45,8,53,42,248,22,166,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,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,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,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,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,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, -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,166,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, -139,16,249,22,137,16,23,198,1,247,22,153,16,248,80,144,57,8,53,42,248, -22,166,20,23,198,1,86,94,23,193,1,248,80,144,55,8,53,42,248,22,166, -20,23,196,1,86,94,23,193,1,27,248,22,166,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,139,16,249,22,137,16,23,198,1,247,22,153,16,248,80,144, -55,8,53,42,248,22,166,20,23,198,1,86,94,23,193,1,248,80,144,53,8, -53,42,248,22,166,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,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,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,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,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,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, 19799); +80,248,22,142,16,249,22,140,16,23,198,1,247,22,156,16,248,80,144,49,8, +53,42,248,22,169,20,23,198,1,86,94,23,193,1,248,80,144,47,8,53,42, +248,22,169,20,23,196,1,86,94,23,193,1,27,248,22,169,20,23,197,1,28, +248,22,88,23,194,2,9,27,27,248,22,81,23,196,2,28,248,22,139,16,23, +194,2,248,22,142,16,23,194,1,28,248,22,138,16,23,194,2,90,144,42,11, +89,146,42,39,11,248,22,135,16,249,22,140,16,250,80,144,52,43,42,248,22, +155,16,2,56,11,11,248,22,155,16,2,57,86,95,23,195,1,23,194,1,248, +22,142,16,249,22,140,16,23,199,1,23,196,1,27,250,80,144,47,43,42,248, +22,155,16,2,56,23,197,1,10,28,23,193,2,248,22,142,16,23,194,1,11, +28,23,193,2,249,22,80,248,22,142,16,249,22,140,16,23,198,1,247,22,156, +16,27,248,22,169,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,142,16,249, +22,140,16,23,198,1,247,22,156,16,248,80,144,49,8,53,42,248,22,169,20, +23,198,1,86,94,23,193,1,248,80,144,47,8,53,42,248,22,169,20,23,196, +1,86,94,23,193,1,27,248,22,169,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,142,16,249,22,140,16,23,198,1,247,22,156,16,248,80,144,47,8,53, +42,248,22,169,20,23,198,1,86,94,23,193,1,248,80,144,45,8,53,42,248, +22,169,20,23,196,1,27,247,22,163,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,132,16,248,22,155,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,155,16,2, +55,9,28,193,249,22,80,195,194,192,27,247,22,163,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,132,16,248, +22,155,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,155,16,2,55,9,28,193,249,22,80,195,194,192,27,247,22,163,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,132,16,248,22,155,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,155,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,139,16,23,194,2,248, +22,142,16,23,194,1,28,248,22,138,16,23,194,2,90,144,42,11,89,146,42, +39,11,248,22,135,16,249,22,140,16,250,80,144,60,43,42,248,22,155,16,2, +56,11,11,248,22,155,16,2,57,86,95,23,195,1,23,194,1,248,22,142,16, +249,22,140,16,23,199,1,23,196,1,27,250,80,144,55,43,42,248,22,155,16, +2,56,23,197,1,10,28,23,193,2,248,22,142,16,23,194,1,11,28,23,193, +2,249,22,80,248,22,142,16,249,22,140,16,23,198,1,247,22,156,16,27,248, +22,169,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,142,16,249,22,140,16, +23,198,1,247,22,156,16,248,80,144,57,8,53,42,248,22,169,20,23,198,1, +86,94,23,193,1,248,80,144,55,8,53,42,248,22,169,20,23,196,1,86,94, +23,193,1,27,248,22,169,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,142, +16,249,22,140,16,23,198,1,247,22,156,16,248,80,144,55,8,53,42,248,22, +169,20,23,198,1,86,94,23,193,1,248,80,144,53,8,53,42,248,22,169,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,152,15,10,22,159, +15,10,22,160,15,10,22,161,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,152,15, +10,22,159,15,10,22,160,15,10,22,161,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,152,15,10,22,159,15,10,22,160,15,10,22,161,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,155, +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,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,167,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,44,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,44,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, 19835); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,48,46,52,84,0,0,0,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,48,46,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,248,1,0,0,3,1,5,105,110,115,112,48,76,35,37,112, @@ -1079,7 +1081,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 576); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,48,46,52,84,0,0,0,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,48,46,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,1,108,1, @@ -1114,65 +1116,65 @@ 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,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, +114,101,100,27,252,22,132,16,28,249,22,169,9,23,201,2,2,27,86,94,23, +199,1,23,200,1,28,248,22,137,16,23,200,2,249,22,132,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,147,16, +181,8,249,80,144,50,46,42,23,203,1,80,144,50,39,41,27,250,22,150,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,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, +6,33,42,23,199,1,23,196,1,23,197,1,23,195,1,27,252,22,132,16,28, +249,22,169,9,23,201,2,2,27,86,94,23,199,1,23,200,1,28,248,22,137, +16,23,200,2,249,22,132,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,147,16,196,11,32,0,88,148,8,36,39, +203,1,80,144,50,39,41,27,250,22,150,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,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, +23,197,1,23,195,1,27,250,22,132,16,28,249,22,169,9,23,199,2,2,27, +86,94,23,197,1,23,198,1,28,248,22,137,16,23,198,2,249,22,132,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, +80,144,48,46,42,23,201,1,2,29,27,250,22,150,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,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, +23,196,1,23,197,1,23,195,1,27,250,22,132,16,28,249,22,169,9,23,199, +2,2,27,86,94,23,197,1,23,198,1,28,248,22,137,16,23,198,2,249,22, +132,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,150,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,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,165,20,23,197,2,249, -22,4,22,64,248,22,166,20,23,198,2,11,11,11,10,12,250,22,182,11,2, +22,64,248,22,81,23,197,2,10,248,22,167,9,248,22,168,20,23,197,2,249, +22,4,22,64,248,22,169,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,129,17, +22,191,4,11,27,28,23,194,2,250,22,158,2,80,143,44,44,248,22,132,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,175,15,23,197,2,23,196,1,86,94,23,196,1,247,22,153,16, -249,247,22,175,5,248,22,165,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, +5,28,248,22,178,15,23,197,2,23,196,1,86,94,23,196,1,247,22,156,16, +249,247,22,175,5,248,22,168,20,23,197,1,23,201,1,86,94,23,193,1,27, +28,248,22,139,16,23,199,2,23,198,2,27,247,22,177,5,28,192,249,22,140, +16,23,201,2,194,23,199,2,90,144,42,11,89,146,42,39,11,248,22,135,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, +27,248,22,183,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,184,15,249,22,154,8,250,22,153,8,201, +43,11,249,22,7,23,200,2,248,22,187,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,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, +199,2,249,22,132,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,132,16,23,199, 2,23,198,2,86,95,23,200,1,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,158,16,27,247,22,159,16,27,250,22,147,16,23,201,2,11,32,0,88, +247,22,161,16,27,247,22,162,16,27,250,22,150,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, -147,16,23,203,2,11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249, +150,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,86,94,23,197,1, @@ -1183,8 +1185,8 @@ 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,175, -15,23,206,2,23,205,1,86,94,23,205,1,247,22,153,16,249,247,22,163,16, +8,24,42,40,249,22,31,11,80,144,8,26,41,40,22,177,5,28,248,22,178, +15,23,206,2,23,205,1,86,94,23,205,1,247,22,156,16,249,247,22,166,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, @@ -1193,8 +1195,8 @@ 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,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, +27,41,40,22,177,5,28,248,22,178,15,23,207,2,23,206,1,86,94,23,206, +1,247,22,156,16,249,247,22,166,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, @@ -1204,9 +1206,9 @@ 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,175,15,23, -208,2,23,207,1,86,94,23,207,1,247,22,153,16,249,247,22,175,5,248,22, -165,20,23,196,1,23,220,1,86,94,23,193,1,27,28,23,197,1,27,249,22, +42,40,249,22,31,11,80,144,8,28,41,40,22,177,5,28,248,22,178,15,23, +208,2,23,207,1,86,94,23,207,1,247,22,156,16,249,247,22,175,5,248,22, +168,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,97,23, @@ -1216,16 +1218,16 @@ 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,175,15,23,209,2,23,208,1,86,94,23,208,1,247,22,153,16,249,247,22, -175,5,248,22,165,20,23,196,1,23,221,1,86,96,23,216,1,23,215,1,23, -193,1,28,28,248,22,78,23,220,2,248,22,165,20,23,220,2,10,27,28,23, +22,178,15,23,209,2,23,208,1,86,94,23,208,1,247,22,156,16,249,247,22, +175,5,248,22,168,20,23,196,1,23,221,1,86,96,23,216,1,23,215,1,23, +193,1,28,28,248,22,78,23,220,2,248,22,168,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,187,15,23,195,2,11,12,20,13,144, +22,78,23,221,2,248,22,167,9,248,22,190,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,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, +11,80,144,8,30,41,40,22,177,5,28,248,22,178,15,23,210,2,23,209,1, +86,94,23,209,1,247,22,156,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, @@ -1289,21 +1291,21 @@ 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,165,20,23,196,1,90,144,41,11,89,146,41,39,11,27,248,22,166,20,23, -197,2,28,248,22,88,248,22,82,23,195,2,249,22,7,9,248,22,165,20,195, -90,144,41,11,89,146,41,39,11,27,248,22,166,20,196,28,248,22,88,248,22, -82,23,195,2,249,22,7,9,248,22,165,20,195,90,144,41,11,89,146,41,39, -11,248,2,70,248,22,166,20,196,249,22,7,249,22,80,248,22,165,20,199,196, -195,249,22,7,249,22,80,248,22,165,20,199,196,195,249,22,7,249,22,80,248, -22,165,20,23,200,1,23,197,1,23,196,1,27,19,248,22,156,7,23,196,2, +22,168,20,23,196,1,90,144,41,11,89,146,41,39,11,27,248,22,169,20,23, +197,2,28,248,22,88,248,22,82,23,195,2,249,22,7,9,248,22,168,20,195, +90,144,41,11,89,146,41,39,11,27,248,22,169,20,196,28,248,22,88,248,22, +82,23,195,2,249,22,7,9,248,22,168,20,195,90,144,41,11,89,146,41,39, +11,248,2,70,248,22,169,20,196,249,22,7,249,22,80,248,22,168,20,199,196, +195,249,22,7,249,22,80,248,22,168,20,199,196,195,249,22,7,249,22,80,248, +22,168,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,165,20,23,196,1,27,248,22,166,20, +22,82,23,195,2,249,22,7,9,248,22,168,20,23,196,1,27,248,22,169,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,165,20,23,198,1,27,248,22,166,20,23,197,2,90, +2,249,22,7,9,248,22,168,20,23,198,1,27,248,22,169,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,165,20,197,90,144,41,11,89,146,41,39,11,248,2,70,248,22,166, -20,198,249,22,7,249,22,80,248,22,165,20,201,196,195,249,22,7,249,22,80, -248,22,165,20,23,203,1,196,195,249,22,7,249,22,80,248,22,165,20,23,201, +9,248,22,168,20,197,90,144,41,11,89,146,41,39,11,248,2,70,248,22,169, +20,198,249,22,7,249,22,80,248,22,168,20,201,196,195,249,22,7,249,22,80, +248,22,168,20,23,203,1,196,195,249,22,7,249,22,80,248,22,168,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, @@ -1312,13 +1314,13 @@ 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,165,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, +248,22,78,23,195,2,248,22,168,20,23,195,1,23,194,1,28,248,22,178,15, +23,194,2,90,144,42,11,89,146,42,39,11,248,22,135,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,86, 94,23,195,1,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,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, +23,193,2,192,86,94,23,193,1,247,22,156,16,90,144,42,11,89,146,42,39, +11,248,22,135,16,23,198,2,86,95,23,195,1,23,193,1,28,249,22,171,16, +0,11,35,114,120,34,91,46,93,115,115,36,34,248,22,183,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,182,11,2,22,6,21,21,114,101,115,111,108,118,101,100,45,109,111,100,117, @@ -1326,14 +1328,14 @@ 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,129,17,247,22,145,14,11,27,28,23,194,2,23,194,1,86,94,23,194, +248,22,132,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,129,17,247,22,145,14,195,192,86,94,250,22,156,2,248,22, +46,44,41,248,22,132,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,129,17, +5,23,201,1,23,198,1,27,250,22,158,2,80,144,47,44,41,248,22,132,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,166,20,23,200,1,23,198,1,23, +2,11,28,23,193,2,250,22,156,2,248,22,169,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, @@ -1346,14 +1348,14 @@ 2,86,95,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,175,15,23,200,2,23,199,1, +171,9,23,201,2,2,36,23,199,1,28,248,22,178,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,166,20,200,251,2,82,196,197,249,22,80, -248,22,165,20,202,200,248,22,166,20,200,251,2,82,196,197,9,197,27,250,22, +2,82,196,197,248,22,82,199,248,22,169,20,200,251,2,82,196,197,249,22,80, +248,22,168,20,202,200,248,22,169,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,179,16,0,7,35,114,120,34,92,110,34,23,203,1,249,22,137,8,6, +250,22,182,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,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, @@ -1366,9 +1368,9 @@ 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,179,15,248,22,103,23,198,2,248,2,90,248,22,166, +4,10,32,32,32,248,22,182,15,248,22,103,23,198,2,248,2,90,248,22,169, 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,165,20,23,200,1,23,196,1,251,22,178,11,2,22,6,41,41, +169,9,248,22,168,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, @@ -1377,11 +1379,11 @@ 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,165,20,23,209,2,2,32,11, +28,248,22,78,23,207,2,249,22,169,9,248,22,168,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,179,15,23,202,1,28,23,204,2,28, -250,22,158,2,248,22,165,20,23,202,1,23,202,1,11,249,22,80,11,205,249, +176,5,23,201,1,27,248,22,68,248,22,182,15,23,202,1,28,23,204,2,28, +250,22,158,2,248,22,168,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,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, @@ -1390,46 +1392,46 @@ 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,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,165,20,23,198,2,2,5,11,86,97,23,198,1,23, +2,249,22,169,9,248,22,168,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,165,20,23,198,2,2,34,28,248, +22,78,23,196,2,28,249,22,169,9,248,22,168,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,165,20,23,198,2,2,34,28,28,249,22,171,9, +2,28,249,22,169,9,248,22,168,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,165,20,194,11,11,11,11,11,86,96,23,198,1,23, +78,193,248,22,64,248,22,168,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,165,20,23,197,2,23,196,2,27,28,249,22,171, -9,248,22,102,23,203,2,2,35,248,22,166,20,200,248,22,104,200,28,248,22, -78,23,198,2,249,22,94,248,22,166,20,199,194,192,28,28,248,22,78,23,196, -2,249,22,169,9,248,22,165,20,23,198,2,2,38,11,86,94,248,80,144,41, +248,22,78,23,197,2,248,22,168,20,23,197,2,23,196,2,27,28,249,22,171, +9,248,22,102,23,203,2,2,35,248,22,169,20,200,248,22,104,200,28,248,22, +78,23,198,2,249,22,94,248,22,169,20,199,194,192,28,28,248,22,78,23,196, +2,249,22,169,9,248,22,168,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, -165,20,23,198,2,2,34,28,248,22,78,248,22,102,23,197,2,249,22,169,9, +168,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,165,20,23,200,2,27,248,22,102,23,199,2, +28,249,22,169,9,2,34,248,22,168,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,165,20,193,192,250,22,178,11,2,22,6,45,45,110,111,32,98,97, +193,248,22,168,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,165,20,23,201,2,27,28,28,28,249,22,171,9,248,22,102,23, +2,34,248,22,168,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,166,20,23,202,1,248,22,104,23,202,1,28,248,22,78,23,195,2, -249,2,81,248,22,165,20,23,197,2,249,22,94,248,22,166,20,23,199,1,23, +35,248,22,169,20,23,202,1,248,22,104,23,202,1,28,248,22,78,23,195,2, +249,2,81,248,22,168,20,23,197,2,249,22,94,248,22,169,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,166,20,23,202,1,248,22,104,23,202,1, -28,248,22,78,193,248,22,166,20,193,11,86,94,23,198,1,11,86,94,23,198, +248,22,102,23,204,2,2,35,248,22,169,20,23,202,1,248,22,104,23,202,1, +28,248,22,78,193,248,22,169,20,193,11,86,94,23,198,1,11,86,94,23,198, 1,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, +199,2,248,22,132,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,200,2,23,200,1,86,94,23, @@ -1438,45 +1440,45 @@ 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,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, +194,2,86,94,23,193,1,249,22,132,16,23,198,1,248,2,86,23,197,1,250, +22,1,22,132,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, -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, +178,15,23,196,2,86,94,23,196,1,248,80,144,45,8,30,42,248,22,142,16, +28,248,22,139,16,23,198,2,23,197,2,249,22,140,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,129,17,247,22,145,14,28, +248,80,144,46,51,42,249,22,80,23,199,2,248,22,132,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,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,172, +28,248,22,88,23,195,2,249,22,175,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,175, 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,166,20,23,199,1, -23,199,1,10,86,94,23,196,1,28,249,22,169,9,248,22,165,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, +144,55,8,23,42,23,207,1,248,22,81,23,199,2,248,22,169,20,23,199,1, +23,199,1,10,86,94,23,196,1,28,249,22,169,9,248,22,168,20,23,198,2, +2,37,248,80,144,45,8,30,42,248,22,142,16,249,22,140,16,248,22,144,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, +248,22,178,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,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,139,16,248, -22,140,16,23,197,2,11,27,28,248,22,184,8,23,196,2,249,22,189,8,23, +28,248,22,184,8,23,195,2,249,22,189,8,23,196,2,39,249,22,142,16,248, +22,143,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,132,16,23,198,2,86,95,23,195,1,23,193,1,27,28,248, +41,2,41,248,22,135,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,129,17, +248,22,152,5,23,200,2,27,250,22,158,2,80,144,55,44,41,248,22,132,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,129,17,247,22,145,14,195,192,27,28,23,204,2,248,22,152,5,249,22,80, +22,132,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,129,17,247,22,145,14,86,94,249, +41,80,144,59,54,41,247,22,17,27,248,22,132,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, @@ -1484,9 +1486,9 @@ 23,197,1,23,207,1,23,214,1,86,96,23,211,1,23,204,1,23,194,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,165,20,23,208,2,2,32,11,11,249,80,144,56,52, +2,249,22,169,9,248,22,168,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,129,17,247,22, +42,23,215,1,86,94,23,212,1,249,22,80,23,209,1,248,22,132,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, @@ -1548,7 +1550,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 9765); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,48,46,52,84,0,0,0,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,48,46,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,199,1,0,0,3,1,5,105,110,115,112,48, From 69b8b2be356f260392d8289a55af0398a512c0e7 Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Fri, 20 Nov 2015 10:34:19 -0500 Subject: [PATCH 072/369] Fix up prim count from merge mistake --- racket/src/racket/src/schminc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/src/racket/src/schminc.h b/racket/src/racket/src/schminc.h index 5c5853a607..ff4ac468f9 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 1138 +#define EXPECTED_PRIM_COUNT 1139 #define EXPECTED_UNSAFE_COUNT 106 #define EXPECTED_FLFXNUM_COUNT 69 #define EXPECTED_EXTFL_COUNT 45 From 8e46e46d40049409b944add2245d3307bc4e0fe4 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 20 Nov 2015 09:27:05 -0700 Subject: [PATCH 073/369] add more support for continuation marks in procedure impersonators Allow a more dynamic (than `impersonator-prop:application-mark`) determination of continuation marks and associated values to wrap the call of an impersonated procedure. --- .../scribblings/reference/chaperones.scrbl | 37 +++-- .../tests/racket/chaperone.rktl | 137 ++++++++++++++- racket/collects/racket/private/kw.rkt | 19 ++- racket/src/racket/src/fun.c | 156 ++++++++++++++---- racket/src/racket/src/schpriv.h | 3 + racket/src/racket/src/thread.c | 16 +- 6 files changed, 311 insertions(+), 57 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/chaperones.scrbl b/pkgs/racket-doc/scribblings/reference/chaperones.scrbl index 747835735c..cf5ae09818 100644 --- a/pkgs/racket-doc/scribblings/reference/chaperones.scrbl +++ b/pkgs/racket-doc/scribblings/reference/chaperones.scrbl @@ -191,18 +191,31 @@ required keyword arguments of @racket[wrapper-proc] must be a subset of the required keywords of @racket[proc]. For applications without keywords, the result of @racket[wrapper-proc] -must be either the same number of values as supplied to it or one more -than the number of supplied values, where an extra result is supplied -before the others. The additional result, if any, must be a procedure +must be at least the same number of values as supplied to it. +Additional results can be supplied---before the values that correspond +to the supplied values---in the following pattern: + +@itemlist[ + + @item{An optional procedure, @racket[_result-wrapper-proc], which + will be applied to the results of @racket[proc]; followed by} + + @item{any number of repetitions of @racket['mark _key _val] (i.e., + three values), where the call @racket[_proc] is wrapped to + install a @tech{continuation mark} @racket[_key] and @racket[_val].} + +] + +If @racket[_result-wrapper-proc] is produced, it must be a procedure that accepts as many results as produced by @racket[proc]; it must -return the same number of results. If @racket[wrapper-proc] returns -the same number of values as it is given (i.e., it does not return a -procedure to impersonator @racket[proc]'s result), then @racket[proc] is -called in @tech{tail position} with respect to the call to the impersonator. +return the same number of results. If @racket[_result-wrapper-proc] is +not supplied, then @racket[proc] is called in @tech{tail position} +with respect to the call to the impersonator. For applications that include keyword arguments, @racket[wrapper-proc] -must return an additional value before any other values but after the -result-impersonating procedure (if any). The additional value must be a +must return an additional value before any other values but after +@racket[_result-wrapper-proc] and @racket['mark _key _val] +sequences (if any). The additional value must be a list of replacements for the keyword arguments that were supplied to the impersonator (i.e., not counting optional arguments that were not supplied). The arguments must be ordered according to the sorted @@ -229,7 +242,11 @@ 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 -@racket[wrapper-proc]).} +@racket[wrapper-proc]). + +@history[#:changed "6.3.0.5" @elem{Added support for @racket['mark + _key _val] results from + @racket[wrapper-proc].}]} @defproc[(impersonate-procedure* [proc procedure?] [wrapper-proc (or/c procedure? #f)] diff --git a/pkgs/racket-test-core/tests/racket/chaperone.rktl b/pkgs/racket-test-core/tests/racket/chaperone.rktl index 482e62d849..ddee10417e 100644 --- a/pkgs/racket-test-core/tests/racket/chaperone.rktl +++ b/pkgs/racket-test-core/tests/racket/chaperone.rktl @@ -348,6 +348,28 @@ (test (vector 1110 1111) values in) (check-proc-prop f mk))) +;; Single argument, no post filter, set continuation mark: +(as-chaperone-or-impersonator + ([chaperone-procedure impersonate-procedure + chaperone-procedure** + impersonate-procedure**]) + (let* ([f (lambda (x) (list x (continuation-mark-set-first #f 'the-mark)))] + [in #f] + [mk (lambda (f) + (chaperone-procedure + f + (lambda (x) + (set! in x) + (values 'mark 'the-mark 8 x))))] + [f2 (mk f)]) + (with-continuation-mark 'the-mark + 7 + (test '(110 7) f 110)) + (test #f values in) + (test '(111 8) f2 111) + (test 111 values in) + (check-proc-prop f mk))) + ;; Single argument, post filter on single value: (as-chaperone-or-impersonator ([chaperone-procedure impersonate-procedure @@ -400,6 +422,42 @@ (test (vector 'b '(a c)) values out) (check-proc-prop f mk))) +;; Multiple arguments, post filter on multiple values +;; and set multiple continuation marks: +(as-chaperone-or-impersonator + ([chaperone-procedure impersonate-procedure + chaperone-procedure** + impersonate-procedure**]) + (let* ([f (lambda (x y z) (values y (list x z + (continuation-mark-set-first #f 'the-mark) + (continuation-mark-set-first #f 'the-other-mark))))] + [in #f] + [out #f] + [mk (lambda (f) + (chaperone-procedure + f + (lambda (x y z) + (set! in (vector x y z)) + (values (lambda (y z) + (set! out (vector y z)) + (values y z)) + 'mark 'the-mark 88 + 'mark 'the-other-mark 86 + x y z))))] + [f2 (mk f)]) + (with-continuation-mark 'the-mark + 77 + (with-continuation-mark 'the-other-mark + 79 + (begin + (test-values '(b (a c 77 79)) (lambda () (f 'a 'b 'c))) + (test #f values in) + (test #f values out) + (test-values '(b (a c 88 86)) (lambda () (f2 'a 'b 'c))) + (test (vector 'a 'b 'c) values in) + (test (vector 'b '(a c 88 86)) values out) + (check-proc-prop f mk)))))) + ;; Optional keyword arguments: (as-chaperone-or-impersonator ([chaperone-procedure impersonate-procedure @@ -432,6 +490,43 @@ (test-values '(() (#:a #:b)) (lambda () (procedure-keywords f2))) (check-proc-prop f mk))) +;; Optional keyword arguments with mark: +(as-chaperone-or-impersonator + ([chaperone-procedure impersonate-procedure + chaperone-procedure**/kw + impersonate-procedure**/kw]) + (let* ([f (lambda (x #:a [a 'a] #:b [b 'b]) (list x a b (continuation-mark-set-first #f 'the-mark)))] + [in #f] + [mk (lambda (f) + (chaperone-procedure + f + (lambda (x #:a [a 'nope] #:b [b 'nope]) + (if (and (eq? a 'nope) (eq? b 'nope)) + (values 'mark 'the-mark 8 + x) + (values + 'mark 'the-mark 8 + (append + (if (eq? a 'nope) null (list a)) + (if (eq? b 'nope) null (list b))) + x)))))] + [f2 (mk f)]) + (with-continuation-mark 'the-mark + 7 + (begin + (test '(1 a b 7) f 1) + (test '(1 a b 8) f2 1) + (test '(1 2 b 7) f 1 #:a 2) + (test '(1 2 b 8) f2 1 #:a 2) + (test '(1 a 3 7) f 1 #:b 3) + (test '(1 a 3 8) f2 1 #:b 3) + (test '(1 2 3 7) f 1 #:a 2 #:b 3) + (test '(1 2 3 8) f2 1 #:a 2 #:b 3) + (test 1 procedure-arity f2) + (test 'f object-name f2) + (test-values '(() (#:a #:b)) (lambda () (procedure-keywords f2))) + (check-proc-prop f mk))))) + ;; Optional keyword arguments with result chaperone: (as-chaperone-or-impersonator ([chaperone-procedure impersonate-procedure @@ -502,7 +597,7 @@ (test-values '((#:b) (#:a #:b)) (lambda () (procedure-keywords f2))) (check-proc-prop f mk))) -;; Required keyword arguments: +;; Required keyword arguments with result chaperone: (as-chaperone-or-impersonator ([chaperone-procedure impersonate-procedure chaperone-procedure**/kw @@ -538,6 +633,46 @@ (test-values '((#:b) (#:a #:b)) (lambda () (procedure-keywords f2))) (check-proc-prop f mk))) +;; Required keyword arguments with result chaperone and marks: +(as-chaperone-or-impersonator + ([chaperone-procedure impersonate-procedure + chaperone-procedure**/kw + impersonate-procedure**/kw]) + (let* ([f (lambda (x #:a [a 'a] #:b b) (list x a b (continuation-mark-set-first #f 'the-mark)))] + [in #f] + [out #f] + [mk (lambda (f) + (chaperone-procedure + f + (lambda (x #:a [a 'nope] #:b [b 'nope]) + (set! in (list x a b)) + (if (and (eq? a 'nope) (eq? b 'nope)) + x + (values + (lambda (z) (set! out z) z) + 'mark 'the-mark 9 + (append + (if (eq? a 'nope) null (list a)) + (if (eq? b 'nope) null (list b))) + x)))))] + [f2 (mk f)]) + (with-continuation-mark 'the-mark + 7 + (begin + (err/rt-test (f 1)) + (err/rt-test (f2 1)) + (err/rt-test (f 1 #:a 2)) + (err/rt-test (f2 1 #:a 2)) + (test '(1 a 3 7) f 1 #:b 3) + (test '(1 a 3 9) f2 1 #:b 3) + (test '((1 nope 3) (1 a 3 9)) list in out) + (test '(1 2 3 7) f 1 #:a 2 #:b 3) + (test '(1 2 3 9) f2 1 #:a 2 #:b 3) + (test 1 procedure-arity f2) + (test 'f object-name f2) + (test-values '((#:b) (#:a #:b)) (lambda () (procedure-keywords f2))) + (check-proc-prop f mk))))) + (err/rt-test ((chaperone-procedure (lambda (x) x) (lambda (y) (values y y))) 1)) (err/rt-test ((impersonate-procedure (lambda (x) x) (lambda (y) (values y y))) 1)) (err/rt-test ((chaperone-procedure (lambda (x) x) (lambda (y) (values y y y))) 1)) diff --git a/racket/collects/racket/private/kw.rkt b/racket/collects/racket/private/kw.rkt index 98a85577f3..14eef699e8 100644 --- a/racket/collects/racket/private/kw.rkt +++ b/racket/collects/racket/private/kw.rkt @@ -1611,16 +1611,15 @@ (lambda results (let* ([len (length results)] [alen (length rest)]) - (unless (<= (+ alen 1) len (+ alen 2)) + (when (< len (+ alen 1)) (raise-arguments-error '|keyword procedure chaperone| "wrong number of results from wrapper procedure" "expected minimum number of results" (+ alen 1) - "expected maximum number of results" (+ alen 2) "received number of results" len "wrapper procedure" wrap-proc)) - (let ([extra? (= len (+ alen 2))]) - (let ([new-args ((if extra? cadr car) results)]) + (let ([num-extra (- len (+ alen 1))]) + (let ([new-args (list-ref results num-extra)]) (unless (and (list? new-args) (= (length new-args) (length args))) (raise-arguments-error @@ -1629,7 +1628,7 @@ "expected a list of keyword-argument values as first result~a from wrapper procedure" (if (= len alen) "" - " (after the result-wrapper procedure)")) + " (after the result-wrapper procedure or mark specifications)")) "first result" new-args "wrapper procedure" wrap-proc)) (for-each @@ -1646,9 +1645,13 @@ kws new-args args)) - (if extra? - (apply values (car results) kws (cdr results)) - (apply values kws results))))))] + (case num-extra + [(0) (apply values kws results)] + [(1) (apply values (car results) kws (cdr results))] + [else (apply values (let loop ([results results] [c num-extra]) + (if (zero? c) + (cons kws results) + (cons (car results) (loop (cdr results) (sub1 c))))))])))))] ;; The following case exists only to make sure that the arity of ;; any procedure passed to `make-keyword-args' is covered ;; by this procedure's arity. diff --git a/racket/src/racket/src/fun.c b/racket/src/racket/src/fun.c index 540d03fb97..4e88cca8ac 100644 --- a/racket/src/racket/src/fun.c +++ b/racket/src/racket/src/fun.c @@ -104,6 +104,7 @@ ROSYM static Scheme_Object *is_method_symbol; ROSYM static Scheme_Object *cont_key; /* uninterned */ ROSYM static Scheme_Object *barrier_prompt_key; /* uninterned */ ROSYM static Scheme_Object *prompt_cc_guard_key; /* uninterned */ +ROSYM static Scheme_Object *mark_symbol; READ_ONLY static Scheme_Prompt *original_default_prompt; /* for escapes, represents the implicit initial prompt */ READ_ONLY static Scheme_Object *call_with_prompt_proc; READ_ONLY static Scheme_Object *abort_continuation_proc; @@ -676,6 +677,9 @@ scheme_init_fun (Scheme_Env *env) barrier_prompt_key = scheme_make_symbol("bar"); /* uninterned */ prompt_cc_guard_key = scheme_make_symbol("cc"); /* uninterned */ + REGISTER_SO(mark_symbol); + mark_symbol = scheme_intern_symbol("mark"); + REGISTER_SO(scheme_default_prompt_tag); { Scheme_Object *a[1]; @@ -3591,6 +3595,104 @@ Scheme_Object *_scheme_apply_native(Scheme_Object *obj, int num_rands, Scheme_Ob return _apply_native(obj, num_rands, rands); } +Scheme_Object *extract_impersonator_results(int c, int argc, Scheme_Object **argv2, + const char *what, Scheme_Object *o, + Scheme_Chaperone *px, + Scheme_Cont_Frame_Data *cframe, int *_need_pop) +{ + int extra = c - argc; + int i, fail_reason = 0; + Scheme_Object *post; + char nth[32]; + Scheme_Config *config = NULL; + + if (!extra) + return NULL; + + post = NULL; + for (i = 0; i < extra; ) { + if (!i && SCHEME_PROCP(argv2[0])) { + post = argv2[i]; + i++; + } else if (SAME_OBJ(argv2[i], mark_symbol)) { + if (i + 3 > extra) { + fail_reason = 2; + break; + } + if (post && !*_need_pop) { + scheme_push_continuation_frame(cframe); + *_need_pop = 1; + } + scheme_set_cont_mark(argv2[i+1], argv2[i+2]); + i += 3; + } else { + fail_reason = 1; + break; + } + } + + if (!fail_reason) { + if (config) { + if (post && !*_need_pop) { + scheme_push_continuation_frame(cframe); + *_need_pop = 1; + } + scheme_set_cont_mark(scheme_parameterization_key, (Scheme_Object *)config); + } + return post; + } + + /* Failure at argument i */ + + switch (i % 10) { + case 1: + sprintf(nth, "%dst", i); + break; + case 2: + sprintf(nth, "%dnd", i); + break; + case 3: + sprintf(nth, "%drd", i); + break; + default: + sprintf(nth, "%dth", i); + } + + if (fail_reason == 1) { + scheme_raise_exn(MZEXN_FAIL_CONTRACT, + "procedure %s: wrapper's %s result is not valid;\n" + " %s extra result (before original argument count) should be\n" + " 'mark%s'parameter%s\n" + " original: %V\n" + " wrapper: %V\n" + " received: %V", + what, + nth, + nth, + (i ? " or " : ", "), + (i ? "" : ", or a wrapper for the original procedure's result"), + o, + SCHEME_VEC_ELS(px->redirects)[0], + argv2[i]); + } else if (fail_reason == 2) { + scheme_raise_exn(MZEXN_FAIL_CONTRACT, + "procedure %s: wrapper's %s result needs addition extra results;\n" + " %s extra result (before original argument count) needs an\n" + " additional %s after %V\n" + " original: %V\n" + " wrapper: %V", + what, + nth, + nth, + ((i + 1 < extra) ? "result" : "two results"), + argv2[i], + o, + SCHEME_VEC_ELS(px->redirects)[0]); + } + + return NULL; +} + /* must be at least 3: */ #define MAX_QUICK_CHAP_ARGV 5 @@ -3736,13 +3838,16 @@ Scheme_Object *scheme_apply_chaperone(Scheme_Object *o, int argc, Scheme_Object MZ_CONT_MARK_POS += 2; scheme_pop_continuation_frame(&cframe); } - - if ((c == argc) || (c == (argc + 1))) { - if (c > argc) { - post = argv2[0]; - memmove(argv2, argv2 + 1, sizeof(Scheme_Object*)*argc); - } else - post = NULL; + + if (c >= argc) { + int need_pop = 0; + post = extract_impersonator_results(c, argc, argv2, + what, o, px, + &cframe, &need_pop); + need_pop_mark = need_pop; + + if (c > argc) + memmove(argv2, argv2 + (c - argc), sizeof(Scheme_Object*)*argc); if (!(SCHEME_CHAPERONE_FLAGS(px) & SCHEME_CHAPERONE_IS_IMPERSONATOR)) { for (i = 0; i < argc; i++) { if (!SAME_OBJ(argv2[i], argv[i]) @@ -3764,12 +3869,12 @@ Scheme_Object *scheme_apply_chaperone(Scheme_Object *o, int argc, Scheme_Object " procedure's arguments\n" " original: %V\n" " wrapper: %V\n" - " expected: %d or %d\n" + " expected: %d or more\n" " received: %d", what, o, SCHEME_VEC_ELS(px->redirects)[0], - argc, argc + 1, + argc, c); return NULL; } @@ -3784,7 +3889,7 @@ Scheme_Object *scheme_apply_chaperone(Scheme_Object *o, int argc, Scheme_Object } else argv = NULL; - if (c == argc) { + if (!post) { /* No filter for the result, so tail call: */ if (app_mark) scheme_set_cont_mark(SCHEME_CAR(app_mark), SCHEME_CDR(app_mark)); @@ -3794,7 +3899,7 @@ Scheme_Object *scheme_apply_chaperone(Scheme_Object *o, int argc, Scheme_Object } if (auto_val) { if (SCHEME_CHAPERONEP(px->prev)) - return do_apply_chaperone(px->prev, c, argv2, auto_val, 0); + return do_apply_chaperone(px->prev, argc, argv2, auto_val, 0); else return argv2[0]; } else { @@ -3807,40 +3912,29 @@ Scheme_Object *scheme_apply_chaperone(Scheme_Object *o, int argc, Scheme_Object /* cannot return a tail call */ MZ_CONT_MARK_POS -= 2; if (checks & 0x1) { - v = _scheme_apply(orig_obj, c, argv2); + v = _scheme_apply(orig_obj, argc, argv2); } else if (SAME_TYPE(SCHEME_TYPE(orig_obj), scheme_native_closure_type)) { - v = _apply_native(orig_obj, c, argv2); + v = _apply_native(orig_obj, argc, argv2); } else { - v = _scheme_apply_multi(orig_obj, c, argv2); + v = _scheme_apply_multi(orig_obj, argc, argv2); } MZ_CONT_MARK_POS += 2; return v; } else - return scheme_tail_apply(orig_obj, c, argv2); + return scheme_tail_apply(orig_obj, argc, argv2); } } else { - /* First element is a filter for the result(s) */ - if (!SCHEME_PROCP(post)) - scheme_raise_exn(MZEXN_FAIL_CONTRACT, - "procedure %s: wrapper's first result is not a procedure;\n" - " extra result compared to original argument count should be\n" - " a wrapper for the original procedure's result\n" - " original: %V\n" - " wrapper: %V\n" - " received: %V", - what, - o, - SCHEME_VEC_ELS(px->redirects)[0], - post); - if (app_mark) { - scheme_push_continuation_frame(&cframe); + if (!need_pop_mark) + scheme_push_continuation_frame(&cframe); scheme_set_cont_mark(SCHEME_CAR(app_mark), SCHEME_CDR(app_mark)); - MZ_CONT_MARK_POS -= 2; need_pop_mark = 1; }else need_pop_mark = 0; + if (need_pop_mark) + MZ_CONT_MARK_POS -= 2; + if (SCHEME_CHAPERONEP(px->prev)) { /* commuincate `self_proc` to the next layer: */ scheme_current_thread->self_for_proc_chaperone = self_proc; diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 867a918645..3f7c44a964 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -831,6 +831,9 @@ extern Scheme_Object *scheme_parameterization_key; extern Scheme_Object *scheme_exn_handler_key; extern Scheme_Object *scheme_break_enabled_key; +Scheme_Object *scheme_extend_parameterization(int argc, Scheme_Object *args[]); +XFORM_NONGCING int scheme_is_parameter(Scheme_Object *o); + extern void scheme_flatten_config(Scheme_Config *c); extern Scheme_Object *scheme_apply_thread_thunk(Scheme_Object *rator); diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index 3fedeaea0c..80c0c8b4c6 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -391,7 +391,6 @@ static Scheme_Object *parameter_p(int argc, Scheme_Object *args[]); static Scheme_Object *parameter_procedure_eq(int argc, Scheme_Object *args[]); static Scheme_Object *make_parameter(int argc, Scheme_Object *args[]); static Scheme_Object *make_derived_parameter(int argc, Scheme_Object *args[]); -static Scheme_Object *extend_parameterization(int argc, Scheme_Object *args[]); static Scheme_Object *parameterization_p(int argc, Scheme_Object *args[]); static Scheme_Object *reparameterize(int argc, Scheme_Object **argv); @@ -708,7 +707,7 @@ void scheme_init_paramz(Scheme_Env *env) scheme_add_global_constant("parameterization-key" , scheme_parameterization_key, newenv); scheme_add_global_constant("break-enabled-key" , scheme_break_enabled_key , newenv); - GLOBAL_PRIM_W_ARITY("extend-parameterization" , extend_parameterization , 1, -1, newenv); + GLOBAL_PRIM_W_ARITY("extend-parameterization" , scheme_extend_parameterization , 1, -1, newenv); GLOBAL_PRIM_W_ARITY("check-for-break" , check_break_now , 0, 0, newenv); GLOBAL_PRIM_W_ARITY("reparameterize" , reparameterize , 1, 1, newenv); GLOBAL_PRIM_W_ARITY("make-custodian-from-main", make_custodian_from_main, 0, 0, newenv); @@ -7633,7 +7632,7 @@ static Scheme_Object *parameterization_p(int argc, Scheme_Object **argv) && ((((Scheme_Primitive_Proc *)v)->pp.flags & SCHEME_PRIM_OTHER_TYPE_MASK) \ == SCHEME_PRIM_TYPE_PARAMETER)) -static Scheme_Object *extend_parameterization(int argc, Scheme_Object *argv[]) +Scheme_Object *scheme_extend_parameterization(int argc, Scheme_Object *argv[]) { Scheme_Object *key, *a[2], *param; Scheme_Config *c; @@ -7719,13 +7718,16 @@ static Scheme_Object *reparameterize(int argc, Scheme_Object **argv) return (Scheme_Object *)naya; } -static Scheme_Object *parameter_p(int argc, Scheme_Object **argv) +int scheme_is_parameter(Scheme_Object *v) { - Scheme_Object *v = argv[0]; - if (SCHEME_CHAPERONEP(v)) v = SCHEME_CHAPERONE_VAL(v); - return (SCHEME_PARAMETERP(v) + return SCHEME_PARAMETERP(v); +} + +static Scheme_Object *parameter_p(int argc, Scheme_Object **argv) +{ + return (scheme_is_parameter(argv[0]) ? scheme_true : scheme_false); } From aff167b13dc36828c44995f0c4255982a85e556e Mon Sep 17 00:00:00 2001 From: Chris Jester-Young Date: Fri, 20 Nov 2015 18:38:47 -0500 Subject: [PATCH 074/369] Fix parsing of 0e401 on USE_EXPLICT_FP_FORM_CHECK platforms. --- pkgs/racket-test-core/tests/racket/number.rktl | 2 ++ racket/src/racket/src/numstr.c | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/number.rktl b/pkgs/racket-test-core/tests/racket/number.rktl index 968562d2fd..32c0d83385 100644 --- a/pkgs/racket-test-core/tests/racket/number.rktl +++ b/pkgs/racket-test-core/tests/racket/number.rktl @@ -2727,6 +2727,8 @@ (test (- (sub1 (expt 2 256))) string->number "-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 16) (test #f string->number "144r" 10) (err/rt-test (string->number "10" 30)) +(test 0.0 string->number "0e401") +(test 0.0 string->number "00000.00000e9999999999") (define (q-test quotient) (test 0 quotient 0 12345678909876532341) diff --git a/racket/src/racket/src/numstr.c b/racket/src/racket/src/numstr.c index 0f4fb210ac..e3e8ebc863 100644 --- a/racket/src/racket/src/numstr.c +++ b/racket/src/racket/src/numstr.c @@ -386,7 +386,7 @@ END_XFORM_ARITH; static double STRTOD(const char *orig_c, char **f, int extfl) { int neg = 0; - int found_dot = 0, is_infinity = 0, is_zero = 0; + int found_dot = 0, is_infinity = 0, is_zero = 0, is_nonzero = 0; const char *c = orig_c; *f = (char *)c; @@ -410,7 +410,8 @@ static double STRTOD(const char *orig_c, char **f, int extfl) int ch = *c; if (isdigit(ch)) { - /* ok */ + if (ch != '0') + is_nonzero = 1; } else if ((ch == 'e') || (ch == 'E')) { int e = 0, neg_exp = 0; @@ -431,7 +432,7 @@ static double STRTOD(const char *orig_c, char **f, int extfl) else { e = (e * 10) + (ch - '0'); if (e > CHECK_INF_EXP_THRESHOLD(extfl)) { - if (neg_exp) + if (neg_exp || !is_nonzero) is_zero = 1; else is_infinity = 1; From 9d2dd0168958b2da462541a06b2e868e7265c41b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 21 Nov 2015 09:15:25 -0700 Subject: [PATCH 075/369] more repairs of parsing inexact with large exponents Fix the slow-path parsing of numbers in essentially the same way as aff167b13d. Closes #1140 --- .../racket-test-core/tests/racket/number.rktl | 23 +++++++++ racket/src/racket/src/numstr.c | 47 ++++++++++++++----- 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/number.rktl b/pkgs/racket-test-core/tests/racket/number.rktl index 32c0d83385..ffd6bfb059 100644 --- a/pkgs/racket-test-core/tests/racket/number.rktl +++ b/pkgs/racket-test-core/tests/racket/number.rktl @@ -2404,6 +2404,29 @@ (err/rt-test (string->number "1" "1")) (err/rt-test (string->number 1 1)) +;; Test inexacts with large exponents +(test 0.0 string->number "0e401") +(test 0.0 string->number "0e6001") +(test -0.0 string->number "-0e401") +(test -0.0 string->number "-0e6001") +(test +inf.0 string->number "0.1e401") +(test +inf.0 string->number "0.1e6001") +(test -inf.0 string->number "-0.1e401") +(test -inf.0 string->number "-0.1e6001") +(test 0.0 string->number (string-append "0." (make-string 400 #\0) "0e400")) +(test 0.0 string->number (string-append "0." (make-string 8000 #\0) "0e8000")) +(test -0.0 string->number (string-append "-0." (make-string 400 #\0) "0e400")) +(test -0.0 string->number (string-append "-0." (make-string 8000 #\0) "0e8000")) +(test 0.1 string->number (string-append "0." (make-string 400 #\0) "1e400")) +(test 0.1 string->number (string-append "0." (make-string 8000 #\0) "1e8000")) +(test 1.0e-101 string->number (string-append "0." (make-string 8000 #\0) "1e7900")) +(test +inf.0 string->number (string-append "0." (make-string 400 #\0) "1e1000")) +(test -inf.0 string->number (string-append "-0." (make-string 400 #\0) "1e1000")) +(test +inf.0 string->number (string-append "0." (make-string 8000 #\0) "1e8400")) +(test -inf.0 string->number (string-append "-0." (make-string 8000 #\0) "1e8400")) +(test #f string->number (string-append "-0." (make-string 8000 #\0) "9e10000") 8) +(test #f string->number (string-append "0." (make-string 8000 #\0) "e1008") 8) + (test #t andmap (lambda (x) (and (>= x 0) (< x 10))) (map random '(10 10 10 10))) (test (void) random-seed 5) (test (begin (random-seed 23) (list (random 10) (random 20) (random 30))) diff --git a/racket/src/racket/src/numstr.c b/racket/src/racket/src/numstr.c index e3e8ebc863..5995af1c65 100644 --- a/racket/src/racket/src/numstr.c +++ b/racket/src/racket/src/numstr.c @@ -1393,7 +1393,7 @@ Scheme_Object *scheme_read_number(const mzchar *str, intptr_t len, } else { /* Mantissa is not a fraction. */ mzchar *digits; - int extra_power = 0, dcp = 0, num_ok; + int extra_power = 0, dcp = 0, non_zero = 0, num_ok; digits = (mzchar *)scheme_malloc_atomic((has_expt - delta + 1) * sizeof(mzchar)); @@ -1402,7 +1402,11 @@ Scheme_Object *scheme_read_number(const mzchar *str, intptr_t len, digits[dcp++] = str[i++]; for (; isAdigit(str[i]) || ((radix > 10) && isbaseNdigit(radix, str[i])); i++) { + if ((radix < 10) && ((str[i] - '0') >= radix)) + break; digits[dcp++] = str[i]; + if (str[i] != '0') + non_zero = 1; } if (str[i] == '#') { @@ -1412,13 +1416,17 @@ Scheme_Object *scheme_read_number(const mzchar *str, intptr_t len, num_ok = 0; } else num_ok = 1; - + if (str[i] == '.') { i++; if (num_ok) for (; isAdigit(str[i]) || ((radix > 10) && isbaseNdigit(radix, str[i])); i++) { + if ((radix < 10) && ((str[i] - '0') >= radix)) + break; digits[dcp++] = str[i]; extra_power++; + if (str[i] != '0') + non_zero = 1; } for (; str[i] == '#'; i++) { @@ -1445,22 +1453,35 @@ Scheme_Object *scheme_read_number(const mzchar *str, intptr_t len, return scheme_false; } - /* Reduce unnecessary mantissa-reading work for inexact results. - This is also necessary to make the range check on `exponent' - correct. */ - if (result_is_float && (dcp > MAX_FLOATREAD_PRECISION_DIGITS(is_long_double))) { - extra_power -= (dcp - MAX_FLOATREAD_PRECISION_DIGITS(is_long_double)); - dcp = MAX_FLOATREAD_PRECISION_DIGITS(is_long_double); + /* Zero mantissa => zero inexact result */ + if (!non_zero && result_is_float) { + if (dcp && (digits[0] == '-')) + return CHECK_SINGLE(scheme_nzerod, sgl, is_long_double); + else + return CHECK_SINGLE(scheme_zerod, sgl, is_long_double); + } + + /* Reduce unnecessary mantissa-reading work for inexact results. */ + if (result_is_float) { + Scheme_Object *max_useful; + + max_useful = scheme_bin_plus(scheme_make_integer(MAX_FLOATREAD_PRECISION_DIGITS(is_long_double)), + exponent); + if (scheme_bin_lt(max_useful, scheme_make_integer(0))) { + if (dcp > 2) + dcp = 2; /* leave room for a sign and a digit */ + } else if (SCHEME_INTP(max_useful)) { + if (result_is_float && (dcp > SCHEME_INT_VAL(max_useful))) { + extra_power -= (dcp - SCHEME_INT_VAL(max_useful)); + dcp = SCHEME_INT_VAL(max_useful); + } + } } digits[dcp] = 0; mantissa = scheme_read_bignum(digits, 0, radix); if (SCHEME_FALSEP(mantissa)) { - /* can get here with bad radix */ - if (report) - scheme_read_err(complain, stxsrc, line, col, pos, span, 0, indentation, - "read: bad number: %u", - str, len); + scheme_signal_error("internal error parsing mantissa: %s", digits); return scheme_false; } From c40229f7564b5006bc4603cf4995b5ee011aa5bf Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 21 Nov 2015 10:42:42 -0700 Subject: [PATCH 076/369] fix reading of extflonums, including with large exponents Fix even basic readind when extflonums are not supported, but also fix reading extflonums with large exponents (related to the other recent changes to number parsing). --- .../racket-test-core/tests/racket/number.rktl | 11 ++++-- racket/src/racket/src/numstr.c | 36 +++++++++++++------ 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/number.rktl b/pkgs/racket-test-core/tests/racket/number.rktl index ffd6bfb059..00b73fbbf6 100644 --- a/pkgs/racket-test-core/tests/racket/number.rktl +++ b/pkgs/racket-test-core/tests/racket/number.rktl @@ -3,6 +3,8 @@ (Section 'numbers) +(require racket/extflonum) + (test #f number? 'a) (test #f complex? 'a) (test #f real? 'a) @@ -2404,6 +2406,9 @@ (err/rt-test (string->number "1" "1")) (err/rt-test (string->number 1 1)) +(define (string->extfl-number s) + (read (open-input-string s))) + ;; Test inexacts with large exponents (test 0.0 string->number "0e401") (test 0.0 string->number "0e6001") @@ -2415,8 +2420,10 @@ (test -inf.0 string->number "-0.1e6001") (test 0.0 string->number (string-append "0." (make-string 400 #\0) "0e400")) (test 0.0 string->number (string-append "0." (make-string 8000 #\0) "0e8000")) +(test #t extflonum? (string->extfl-number (string-append "0." (make-string 400 #\0) "0t9000"))) (test -0.0 string->number (string-append "-0." (make-string 400 #\0) "0e400")) (test -0.0 string->number (string-append "-0." (make-string 8000 #\0) "0e8000")) +(test #t extflonum? (string->extfl-number (string-append "-0." (make-string 400 #\0) "0t9000"))) (test 0.1 string->number (string-append "0." (make-string 400 #\0) "1e400")) (test 0.1 string->number (string-append "0." (make-string 8000 #\0) "1e8000")) (test 1.0e-101 string->number (string-append "0." (make-string 8000 #\0) "1e7900")) @@ -2424,6 +2431,8 @@ (test -inf.0 string->number (string-append "-0." (make-string 400 #\0) "1e1000")) (test +inf.0 string->number (string-append "0." (make-string 8000 #\0) "1e8400")) (test -inf.0 string->number (string-append "-0." (make-string 8000 #\0) "1e8400")) +(test #t extflonum? (string->extfl-number (string-append "0." (make-string 8000 #\0) "1t8400"))) +(test #t extflonum? (string->extfl-number (string-append "-0." (make-string 8000 #\0) "1t8400"))) (test #f string->number (string-append "-0." (make-string 8000 #\0) "9e10000") 8) (test #f string->number (string-append "0." (make-string 8000 #\0) "e1008") 8) @@ -3190,8 +3199,6 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; exact->inexact precision (thanks to Neil Toronto) -(require racket/extflonum) - (define (check start end exact-> ->exact >=?) (define delta (/ (- end start) 300)) (for/fold ([prev (exact-> start)]) ([i (in-range start (+ end delta) delta)]) diff --git a/racket/src/racket/src/numstr.c b/racket/src/racket/src/numstr.c index 5995af1c65..a3817d101b 100644 --- a/racket/src/racket/src/numstr.c +++ b/racket/src/racket/src/numstr.c @@ -495,13 +495,27 @@ START_XFORM_ARITH; # define STRTOD(x, y, extfl) strtod(x, y) #endif -static Scheme_Object *CHECK_SINGLE(Scheme_Object *v, int s, int long_dbl) +#ifdef MZ_LONG_DOUBLE +# define CHECK_SINGLE(v, s, il, l, str, len, radix) do_CHECK_SINGLE(v, s, il, l, NULL, 0, 0) +#else +# define CHECK_SINGLE(v, s, il, l, str, len, radix) do_CHECK_SINGLE(v, s, il, NULL, str, len, radix) +#endif + +static Scheme_Object *do_CHECK_SINGLE(Scheme_Object *v, int s, int long_dbl, + Scheme_Object *lv, const mzchar *str, intptr_t len, int radix) { if (SCHEME_DBLP(v)) { #ifdef MZ_USE_SINGLE_FLOATS if (s) return scheme_make_float((float)SCHEME_DBL_VAL(v)); #endif + if (long_dbl) { +#ifdef MZ_LONG_DOUBLE + return lv; +#else + return wrap_as_long_double(scheme_utf8_encode_to_buffer(str, len, NULL, 0), radix); +#endif + } } return v; @@ -1456,9 +1470,9 @@ Scheme_Object *scheme_read_number(const mzchar *str, intptr_t len, /* Zero mantissa => zero inexact result */ if (!non_zero && result_is_float) { if (dcp && (digits[0] == '-')) - return CHECK_SINGLE(scheme_nzerod, sgl, is_long_double); + return CHECK_SINGLE(scheme_nzerod, sgl, is_long_double, scheme_nzerol, str, len, radix); else - return CHECK_SINGLE(scheme_zerod, sgl, is_long_double); + return CHECK_SINGLE(scheme_zerod, sgl, is_long_double, scheme_zerol, str, len, radix); } /* Reduce unnecessary mantissa-reading work for inexact results. */ @@ -1492,14 +1506,14 @@ Scheme_Object *scheme_read_number(const mzchar *str, intptr_t len, if (result_is_float) { if (scheme_bin_gt(exponent, scheme_make_integer(CHECK_INF_EXP_THRESHOLD(is_long_double)))) { if (scheme_is_negative(mantissa)) - return CHECK_SINGLE(scheme_minus_inf_object, sgl, is_long_double); + return CHECK_SINGLE(scheme_minus_inf_object, sgl, is_long_double, scheme_long_minus_inf_object, str, len, radix); else - return CHECK_SINGLE(scheme_inf_object, sgl, is_long_double); + return CHECK_SINGLE(scheme_inf_object, sgl, is_long_double, scheme_long_inf_object, str, len, radix); } else if (scheme_bin_lt(exponent, scheme_make_integer(-CHECK_INF_EXP_THRESHOLD(is_long_double)))) { if (scheme_is_negative(mantissa)) - return CHECK_SINGLE(scheme_nzerod, sgl, is_long_double); + return CHECK_SINGLE(scheme_nzerod, sgl, is_long_double, scheme_nzerol, str, len, radix); else - return CHECK_SINGLE(scheme_zerod, sgl, is_long_double); + return CHECK_SINGLE(scheme_zerod, sgl, is_long_double, scheme_zerol, str, len, radix); } } } @@ -1528,7 +1542,7 @@ Scheme_Object *scheme_read_number(const mzchar *str, intptr_t len, n = wrap_as_long_double(scheme_utf8_encode_to_buffer(str, len, NULL, 0), radix); #endif } else { - n = CHECK_SINGLE(TO_DOUBLE(n), sgl, 0); + n = CHECK_SINGLE(TO_DOUBLE(n), sgl, 0, NULL, NULL, 0, 0); } } else { if (is_long_double) { @@ -1538,7 +1552,7 @@ Scheme_Object *scheme_read_number(const mzchar *str, intptr_t len, str, len); return scheme_false; } - n = CHECK_SINGLE(n, sgl, 0); + n = CHECK_SINGLE(n, sgl, 0, NULL, NULL, 0, 0); } if (SCHEME_FLOATP(n) && str[delta] == '-') { @@ -1633,7 +1647,7 @@ Scheme_Object *scheme_read_number(const mzchar *str, intptr_t len, } else if (is_float) n1 = TO_DOUBLE(n1); - return CHECK_SINGLE(n1, sgl, 0); + return CHECK_SINGLE(n1, sgl, 0, NULL, NULL, 0, 0); } o = scheme_read_bignum(str, delta, radix); @@ -1651,7 +1665,7 @@ Scheme_Object *scheme_read_number(const mzchar *str, intptr_t len, return scheme_nzerod; } - return CHECK_SINGLE(TO_DOUBLE(o), sgl, 0); + return CHECK_SINGLE(TO_DOUBLE(o), sgl, 0, NULL, NULL, 0, 0); } return o; From 92fc1f41c83a149135575bbcbedd671f4cf2e3a5 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Mon, 9 Nov 2015 16:46:20 -0500 Subject: [PATCH 077/369] Add more hash-like operations to id-table The operations are ref!, set*, set*!, update, and update!. Also bumps version number. --- pkgs/base/info.rkt | 2 +- .../syntax/scribblings/id-table.scrbl | 83 ++++++++++++++++++- .../tests/racket/id-table-test.rktl | 35 ++++++++ racket/collects/syntax/id-table.rkt | 31 +++++++ racket/collects/syntax/private/id-table.rkt | 58 +++++++++++++ racket/src/racket/src/schvers.h | 4 +- 6 files changed, 209 insertions(+), 4 deletions(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index 3c80fdb375..4622d86004 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.3.0.5") +(define version "6.3.0.6") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/pkgs/racket-doc/syntax/scribblings/id-table.scrbl b/pkgs/racket-doc/syntax/scribblings/id-table.scrbl index 376954301e..3cea9b42f4 100644 --- a/pkgs/racket-doc/syntax/scribblings/id-table.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/id-table.scrbl @@ -118,6 +118,16 @@ the @racket[failure] argument is applied if it is a procedure, or simply returned otherwise. } +@defproc[(free-id-table-ref! [table mutable-free-id-table?] + [id identifier?] + [failure any/c]) + any]{ + +Like @racket[hash-ref!]. + +@history[#:added "6.3.0.6"] +} + @defproc[(free-id-table-set! [table mutable-free-id-table?] [id identifier?] [v any/c]) @@ -134,6 +144,26 @@ Like @racket[hash-set!]. Like @racket[hash-set]. } +@defproc[(free-id-table-set*! [table mutable-free-id-table?] + [id identifier?] + [v any/c] ...) + void?]{ + +Like @racket[hash-set*!]. + +@history[#:added "6.3.0.6"] +} + +@defproc[(free-id-table-set* [table immutable-free-id-table?] + [id identifier?] + [v any/c] ...) + immutable-free-id-table?]{ + +Like @racket[hash-set*]. + +@history[#:added "6.3.0.6"] +} + @defproc[(free-id-table-remove! [table mutable-free-id-table?] [id identifier?]) void?]{ @@ -148,6 +178,30 @@ Like @racket[hash-remove!]. Like @racket[hash-remove]. } +@defproc[(free-id-table-update! [table mutable-free-id-table?] + [id identifier?] + [updater (any/c . -> . any/c)] + [failure any/c + (lambda () (raise (make-exn:fail .....)))]) + void?]{ + +Like @racket[hash-update!]. + +@history[#:added "6.3.0.6"] +} + +@defproc[(free-id-table-update [table immutable-free-id-table?] + [id identifier?] + [updater (any/c . -> . any/c)] + [failure any/c + (lambda () (raise (make-exn:fail .....)))]) + immutable-free-id-table?]{ + +Like @racket[hash-update]. + +@history[#:added "6.3.0.6"] +} + @defproc[(free-id-table-map [table free-id-table?] [proc (-> identifier? any/c any)]) list?]{ @@ -254,6 +308,10 @@ etc) can be used on bound-identifier tables. [failure any/c (lambda () (raise (make-exn:fail .....)))]) any] +@defproc[(bound-id-table-ref! [table mutable-bound-id-table?] + [id identifier?] + [failure any/c]) + any] @defproc[(bound-id-table-set! [table mutable-bound-id-table?] [id identifier?] [v any/c]) @@ -262,12 +320,32 @@ etc) can be used on bound-identifier tables. [id identifier?] [v any/c]) immutable-bound-id-table?] +@defproc[(bound-id-table-set*! [table mutable-bound-id-table?] + [id identifier?] + [v any/c] ...) + void?] +@defproc[(bound-id-table-set* [table immutable-bound-id-table?] + [id identifier?] + [v any/c] ...) + immutable-bound-id-table?] @defproc[(bound-id-table-remove! [table mutable-bound-id-table?] [id identifier?]) void?] @defproc[(bound-id-table-remove [table immutable-bound-id-table?] [id identifier?]) immutable-bound-id-table?] +@defproc[(bound-id-table-update! [table mutable-bound-id-table?] + [id identifier?] + [updater (any/c . -> . any/c)] + [failure any/c + (lambda () (raise (make-exn:fail .....)))]) + void?] +@defproc[(bound-id-table-update [table immutable-bound-id-table?] + [id identifier?] + [updater (any/c . -> . any/c)] + [failure any/c + (lambda () (raise (make-exn:fail .....)))]) + immutable-bound-id-table?] @defproc[(bound-id-table-map [table bound-id-table?] [proc (-> identifier? any/c any)]) list?] @@ -304,7 +382,10 @@ Like the procedures for free-identifier tables for bound-identifier tables, which use @racket[bound-identifier=?] to compare keys. -@history[#:changed "6.3.0.3" "Added bound-id-table-keys, bound-id-table-values, in-bound-id-table."] +@history[#:changed "6.3.0.3" "Added bound-id-table-keys, bound-id-table-values, in-bound-id-table." + #:changed "6.3.0.6" + @string-append{Added bound-id-table-ref!, bound-id-table-set*, + bound-id-table-set*!, bound-id-table-update!, and bound-id-table-update}] } @close-eval[id-table-eval] diff --git a/pkgs/racket-test-core/tests/racket/id-table-test.rktl b/pkgs/racket-test-core/tests/racket/id-table-test.rktl index 3ae9668228..d47d8622bd 100644 --- a/pkgs/racket-test-core/tests/racket/id-table-test.rktl +++ b/pkgs/racket-test-core/tests/racket/id-table-test.rktl @@ -389,6 +389,41 @@ (list (cons #'x 0) (cons #'x 1) (cons #'y 2)))) bound-identifier=?)) +;; Tests for id-table-set*, set*!, update, update!, ref! +(let () + (define table (make-bound-id-table)) + (define table2 (make-immutable-bound-id-table)) + (define x0 #'x) + (define x1 ((make-syntax-introducer) x0)) + (define y0 #'y) + (define y1 ((make-syntax-introducer) y0)) + + (test 0 bound-id-table-ref! table x0 0) + (test 1 bound-id-table-ref! table x1 1) + (test 0 bound-id-table-ref table x0) + (test 1 bound-id-table-ref (bound-id-table-update table2 y0 add1 0) y0) + (test 1 bound-id-table-ref (bound-id-table-set* table2 y0 0 y1 1) y1) + (test (void) bound-id-table-set*! table y0 1 y1 5) + (test (void) bound-id-table-update! table y0 add1 0) + (test 2 bound-id-table-ref table y0)) + +(let () + (define table (make-free-id-table)) + (define table2 (make-immutable-free-id-table)) + (define x0 #'x) + (define x1 #'x1) + (define y0 #'y) + (define y1 #'y1) + + (test 0 free-id-table-ref! table x0 0) + (test 1 free-id-table-ref! table x1 1) + (test 0 free-id-table-ref table x0) + (test 1 free-id-table-ref (free-id-table-update table2 y0 add1 0) y0) + (test 1 free-id-table-ref (free-id-table-set* table2 y0 0 y1 1) y1) + (test (void) free-id-table-set*! table y0 1 y1 5) + (test (void) free-id-table-update! table y0 add1 0) + (test 2 free-id-table-ref table y0)) + (define-syntax name-for-boundmap-test 'dummy) (define-syntax alias-for-boundmap-test (make-rename-transformer #'name-for-boundmap-test)) (define table (make-free-id-table)) diff --git a/racket/collects/syntax/id-table.rkt b/racket/collects/syntax/id-table.rkt index f4b96fd79c..a9fb980bef 100644 --- a/racket/collects/syntax/id-table.rkt +++ b/racket/collects/syntax/id-table.rkt @@ -197,6 +197,8 @@ idtbl-set! idtbl-set idtbl-remove! idtbl-remove idtbl-set/constructor idtbl-remove/constructor + idtbl-set* idtbl-set*/constructor idtbl-set*! idtbl-ref! + idtbl-update idtbl-update/constructor idtbl-update! idtbl-count idtbl-iterate-first idtbl-iterate-next idtbl-iterate-key idtbl-iterate-value @@ -232,6 +234,13 @@ (idtbl-set/constructor d id v immutable-idtbl)) (define (idtbl-remove d id) (idtbl-remove/constructor d id immutable-idtbl)) + (define (idtbl-set* d . rst) + (apply idtbl-set*/constructor d immutable-idtbl rst)) + (define not-given (gensym 'not-given)) + (define (idtbl-update d id updater [default not-given]) + (if (eq? default not-given) + (idtbl-update/constructor d id updater immutable-idtbl) + (idtbl-update/constructor d id updater immutable-idtbl default))) (define idtbl-immutable-methods (vector-immutable idtbl-ref #f @@ -279,6 +288,28 @@ (-> mutable-idtbl? identifier? void?)] [idtbl-remove (-> immutable-idtbl? identifier? immutable-idtbl?)] + [idtbl-set* + (->* [immutable-idtbl?] + #:rest (flat-rec-contract key-value-pairs + (or/c null + (cons/c identifier? (cons/c any/c key-value-pairs)))) + immutable-idtbl?)] + [idtbl-set*! + (->* [mutable-idtbl?] + #:rest (flat-rec-contract key-value-pairs + (or/c null + (cons/c identifier? (cons/c any/c key-value-pairs)))) + void?)] + [idtbl-ref! + (-> mutable-idtbl? identifier? any/c any)] + [idtbl-update + (->* [immutable-idtbl? identifier? (-> any/c any/c)] + [any/c] + immutable-idtbl?)] + [idtbl-update! + (->* [mutable-idtbl? identifier? (-> any/c any/c)] + [any/c] + void?)] [idtbl-count (-> idtbl? exact-nonnegative-integer?)] [idtbl-iterate-first diff --git a/racket/collects/syntax/private/id-table.rkt b/racket/collects/syntax/private/id-table.rkt index e09c3646d1..b7c0ad745c 100644 --- a/racket/collects/syntax/private/id-table.rkt +++ b/racket/collects/syntax/private/id-table.rkt @@ -136,6 +136,47 @@ The {key,value}-{in-out} functions should all return a chaperone of their argume (hash-remove (id-table-hash d) sym)) phase))) +(define (id-table-set*! who d identifier->symbol identifier=? . rst) + (let loop ([rst rst]) + (cond [(null? rst) (void)] + [else + (id-table-set! + who d + (car rst) (cadr rst) + identifier->symbol identifier=?) + (loop (cddr rst))]))) + +(define (id-table-set*/constructor who d constructor identifier->symbol identifier=? . rst) + (let loop ([d d] [rst rst]) + (if (null? rst) + d + (loop (id-table-set/constructor + who d + (car rst) (cadr rst) + constructor identifier->symbol identifier=?) + (cddr rst))))) + +(define missing (gensym 'missing)) +(define (id-table-ref! who d id default identifier->symbol identifier=?) + (define entry (id-table-ref who d id missing identifier->symbol identifier=?)) + (cond [(eq? entry missing) + (id-table-set! who d id default identifier->symbol identifier=?) + default] + [else entry])) + +(define (id-table-update/constructor who d id updater default constructor identifier->symbol identifier=?) + (define entry + (id-table-ref who d id default identifier->symbol identifier=?)) + (id-table-set/constructor + who d id + (updater entry) + constructor identifier->symbol identifier=?)) + +(define (id-table-update! who d id updater default identifier->symbol identifier=?) + (define entry + (id-table-ref who d id default identifier->symbol identifier=?)) + (id-table-set! who d id (updater entry) identifier->symbol identifier=?)) + (define (id-table-count d) (for/sum ([(k v) (in-hash (id-table-hash d))]) (length v))) @@ -312,6 +353,8 @@ Notes (FIXME?): idtbl-set! idtbl-set idtbl-remove! idtbl-remove idtbl-set/constructor idtbl-remove/constructor + idtbl-set* idtbl-set*/constructor idtbl-set*! idtbl-ref! + idtbl-update idtbl-update/constructor idtbl-update! idtbl-count idtbl-iterate-first idtbl-iterate-next idtbl-iterate-key idtbl-iterate-value @@ -347,6 +390,16 @@ Notes (FIXME?): (id-table-remove/constructor 'idtbl-remove d id constructor identifier->symbol identifier=?)) (define (idtbl-remove d id) (idtbl-remove/constructor d id immutable-idtbl)) + (define (idtbl-set*/constructor d constructor . rst) + (apply id-table-set*/constructor 'idtbl-set* d constructor identifier->symbol identifier=? rst)) + (define (idtbl-set*! d . rst) + (apply id-table-set*! 'idtbl-set*! d identifier->symbol identifier=? rst)) + (define (idtbl-ref! d id default) + (id-table-ref! 'idtbl-ref! d id default identifier->symbol identifier=?)) + (define (idtbl-update/constructor d id updater constructor [default not-given]) + (id-table-update/constructor 'idtbl-update d id updater default constructor identifier->symbol identifier=?)) + (define (idtbl-update! d id updater [default not-given]) + (id-table-update! 'idtbl-update! d id updater default identifier->symbol identifier=?)) (define (idtbl-count d) (id-table-count d)) (define (idtbl-for-each d p) @@ -417,6 +470,9 @@ Notes (FIXME?): idtbl-set idtbl-remove! idtbl-remove + idtbl-set*! + idtbl-ref! + idtbl-update! idtbl-count idtbl-iterate-first idtbl-iterate-next @@ -430,7 +486,9 @@ Notes (FIXME?): ;; just for use/extension by syntax/id-table idtbl-set/constructor + idtbl-set*/constructor idtbl-remove/constructor + idtbl-update/constructor idtbl-mutable-methods mutable-idtbl immutable-idtbl)))])) diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 8f27de7232..46c0cbf6a6 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.5" +#define MZSCHEME_VERSION "6.3.0.6" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 3 #define MZSCHEME_VERSION_Z 0 -#define MZSCHEME_VERSION_W 4 +#define MZSCHEME_VERSION_W 6 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From f5dbd99e43410ce6bb67bf3e5a9701e2c4ab594b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 21 Nov 2015 18:59:44 -0700 Subject: [PATCH 078/369] fix precision in `exact->inexact` on bignums The strategy of converting a bignum to a flonum by converting on word boundaries can lose one bit of precision. (If the use of a word boundary causes a single bit to get rounded away, but the first bit of the next word is non-zero, then the rounding might have been down when it should have been up.) Avoid the problem by aligning relative to the high bit, instead. --- .../racket-test-core/tests/racket/number.rktl | 90 +++++++++++++++++++ racket/collects/compiler/private/xform.rkt | 2 +- racket/src/configure | 26 ++++++ racket/src/racket/configure.ac | 12 +++ racket/src/racket/mzconfig.h.in | 3 + racket/src/racket/src/bgnfloat.inc | 68 ++++++++++++-- racket/src/racket/src/bignum.c | 45 ++++++++++ 7 files changed, 236 insertions(+), 10 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/number.rktl b/pkgs/racket-test-core/tests/racket/number.rktl index 00b73fbbf6..a00c9724a6 100644 --- a/pkgs/racket-test-core/tests/racket/number.rktl +++ b/pkgs/racket-test-core/tests/racket/number.rktl @@ -3196,6 +3196,96 @@ (test #t list? (filter n-digit-has-nth-root? (build-list 5000 (lambda (x) (+ x 1)))))) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; exact->inexact precision on bignums (round-trip and proper rounding) + +(define max-53-bit-number (sub1 (arithmetic-shift 1 53))) + +(define (check-conversion 53-bit-number) + ;; Any 53-bit integer fits in a 64-bit floating point: + (unless (= 53-bit-number (inexact->exact (exact->inexact 53-bit-number))) + (error 'random-exact->inexact "round-trip failed ~s" 53-bit-number)) + + ;; The same holds if we shift by up to (- 1023 52): + (define (check-shift p) + (define n2 (arithmetic-shift 53-bit-number p)) + (unless (= n2 (inexact->exact (exact->inexact n2))) + (error 'random-exact->inexact "round-trip of shifted failed ~s" n2))) + (check-shift (- 1023 52)) + (for ([i 10]) + (check-shift (random (- 1023 52)))) + + ;; The same holds if we shift by up to (- -1022 52): + (define (check-div p) + (define n2 (/ 53-bit-number (arithmetic-shift 1 (- p)))) + (unless (= n2 (inexact->exact (exact->inexact n2))) + (error 'random-exact->inexact "round-trip of shifted failed ~s" n2))) + (check-div (- (+ 1022 52))) + (for ([i 10]) + (check-div (- (random (+ 1022 52))))) + + ;; Helper for checking rounding: + (define (check-random-pairs check-shift-pair) + (check-shift-pair 1 0) + (check-shift-pair (- 1023 52 1) 0) + (check-shift-pair 1 (- 1023 52 2)) + (for ([i 10]) + (define zeros (add1 (random (- 1023 52 3)))) + (define extra (random (- 1023 52 1 zeros))) + (check-shift-pair zeros extra))) + + ;; If we add a zero bit and then a non-zero bit anywhere later, + ;; conversion to inexact should round down. + (define (check-shift-plus-bits-to-truncate num-zeros extra-p) + (define n2 (arithmetic-shift + (bitwise-ior (arithmetic-shift 53-bit-number (add1 num-zeros)) + 1) + extra-p)) + (define n3 (inexact->exact (exact->inexact n2))) + (unless (= n3 (arithmetic-shift 53-bit-number (+ num-zeros 1 extra-p))) + (error 'random-exact->inexact "truncating round failed ~s" n2))) + (check-random-pairs check-shift-plus-bits-to-truncate) + + ;; If we add a one bit and then a non-zero bit anywhere later, + ;; conversion to inexact should round up. + (unless (= 53-bit-number max-53-bit-number) + (define (check-shift-plus-bits-to-up num-one-then-zeros extra-p) + (define n2 (arithmetic-shift + (bitwise-ior (arithmetic-shift + (bitwise-ior (arithmetic-shift 53-bit-number 1) + 1) + num-one-then-zeros) + 1) + extra-p)) + (define n3 (inexact->exact (exact->inexact n2))) + (unless (= n3 (arithmetic-shift (add1 53-bit-number) (+ num-one-then-zeros 1 extra-p))) + (error 'random-exact->inexact "round up failed ~s" n2))) + (check-random-pairs check-shift-plus-bits-to-up)) + + ;; If we add a one bit and then only zero bits, + ;; conversion to inexact should round to even. + (unless (= 53-bit-number max-53-bit-number) + (define (check-shift-plus-bits-to-even num-one-then-zeros extra-p) + (define n2 (arithmetic-shift + (bitwise-ior (arithmetic-shift 53-bit-number 1) + 1) + (+ num-one-then-zeros extra-p))) + (define n3 (inexact->exact (exact->inexact n2))) + (unless (= n3 (arithmetic-shift (if (even? 53-bit-number) + 53-bit-number + (add1 53-bit-number)) + (+ num-one-then-zeros 1 extra-p))) + (error 'random-exact->inexact "round to even failed ~s" n2))) + (check-random-pairs check-shift-plus-bits-to-even))) + +(check-conversion max-53-bit-number) +(for ([i 100]) + (check-conversion + ;; Random 53-bit number: + (+ (arithmetic-shift 1 52) + (arithmetic-shift (random (expt 2 24)) 24) + (random (expt 2 28))))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; exact->inexact precision (thanks to Neil Toronto) diff --git a/racket/collects/compiler/private/xform.rkt b/racket/collects/compiler/private/xform.rkt index 38052342fe..ce0b2d9559 100644 --- a/racket/collects/compiler/private/xform.rkt +++ b/racket/collects/compiler/private/xform.rkt @@ -903,7 +903,7 @@ _isnan __isfinited __isnanl __isnan __isinff __isinfl isnanf isinff __isinfd __isnanf __isnand __isinf __inline_isnanl __inline_isnan - __builtin_popcount + __builtin_popcount __builtin_clz _Generic __inline_isinff __inline_isinfl __inline_isinfd __inline_isnanf __inline_isnand __inline_isinf floor floorl ceil ceill round roundl fmod fmodl modf modfl fabs fabsl __maskrune _errno __errno diff --git a/racket/src/configure b/racket/src/configure index 21aecfa370..6e6360cb35 100755 --- a/racket/src/configure +++ b/racket/src/configure @@ -5793,6 +5793,32 @@ if test "${has_builtin_popcount}" = "yes" ; then $as_echo "#define MZ_HAS_BUILTIN_POPCOUNT 1" >>confdefs.h +fi + + msg="for __builtin_clz" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $msg" >&5 +$as_echo_n "checking $msg... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + int main(int argc, char **argv) { + unsigned int i = argc; + return __builtin_clz(i); + } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + has_builtin_clz=yes +else + has_builtin_clz=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_builtin_clz" >&5 +$as_echo "$has_builtin_clz" >&6; } +if test "${has_builtin_clz}" = "yes" ; then + +$as_echo "#define MZ_HAS_BUILTIN_CLZ 1" >>confdefs.h + fi if test "${enable_backtrace}" = "yes" ; then diff --git a/racket/src/racket/configure.ac b/racket/src/racket/configure.ac index bff753b8ed..579b400c39 100644 --- a/racket/src/racket/configure.ac +++ b/racket/src/racket/configure.ac @@ -1276,6 +1276,18 @@ if test "${has_builtin_popcount}" = "yes" ; then AC_DEFINE(MZ_HAS_BUILTIN_POPCOUNT,1,[Has __builtin_popcount]) fi +[ msg="for __builtin_clz" ] +AC_MSG_CHECKING($msg) +AC_LINK_IFELSE([AC_LANG_SOURCE([ + int main(int argc, char **argv) { + unsigned int i = argc; + return __builtin_clz(i); + }])], has_builtin_clz=yes, has_builtin_clz=no) +AC_MSG_RESULT($has_builtin_clz) +if test "${has_builtin_clz}" = "yes" ; then + AC_DEFINE(MZ_HAS_BUILTIN_CLZ,1,[Has __builtin_clz]) +fi + if test "${enable_backtrace}" = "yes" ; then GC2OPTIONS="$GC2OPTIONS -DMZ_GC_BACKTRACE" fi diff --git a/racket/src/racket/mzconfig.h.in b/racket/src/racket/mzconfig.h.in index 8987178abf..c110bdd358 100644 --- a/racket/src/racket/mzconfig.h.in +++ b/racket/src/racket/mzconfig.h.in @@ -74,6 +74,9 @@ typedef unsigned long uintptr_t; /* When __builtin_popcount() is available: */ #undef MZ_HAS_BUILTIN_POPCOUNT +/* When __builtin_clz() is available: */ +#undef MZ_HAS_BUILTIN_CLZ + /* Enable futures: */ #undef MZ_USE_FUTURES diff --git a/racket/src/racket/src/bgnfloat.inc b/racket/src/racket/src/bgnfloat.inc index bd07924ae9..38bd0ec5d1 100644 --- a/racket/src/racket/src/bgnfloat.inc +++ b/racket/src/racket/src/bgnfloat.inc @@ -27,7 +27,7 @@ FP_TYPE SCHEME_BIGNUM_TO_FLOAT_INFO(const Scheme_Object *n, intptr_t skip, intpt FP_TYPE d; nl = SCHEME_BIGLEN(n); - na = SCHEME_BIGDIG(n) + nl; + na = SCHEME_BIGDIG(n); skipped = nl; @@ -38,14 +38,63 @@ FP_TYPE SCHEME_BIGNUM_TO_FLOAT_INFO(const Scheme_Object *n, intptr_t skip, intpt return FP_scheme_floating_point_nzero; } else nl -= skip; - - d = FP_ZEROx; - while (nl--) { - d = FP_TYPE_MULT(d, FP_TYPE_FROM_DOUBLE(BIG_RADIX)); - d = FP_TYPE_PLUS(d, FP_TYPE_FROM_UINTPTR(*(--na))); - if (IS_FLOAT_INF(d)) - break; - --skipped; + + if (!nl) + d = FP_ZEROx; + else if (nl == 1) { + d = FP_TYPE_FROM_UINTPTR(*na); + skipped = 0; + } else { + /* We'll get all the bits that matter in the first word or two, + and we won't lose precision as long as we shift so that the + highest bit in a word is non-zero */ + bigdig b = na[nl-1]; + int delta; + + delta = mz_clz(b); + if (delta) { + /* zero bits in the highest word => pull in bits from the + second-highest word */ + b = (b << delta) + (na[nl-2] >> (WORD_SIZE - delta)); + } + if (sizeof(FP_TYPE) <= sizeof(bigdig)) { + /* one bigdig is enough, and the last bit is certainly + not needed, but it needs to summarize whether there + are any more non-zero bits in the number */ + if (!(b & 0x1) && any_nonzero_digits(na, nl-1, delta)) + b |= 0x1; + d = FP_TYPE_FROM_UINTPTR(b); + } else { + /* Need to look at a second word, possibly pulling in bits from + a third word */ + d = FP_TYPE_FROM_UINTPTR(b); + d = FP_TYPE_MULT(d, FP_TYPE_FROM_DOUBLE(BIG_RADIX)); + b = (na[nl-2] << delta); + if ((nl > 2) && delta) + b += (na[nl-3] >> (WORD_SIZE - delta)); + if (!(b & 0x1) && (nl > 2) && any_nonzero_digits(na, nl-2, delta)) + b |= 0x1; + d = FP_TYPE_PLUS(d, FP_TYPE_FROM_UINTPTR(b)); + d = FP_TYPE_DIV(d, FP_TYPE_FROM_DOUBLE(BIG_RADIX)); + } + /* Shift `d` back down by delta: */ + if (delta) + d = FP_TYPE_DIV(d, FP_TYPE_POW(FP_TYPE_FROM_DOUBLE(2.0), + FP_TYPE_FROM_INT(delta))); + nl--; + + /* Shift `d` up by remaining bignum words */ + if (_skipped) { + while (nl--) { + d = FP_TYPE_MULT(d, FP_TYPE_FROM_DOUBLE(BIG_RADIX)); + if (IS_FLOAT_INF(d)) + break; + --skipped; + } + } else { + d = FP_TYPE_MULT(d, FP_TYPE_POW(FP_TYPE_FROM_DOUBLE(2.0), + FP_TYPE_FROM_UINTPTR(nl * WORD_SIZE))); + } } if (_skipped) @@ -151,6 +200,7 @@ Scheme_Object *SCHEME_BIGNUM_FROM_FLOAT(FP_TYPE d) #undef FP_TYPE_MULT #undef FP_TYPE_PLUS #undef FP_TYPE_DIV +#undef FP_TYPE_POW #undef FP_TYPE_FROM_INT #undef FP_TYPE_GREATER_OR_EQV #undef FP_TYPE_MINUS diff --git a/racket/src/racket/src/bignum.c b/racket/src/racket/src/bignum.c index 51ec30b937..f660b2a62b 100644 --- a/racket/src/racket/src/bignum.c +++ b/racket/src/racket/src/bignum.c @@ -1422,6 +1422,48 @@ static void bignum_add1_inplace(Scheme_Object **_stk_o) *_stk_o = bignum_copy(*_stk_o, carry); } +XFORM_NONGCING static int mz_clz(uintptr_t n) +{ +#ifdef MZ_HAS_BUILTIN_CLZ +# if defined(SIXTY_FOUR_BIT_INTEGERS) || defined(USE_LONG_LONG_FOR_BIGDIG) + uintptr_t hi = (n >> (WORD_SIZE >> 1)); + if (hi) + return __builtin_clz(hi); + else { + unsigned int low = n; + return (WORD_SIZE >> 1) + __builtin_clz(low); + } +# else + return __builtin_clz(n); +# endif +#else + int c = 0, d = (WORD_SIZE >> 1); + while (d) { + if (n >> (c + d)) + c += d; + d = d >> 1; + } + return WORD_SIZE - 1 - c; +#endif +} + +XFORM_NONGCING static int any_nonzero_digits(bigdig *na, intptr_t nl, int delta) +/* if `delta`, then check only after that many bits in the most-significant + digit */ +{ + if (delta) { + if (na[nl-1] & (((bigdig)1 << (WORD_SIZE - delta)) - 1)) + return 1; + nl--; + } + + while (nl--) { + if (na[nl]) + return 1; + } + return 0; +} + #define USE_FLOAT_BITS 53 #define FP_TYPE double @@ -1431,6 +1473,7 @@ static void bignum_add1_inplace(Scheme_Object **_stk_o) #define FP_TYPE_MULT(x, y) ((x)*(y)) #define FP_TYPE_PLUS(x, y) ((x)+(y)) #define FP_TYPE_DIV(x, y) ((x)/(y)) +#define FP_TYPE_POW(x, y) pow(x, y) #define FP_TYPE_FROM_INT(x) ((FP_TYPE)(x)) #define FP_TYPE_GREATER_OR_EQV(x, y) ((x)>=(y)) #define FP_TYPE_MINUS(x, y) ((x)-(y)) @@ -1453,6 +1496,7 @@ static void bignum_add1_inplace(Scheme_Object **_stk_o) #define FP_TYPE_MULT(x, y) ((x)*(y)) #define FP_TYPE_PLUS(x, y) ((x)+(y)) #define FP_TYPE_DIV(x, y) ((x)/(y)) +#define FP_TYPE_POW(x, y) pow(x, y) #define FP_TYPE_FROM_INT(x) ((FP_TYPE)(x)) #define FP_TYPE_GREATER_OR_EQV(x, y) ((x)>=(y)) #define FP_TYPE_MINUS(x, y) ((x)-(y)) @@ -1475,6 +1519,7 @@ static void bignum_add1_inplace(Scheme_Object **_stk_o) # define FP_TYPE_MULT(x, y) long_double_mult(x, y) # define FP_TYPE_DIV(x, y) long_double_div(x, y) # define FP_TYPE_PLUS(x, y) long_double_plus(x, y) +# define FP_TYPE_POW(x, y) long_double_pow(x, y) # define FP_TYPE_FROM_INT(x) long_double_from_int(x) # define FP_TYPE_GREATER_OR_EQV(x, y) long_double_greater_or_eqv(x, y) # define FP_TYPE_MINUS(x, y) long_double_minus(x, y) From 901ffdcbac51af5e647132f7308adc4fd5b8b068 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 22 Nov 2015 06:50:15 -0700 Subject: [PATCH 079/369] fix inexact-number parsing problem Bug introduced in c40229f756. --- pkgs/racket-test-core/tests/racket/numstrs.rktl | 1 + racket/src/racket/src/numstr.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test-core/tests/racket/numstrs.rktl b/pkgs/racket-test-core/tests/racket/numstrs.rktl index bf01770a18..e6d7afb2dd 100644 --- a/pkgs/racket-test-core/tests/racket/numstrs.rktl +++ b/pkgs/racket-test-core/tests/racket/numstrs.rktl @@ -53,6 +53,7 @@ (-0.0 "-1#e-10000000000000000000000000000000") (1e-134 "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001") + (-0.0 "-632.3206524753840966914228247597079196012717570277972845484e-399") (10.0 "1#") (10.0 "1#e0") (10.0 "1####e-3") diff --git a/racket/src/racket/src/numstr.c b/racket/src/racket/src/numstr.c index a3817d101b..ac7b837b45 100644 --- a/racket/src/racket/src/numstr.c +++ b/racket/src/racket/src/numstr.c @@ -1481,7 +1481,8 @@ Scheme_Object *scheme_read_number(const mzchar *str, intptr_t len, max_useful = scheme_bin_plus(scheme_make_integer(MAX_FLOATREAD_PRECISION_DIGITS(is_long_double)), exponent); - if (scheme_bin_lt(max_useful, scheme_make_integer(0))) { + if (scheme_bin_lt(max_useful, scheme_make_integer(2))) { + /* will definitely underflow */ if (dcp > 2) dcp = 2; /* leave room for a sign and a digit */ } else if (SCHEME_INTP(max_useful)) { From 5691b5a3444e4ae789fd9aab76f7022ab4c4ebb6 Mon Sep 17 00:00:00 2001 From: zsh_89 Date: Sat, 21 Nov 2015 18:00:06 +0800 Subject: [PATCH 080/369] Add a link to a Macro tutorial written by Greg Hendershott which helps new learners understand Racket macro better. --- pkgs/racket-doc/scribblings/guide/macros.scrbl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkgs/racket-doc/scribblings/guide/macros.scrbl b/pkgs/racket-doc/scribblings/guide/macros.scrbl index 8da7bd9ab3..963f4c5077 100644 --- a/pkgs/racket-doc/scribblings/guide/macros.scrbl +++ b/pkgs/racket-doc/scribblings/guide/macros.scrbl @@ -15,6 +15,8 @@ make simple transformations easy to implement and reliable to use. Racket also supports arbitrary macro transformers that are implemented in Racket---or in a macro-extended variant of Racket. +(For a bottom-up introduction of Racket macro, you may refer to: @(hyperlink "http://www.greghendershott.com/fear-of-macros/" "Fear of Macros")) + @local-table-of-contents[] @;------------------------------------------------------------------------ From 2a88662d01599d9c284d2fbd1f7b987d57658797 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 22 Nov 2015 08:16:48 -0700 Subject: [PATCH 081/369] exact->inexact fixup for MSVC Casting a `uintptr_t` to `double` seems not to round to nearest, so keep all bits while moving to `double` and use arithmetic to combine them (since the rounding mode is used correctly for arithmetic). --- racket/src/racket/sconfig.h | 6 ++++++ racket/src/racket/src/bignum.c | 35 +++++++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/racket/src/racket/sconfig.h b/racket/src/racket/sconfig.h index 27fb376ea5..4df1b80d59 100644 --- a/racket/src/racket/sconfig.h +++ b/racket/src/racket/sconfig.h @@ -679,6 +679,7 @@ /* With VC 7, ATAN2_DOESNT... wasn't needed, and POW_HANDLES_INF_CORRECTLY worked, too. */ # define SIN_COS_NEED_DEOPTIMIZE +# define AVOID_INT_TO_FLOAT_TRUNCATION #endif #ifdef __BORLANDC__ # define NAN_EQUALS_ANYTHING @@ -1281,6 +1282,11 @@ /* FLOATING_POINT_IS_NOT_IEEE disables inexact->exact conversion via parsing of IEEE-format bits. */ + /* AVOID_INT_TO_FLOAT_TRUNCATION indicates that conversion from an + integer to a floating point type does not round-to-nearest when + precision is lost, even when the FP rounding mode is + round-to-nearest */ + /* USE_SINGLE_FLOATS turns on support for single-precision floating point numbers. Otherwise, floating point numbers are always represented in double-precision. */ diff --git a/racket/src/racket/src/bignum.c b/racket/src/racket/src/bignum.c index f660b2a62b..29659ffda8 100644 --- a/racket/src/racket/src/bignum.c +++ b/racket/src/racket/src/bignum.c @@ -90,6 +90,7 @@ void scheme_bignum_use_fuel(intptr_t n); #if defined(SIXTY_FOUR_BIT_INTEGERS) || defined(USE_LONG_LONG_FOR_BIGDIG) # define BIG_RADIX 18446744073709551616.0 /* = 0x10000000000000000 */ +# define BIG_HALF_RADIX 4294967296.0 # define WORD_SIZE 64 #else # define BIG_RADIX 4294967296.0 /* = 0x100000000 */ @@ -1464,10 +1465,21 @@ XFORM_NONGCING static int any_nonzero_digits(bigdig *na, intptr_t nl, int delta) return 0; } +#if defined(SIXTY_FOUR_BIT_INTEGERS) && defined(AVOID_INT_TO_FLOAT_TRUNCATION) +XFORM_NONGCING static double double_from_bigdig(bigdig b) +{ + double d1, d2; + + d1 = (double)(b >> (WORD_SIZE >> 1)); + d2 = (double)(b & (((bigdig)1 << (WORD_SIZE >> 1))-1)); + return (d1 * BIG_HALF_RADIX) + d2; +} +#endif + #define USE_FLOAT_BITS 53 #define FP_TYPE double -#define FP_TYPE_FROM_DOUBLE(x) (FP_TYPE)x +#define FP_TYPE_FROM_DOUBLE(x) ((FP_TYPE)(x)) #define FP_TYPE_NEG(x) (-(x)) #define FP_TYPE_LESS(x, y) ((x)<(y)) #define FP_TYPE_MULT(x, y) ((x)*(y)) @@ -1475,9 +1487,13 @@ XFORM_NONGCING static int any_nonzero_digits(bigdig *na, intptr_t nl, int delta) #define FP_TYPE_DIV(x, y) ((x)/(y)) #define FP_TYPE_POW(x, y) pow(x, y) #define FP_TYPE_FROM_INT(x) ((FP_TYPE)(x)) +#if defined(SIXTY_FOUR_BIT_INTEGERS) && defined(AVOID_INT_TO_FLOAT_TRUNCATION) +# define FP_TYPE_FROM_UINTPTR(x) double_from_bigdig(x) +#else +# define FP_TYPE_FROM_UINTPTR(x) ((FP_TYPE)(x)) +#endif #define FP_TYPE_GREATER_OR_EQV(x, y) ((x)>=(y)) #define FP_TYPE_MINUS(x, y) ((x)-(y)) -#define FP_TYPE_FROM_UINTPTR #define IS_FLOAT_INF scheme__is_double_inf #define SCHEME_BIGNUM_TO_FLOAT_INFO scheme_bignum_to_double_inf_info @@ -1490,17 +1506,26 @@ XFORM_NONGCING static int any_nonzero_digits(bigdig *na, intptr_t nl, int delta) # define USE_FLOAT_BITS 24 # define FP_TYPE float -# define FP_TYPE_FROM_DOUBLE(x) (FP_TYPE)x +#define FP_TYPE_FROM_DOUBLE(x) ((FP_TYPE)(x)) #define FP_TYPE_NEG(x) (-(x)) #define FP_TYPE_LESS(x, y) ((x)<(y)) #define FP_TYPE_MULT(x, y) ((x)*(y)) #define FP_TYPE_PLUS(x, y) ((x)+(y)) #define FP_TYPE_DIV(x, y) ((x)/(y)) #define FP_TYPE_POW(x, y) pow(x, y) -#define FP_TYPE_FROM_INT(x) ((FP_TYPE)(x)) +#if defined(AVOID_INT_TO_FLOAT_TRUNCATION) +# if defined(SIXTY_FOUR_BIT_INTEGERS) +# define FP_TYPE_FROM_UINTPTR(x) ((FP_TYPE)double_from_bigdig(x)) +# else +# define FP_TYPE_FROM_UINTPTR(x) (FP_TYPE)((double)(x)) +# endif +# define FP_TYPE_FROM_INT(x) (FP_TYPE)((double)(x)) +#else +# define FP_TYPE_FROM_UINTPTR(x) ((FP_TYPE)(x)) +# define FP_TYPE_FROM_INT(x) ((FP_TYPE)(x)) +#endif #define FP_TYPE_GREATER_OR_EQV(x, y) ((x)>=(y)) #define FP_TYPE_MINUS(x, y) ((x)-(y)) -# define FP_TYPE_FROM_UINTPTR # define IS_FLOAT_INF scheme__is_float_inf # define SCHEME_BIGNUM_TO_FLOAT_INFO scheme_bignum_to_float_inf_info From ce7487182ace6aa079f4587f477dcbb4dad32e4e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 22 Nov 2015 09:08:22 -0700 Subject: [PATCH 082/369] fix too-early exact->inexact conversion in number parsing Robby found this bug, continuing his streak that included find the bugs behind commits f5dbd99e43 and 901ffdcbac. --- pkgs/racket-test-core/tests/racket/numstrs.rktl | 3 +++ racket/src/racket/src/numstr.c | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/numstrs.rktl b/pkgs/racket-test-core/tests/racket/numstrs.rktl index e6d7afb2dd..061229bf23 100644 --- a/pkgs/racket-test-core/tests/racket/numstrs.rktl +++ b/pkgs/racket-test-core/tests/racket/numstrs.rktl @@ -54,6 +54,9 @@ (1e-134 "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001") (-0.0 "-632.3206524753840966914228247597079196012717570277972845484e-399") + (1e-300 + ;; check e->i only after division is performed + "#i500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") (10.0 "1#") (10.0 "1#e0") (10.0 "1####e-3") diff --git a/racket/src/racket/src/numstr.c b/racket/src/racket/src/numstr.c index ac7b837b45..c0fe380ea7 100644 --- a/racket/src/racket/src/numstr.c +++ b/racket/src/racket/src/numstr.c @@ -1582,7 +1582,8 @@ Scheme_Object *scheme_read_number(const mzchar *str, intptr_t len, first[has_slash - delta] = 0; n1 = scheme_read_number(first, has_slash - delta, - is_float, is_not_float, 1, + /* recur without is_float to keep all precision */ + 0, is_not_float, 1, radix, 1, next_complain, div_by_zero, test_only, @@ -1606,7 +1607,8 @@ Scheme_Object *scheme_read_number(const mzchar *str, intptr_t len, #endif n2 = scheme_read_number(substr, len - has_slash - 1, - is_float, is_not_float, 1, + /* recur without is_float to keep all precision */ + 0, is_not_float, 1, radix, 1, next_complain, div_by_zero, test_only, From 5cb02282f5f7086280ac3d91b6451f7b12b86b07 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 22 Nov 2015 18:09:11 -0700 Subject: [PATCH 083/369] fix round-to-even for `exact->inexact` on rationals Thanks again to Robby --- pkgs/racket-test-core/tests/racket/number.rktl | 10 ++++++++++ racket/src/racket/src/ratfloat.inc | 6 +++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/number.rktl b/pkgs/racket-test-core/tests/racket/number.rktl index a00c9724a6..d601b473e1 100644 --- a/pkgs/racket-test-core/tests/racket/number.rktl +++ b/pkgs/racket-test-core/tests/racket/number.rktl @@ -3286,6 +3286,16 @@ (arithmetic-shift (random (expt 2 24)) 24) (random (expt 2 28))))) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check roun-to-even of rationale conversion (thanks to Robby) + +(let () + (define l (floating-point-bytes->real #"\x1a\xd8\x9c\x17\x21\x2e\xfd\x25" #t)) + (define r (floating-point-bytes->real #"\x1a\xd8\x9c\x17\x21\x2e\xfd\x26" #t)) + (test r exact->inexact (/ (+ (inexact->exact l) + (inexact->exact r)) + 2))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; exact->inexact precision (thanks to Neil Toronto) diff --git a/racket/src/racket/src/ratfloat.inc b/racket/src/racket/src/ratfloat.inc index 560b3eaaa4..9735c6c687 100644 --- a/racket/src/racket/src/ratfloat.inc +++ b/racket/src/racket/src/ratfloat.inc @@ -104,7 +104,7 @@ FP_TYPE SCHEME_RATIONAL_TO_FLOAT(const Scheme_Object *o) if (shift > FLOAT_M_BITS) { shift = FLOAT_M_BITS; } - + a[0] = n; a[1] = scheme_make_integer(shift); n = scheme_bitwise_shift(2, a); @@ -120,9 +120,9 @@ FP_TYPE SCHEME_RATIONAL_TO_FLOAT(const Scheme_Object *o) } else { /* Round to even: */ a[0] = d; - if (!scheme_odd_p(1, a)) { + if (SCHEME_FALSEP(scheme_odd_p(1, a))) { a[0] = n; - if (!scheme_even_p(1, a)) { + if (SCHEME_FALSEP(scheme_even_p(1, a))) { n = scheme_bin_plus(n, scheme_make_integer(1)); } } From ad53983276afc745e59a11d0af18ec18722b0bb4 Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Mon, 23 Nov 2015 08:41:10 -0500 Subject: [PATCH 084/369] fix history annotations --- pkgs/racket-doc/scribblings/reference/read.scrbl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/read.scrbl b/pkgs/racket-doc/scribblings/reference/read.scrbl index 2b64d6b242..a397aadfce 100644 --- a/pkgs/racket-doc/scribblings/reference/read.scrbl +++ b/pkgs/racket-doc/scribblings/reference/read.scrbl @@ -223,7 +223,7 @@ A @tech{parameter} that controls whether @litchar{[} and @litchar{]} are treated as parentheses, but the resulting list tagged with @racket[#%brackets]. See @secref["parse-pair"] for more information. -@history[#:added "6.2.900.18"]} +@history[#:added "6.3.0.5"]} @defboolparam[read-curly-brace-with-tag on?]{ @@ -232,7 +232,7 @@ A @tech{parameter} that controls whether @litchar["{"] and tagged with @racket[#%braces]. See @secref["parse-pair"] for more information. -@history[#:added "6.2.900.18"]} +@history[#:added "6.3.0.5"]} @defboolparam[read-accept-box on?]{ @@ -279,7 +279,7 @@ A @tech{parameter} that controls parsing input with a dot, in a C structure accessor style. See @secref["parse-cdot"] for more information. -@history[#:added "6.2.900.18"]} +@history[#:added "6.3.0.5"]} @defboolparam[read-accept-quasiquote on?]{ From fcfa969b4ac4ce01044b47bf52ba7249833956c7 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 23 Nov 2015 09:02:22 -0600 Subject: [PATCH 085/369] add some examples to impersonate-procedure --- .../scribblings/reference/chaperones.scrbl | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/chaperones.scrbl b/pkgs/racket-doc/scribblings/reference/chaperones.scrbl index cf5ae09818..646be4c8ec 100644 --- a/pkgs/racket-doc/scribblings/reference/chaperones.scrbl +++ b/pkgs/racket-doc/scribblings/reference/chaperones.scrbl @@ -246,7 +246,47 @@ of impersonators with respect to wrapping impersonators to be detected within @history[#:changed "6.3.0.5" @elem{Added support for @racket['mark _key _val] results from - @racket[wrapper-proc].}]} + @racket[wrapper-proc].}] + + @examples[ + + (define (add15 x) (+ x 15)) + (define add15+print + (impersonate-procedure add15 + (λ (x) + (printf "called with ~s\n" x) + (values (λ (res) + (printf "returned ~s\n" res) + res) + x)))) + (add15 27) + (add15+print 27) + + (define-values (imp-prop:p1 imp-prop:p1? imp-prop:p1-get) + (make-impersonator-property 'imp-prop:p1)) + (define-values (imp-prop:p2 imp-prop:p2? imp-prop:p2-get) + (make-impersonator-property 'imp-prop:p2)) + + (define add15.2 (impersonate-procedure add15 #f imp-prop:p1 11)) + (add15.2 2) + (imp-prop:p1? add15.2) + (imp-prop:p1-get add15.2) + (imp-prop:p2? add15.2) + + (define add15.3 (impersonate-procedure add15.2 #f imp-prop:p2 13)) + (add15.3 3) + (imp-prop:p1? add15.3) + (imp-prop:p1-get add15.3) + (imp-prop:p2? add15.3) + (imp-prop:p2-get add15.3) + + (define add15.4 (impersonate-procedure add15.3 #f imp-prop:p1 101)) + (add15.4 4) + (imp-prop:p1? add15.4) + (imp-prop:p1-get add15.4) + (imp-prop:p2? add15.4) + (imp-prop:p2-get add15.4)] +} @defproc[(impersonate-procedure* [proc procedure?] [wrapper-proc (or/c procedure? #f)] From b443f3fe687a4778a37069cd531d4a4775de769e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 24 Nov 2015 09:19:38 -0700 Subject: [PATCH 086/369] fix broken resize of place array Change default array size from 32 to 4, so that the resize path is used (and tested) on more typical machines. --- racket/src/racket/gc2/newgc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index cbf66a94c9..95b9763c42 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -2984,11 +2984,11 @@ void GC_allow_master_gc_check() { static void NewGCMasterInfo_initialize() { int i; MASTERGCINFO = ofm_malloc_zero(sizeof(NewGCMasterInfo)); - MASTERGCINFO->size = 32; + MASTERGCINFO->size = 4; MASTERGCINFO->alive = 0; MASTERGCINFO->ready = 0; MASTERGCINFO->signal_fds = (void **)ofm_malloc(sizeof(void*) * MASTERGCINFO->size); - for (i=0; i < 32; i++ ) { + for (i=0; i < MASTERGCINFO->size; i++ ) { MASTERGCINFO->signal_fds[i] = (void *)REAPED_SLOT_AVAILABLE; } mzrt_rwlock_create(&MASTERGCINFO->cangc); @@ -3157,7 +3157,6 @@ static intptr_t NewGCMasterInfo_find_free_id() { void **new_signal_fds; size = MASTERGCINFO->size * 2; - MASTERGCINFO->alive++; new_signal_fds = ofm_malloc(sizeof(void*) * size); memcpy(new_signal_fds, MASTERGCINFO->signal_fds, sizeof(void*) * MASTERGCINFO->size); @@ -3165,6 +3164,8 @@ static intptr_t NewGCMasterInfo_find_free_id() { new_signal_fds[i] = (void *)REAPED_SLOT_AVAILABLE; } + ofm_free(MASTERGCINFO->signal_fds, sizeof(void*) * MASTERGCINFO->size); + MASTERGCINFO->signal_fds = new_signal_fds; MASTERGCINFO->size = size; } From 050f708879f568b292ed74743cc8e3f993a0828c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 24 Nov 2015 09:49:09 -0700 Subject: [PATCH 087/369] setup/unixstyle-install: fix DESTDIR mode for ".desktop" fixup Closes #1143 --- racket/collects/setup/unixstyle-install.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/racket/collects/setup/unixstyle-install.rkt b/racket/collects/setup/unixstyle-install.rkt index 5a94021a42..b1230670c1 100644 --- a/racket/collects/setup/unixstyle-install.rkt +++ b/racket/collects/setup/unixstyle-install.rkt @@ -281,10 +281,10 @@ ;; Assume anything after a space is the argument spec: (let ([m (regexp-match #rx"Exec=([^ ]*)(.*)" l)]) (format "Exec=~a~a" - (fixup-path bindir (cadr m)) + (fixup-path (dir: 'bin) (cadr m)) (caddr m)))] [(regexp-match? #rx"^Icon=" l) - (format "Icon=~a" (fixup-path sharerktdir (substring l 5)))] + (format "Icon=~a" (fixup-path (dir: 'sharerkt) (substring l 5)))] [else l]))) (unless (equal? ls new-ls) (call-with-output-file (build-path appsdir d) From 35fffb09d0fc165d9857f7f6356b38c3e3b77361 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Tue, 24 Nov 2015 11:20:28 -0500 Subject: [PATCH 088/369] Finally fix the concurrency in this test. The bug was an induced failure in the http server, to test retry support, triggered another run of half of the synchronization protocol, leading to a stuck state. --- pkgs/racket-test/tests/pkg/tests-locking.rkt | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/pkgs/racket-test/tests/pkg/tests-locking.rkt b/pkgs/racket-test/tests/pkg/tests-locking.rkt index a3bcf6ea54..7fd9de67e1 100644 --- a/pkgs/racket-test/tests/pkg/tests-locking.rkt +++ b/pkgs/racket-test/tests/pkg/tests-locking.rkt @@ -20,10 +20,18 @@ (thread (λ () + (define first-time? #t) (serve/servlet (pkg-index/basic (λ (pkg-name) - (channel-put fail-catalog 'go) - (sync fail-catalog) ;; => 'continue + ;; only do the synchronization protocol once: + ;; `pkg-index/basic` can decide to return 500 + ;; which triggers a retry, and since no one is + ;; posting a second time to these channels, we + ;; would get stuck. + (when first-time? + (channel-put fail-catalog 'go) + (define v (sync fail-catalog)) ;; => 'continue + (set! first-time? #f)) (define r (hash-ref *index-ht-1* pkg-name #f)) r) (λ () *index-ht-1*)) @@ -34,14 +42,11 @@ ;; Step 2: Assign it as our server $ "raco pkg config --set catalogs http://localhost:9967" - $ "raco pkg show pkg-test1" - ;; Step 3: Start an installation request in the background (thread (λ () (shelly-begin - $ "raco pkg install pkg-test1" - $ "raco pkg show pkg-test1") + $ "raco pkg install pkg-test1") (channel-put succeed-catalog 'done))) (sync fail-catalog) ;; => 'go From 8839f7b848c6c7762e006eeed365aa656d5eb277 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 25 Nov 2015 07:18:12 -0700 Subject: [PATCH 089/369] bump version number Should have incremented it for "xform.rkt" change in f5dbd99e43. --- 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 4622d86004..f4ac537349 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.3.0.6") +(define version "6.3.0.7") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 46c0cbf6a6..b877a21668 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.6" +#define MZSCHEME_VERSION "6.3.0.7" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 3 #define MZSCHEME_VERSION_Z 0 -#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) From e9282d4f6e303438324cab6546f532cd287d1037 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Wed, 25 Nov 2015 17:30:26 -0600 Subject: [PATCH 090/369] Fix `expt` of floats by large positive bignums. Brings behavior in line with Gambit. Closes GH #1148. --- .../racket-test-core/tests/racket/number.rktl | 5 +++++ racket/src/racket/src/number.c | 21 ++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/number.rktl b/pkgs/racket-test-core/tests/racket/number.rktl index d601b473e1..0d0cb70062 100644 --- a/pkgs/racket-test-core/tests/racket/number.rktl +++ b/pkgs/racket-test-core/tests/racket/number.rktl @@ -568,6 +568,11 @@ (test 0.0f0 expt -0.9999f0 (expt 2 5000)) (test -0.0f0 expt -0.9999f0 (add1 (expt 2 5000))) +(test +inf.0 expt -4.0 (expt 2 5000)) +(test -inf.0 expt -4.0 (add1 (expt 2 5000))) +(test +inf.f expt -4.0f0 (expt 2 5000)) +(test -inf.f expt -4.0f0 (add1 (expt 2 5000))) + (define (inf-non-real? x) (and (not (real? x)) (= +inf.0 (abs (imag-part x))) diff --git a/racket/src/racket/src/number.c b/racket/src/racket/src/number.c index bb20444a58..9feb28de65 100644 --- a/racket/src/racket/src/number.c +++ b/racket/src/racket/src/number.c @@ -3617,18 +3617,33 @@ scheme_expt(int argc, Scheme_Object *argv[]) } } } - } else if ((d < 0.0) && (d > -1.0)) { + } else if (SCHEME_BIGNUMP(e) && SCHEME_BIGPOS(e)) { /* If `e` is a positive bignum, then the result should be zero, but we won't get that result if conversion produces infinity */ - if (SCHEME_BIGNUMP(e) && SCHEME_BIGPOS(e)) { + double e_dbl; #ifdef MZ_USE_SINGLE_FLOATS - int sgl = !SCHEME_DBLP(n); + int sgl = !SCHEME_DBLP(n); #endif + if ((d < 0.0) && (d > -1.0)) { if (SCHEME_FALSEP(scheme_odd_p(1, &e))) return SELECT_EXPT_PRECISION(scheme_zerof, scheme_zerod); else return SELECT_EXPT_PRECISION(scheme_nzerof, scheme_nzerod); } + /* If d is negative, and `e` is a large enough bignum which would + be converted to infinity, this would return a complex NaN. + Instead, we want to return (positive of negative) infinity. + See discussion in Github issue 1148. */ + e_dbl = scheme_bignum_to_double(e); + if ((d < 0.0) && MZ_IS_POS_INFINITY(e_dbl)) { + if (SCHEME_TRUEP(scheme_odd_p(1, &e))) { + return SELECT_EXPT_PRECISION(scheme_single_minus_inf_object, + scheme_minus_inf_object); + } else { + return SELECT_EXPT_PRECISION(scheme_single_inf_object, + scheme_inf_object); + } + } } if ((d < 0.0) && SCHEME_RATIONALP(e)) { From 37c25584757a526192ea87bde52089e66afe03aa Mon Sep 17 00:00:00 2001 From: Ambrose Bonnaire-Sergeant Date: Thu, 26 Nov 2015 00:59:16 -0500 Subject: [PATCH 091/369] Fix documentation typo --- 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 6ddd1022d9..547a55de35 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -255,7 +255,7 @@ the contracts in order, from left to right.} @defproc[(not/c [flat-contract flat-contract?]) flat-contract?]{ -Accepts a flat contracts or a predicate and returns a flat contract +Accepts a flat contract or a predicate and returns a flat contract that checks the inverse of the argument.} From e24b73fbfd6f97a8ad971a4880274f38da518338 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 25 Nov 2015 11:42:32 -0700 Subject: [PATCH 092/369] minor GC simplification --- racket/src/racket/gc2/mem_account.c | 2 -- racket/src/racket/gc2/newgc.c | 11 ++--------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/racket/src/racket/gc2/mem_account.c b/racket/src/racket/gc2/mem_account.c index fb13cf1b59..803de60775 100644 --- a/racket/src/racket/gc2/mem_account.c +++ b/racket/src/racket/gc2/mem_account.c @@ -576,8 +576,6 @@ static void BTC_do_accounting(NewGC *gc) gc->old_btc_mark = gc->new_btc_mark; gc->new_btc_mark = !gc->new_btc_mark; } - - clear_stack_pages(gc); } inline static void BTC_add_account_hook(int type,void *c1,void *c2,uintptr_t b) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 95b9763c42..96360cc011 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -5666,15 +5666,6 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin zero_weak_arrays(gc, 0); zero_remaining_ephemerons(gc); -#ifndef NEWGC_BTC_ACCOUNT - /* we need to clear out the stack pages. If we're doing memory accounting, - though, we might as well leave them up for now and let the accounting - system clear them later. Better then freeing them, at least. If we're - not doing accounting, though, there is no "later" where they'll get - removed */ - clear_stack_pages(gc); -#endif - TIME_STEP("zeroed"); check_finalizers(gc, 2); @@ -5759,6 +5750,8 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (gc->gc_full || !gc->started_incremental) check_marks_cleared(gc); + clear_stack_pages(gc); + TIME_STEP("reset"); /* now we do want the allocator freaking if we go over half */ From 2486c7f4bcf67f6515b08dd380eaa65cf6ebe82b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 26 Nov 2015 06:56:56 -0700 Subject: [PATCH 093/369] incremental GC: add finalization step This step is semi-incremental, in that it can happen during incremental collection, but all finalization is performed at once. This will work well enoguh if the number of finalizers, weak boxes, etc., will be small enough relative to the heap size. --- racket/src/racket/gc2/gc2.h | 5 +- racket/src/racket/gc2/newgc.c | 177 +++++++++++++++++++++++----------- racket/src/racket/gc2/newgc.h | 8 +- racket/src/racket/gc2/weak.c | 18 ++-- 4 files changed, 137 insertions(+), 71 deletions(-) diff --git a/racket/src/racket/gc2/gc2.h b/racket/src/racket/gc2/gc2.h index db6adf9edb..9925bee0cc 100644 --- a/racket/src/racket/gc2/gc2.h +++ b/racket/src/racket/gc2/gc2.h @@ -380,8 +380,9 @@ 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 +# define GC_CURRENT_MODE_INCREMENTAL_FINAL 3 +# define GC_CURRENT_MODE_BACKPOINTER_REMARK 4 +# define GC_CURRENT_MODE_ACCOUNTING 5 /* The mode during a mark or fixup function callback. The GC_CURRENT_MODE_BACKPOINTER_REMARK mode corresponds diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 96360cc011..e5706d1749 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -2015,11 +2015,6 @@ inline static mpage *pagemap_find_page_for_marking(NewGC *gc, const void *p, int return page; } -/* This procedure fundamentally returns true if a pointer is marked, and - false if it isn't. This function assumes that you're talking, at this - point, purely about the mark field of the object. It ignores things like - the object not being one of our GC heap objects, being in a higher gen - than we're collecting, not being a pointer at all, etc. */ inline static int marked(NewGC *gc, const void *p) { mpage *page; @@ -2029,8 +2024,6 @@ inline static int marked(NewGC *gc, const void *p) if(!p) return 0; 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; case SIZE_CLASS_SMALL_PAGE: if (page->generation >= AGE_GEN_1) { if((NUM(page->addr) + page->scan_boundary) > NUM(p)) @@ -2042,7 +2035,8 @@ inline static int marked(NewGC *gc, const void *p) break; case SIZE_CLASS_BIG_PAGE: return 0; - break; + case SIZE_CLASS_BIG_PAGE_MARKED: + return 1; default: fprintf(stderr, "ABORTING! INVALID SIZE_CLASS %i\n", page->size_class); abort(); @@ -2072,9 +2066,12 @@ int GC_current_mode(struct NewGC *gc) 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 + else if (gc->inc_gen1) { + if (gc->fnl_gen1) + return GC_CURRENT_MODE_INCREMENTAL_FINAL; + else + return GC_CURRENT_MODE_INCREMENTAL; + } else return GC_CURRENT_MODE_MINOR; } @@ -2458,9 +2455,11 @@ inline static void repair_finalizer_structs(NewGC *gc) } } -inline static void check_finalizers(NewGC *gc, int level) +inline static void check_finalizers(NewGC *gc, int level, int old_gen) { - Fnl *work = GC_resolve2(gc->gen0_finalizers, gc); + Fnl *work = (old_gen + ? GC_resolve2(gc->finalizers, gc) + : GC_resolve2(gc->gen0_finalizers, gc)); Fnl *prev = NULL; GCDEBUG((DEBUGOUTF, "CFNL: Checking level %i finalizers\n", level)); @@ -2475,6 +2474,8 @@ inline static void check_finalizers(NewGC *gc, int level) gcMARK2(work->p, gc); if (prev) prev->next = next; + else if (old_gen) + gc->finalizers = next; else gc->gen0_finalizers = next; if (next) @@ -2632,6 +2633,17 @@ static void push_ptr(NewGC *gc, void *ptr, int inc_gen1) push_ptr_at(ptr, inc_gen1 ? &gc->inc_mark_stack : &gc->mark_stack); } +static int mark_stack_is_empty(MarkSegment *mark_stack) +{ + if (mark_stack->top == MARK_STACK_START(mark_stack)) { + if (mark_stack->prev) + return 0; + else + return 1; + } else + return 0; +} + inline static int pop_ptr_at(void **ptr, MarkSegment **_mark_stack) { MarkSegment *mark_stack = *_mark_stack; @@ -3988,17 +4000,17 @@ static void propagate_marks_plus_ephemerons(NewGC *gc) } while (mark_ready_ephemerons(gc, 0)); } -static void propagate_incremental_marks(NewGC *gc, int fuel) +static void propagate_incremental_marks(NewGC *gc, int do_emph, int fuel) { if (gc->inc_mark_stack) { - int save_inc, save_mark, save_check, init_fuel = fuel; + int save_inc, save_check, init_fuel = fuel; + GC_ASSERT(gc->mark_gen1); + 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 { @@ -4008,12 +4020,11 @@ static void propagate_incremental_marks(NewGC *gc, int fuel) propagate_marks_worker(gc, p, 1); fuel--; } - } while (mark_ready_ephemerons(gc, 1) && fuel); + } while (do_emph && 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; } } @@ -4114,7 +4125,7 @@ int GC_is_on_allocated_page(void *p) int GC_is_partial(struct NewGC *gc) { - return !gc->gc_full || gc->doing_memory_accounting; + return (!gc->gc_full && !gc->fnl_gen1) || gc->doing_memory_accounting; } int GC_started_incremental(struct NewGC *gc) @@ -5509,6 +5520,80 @@ extern double scheme_get_inexact_milliseconds(void); # define TIME_DONE() /**/ #endif +static void mark_and_finalize_all(NewGC *gc, int old_gen) +{ + if (!old_gen) + propagate_marks_plus_ephemerons(gc); + + check_finalizers(gc, 1, old_gen); + if (!old_gen) + propagate_marks_plus_ephemerons(gc); + else + propagate_incremental_marks(gc, 1, -1); + + TIME_STEP("marked"); + + if (old_gen) { + /* move gen1 into active positions: */ + init_weak_boxes(gc, 1); + init_weak_arrays(gc, 1); + init_ephemerons(gc, 1); + GC_ASSERT(!gc->fnl_gen1); + gc->fnl_gen1 = 1; + } + + zero_weak_boxes(gc, 0, 0); + zero_weak_arrays(gc, 0); + zero_remaining_ephemerons(gc); + + TIME_STEP("zeroed"); + + check_finalizers(gc, 2, old_gen); + if (!old_gen) + propagate_marks(gc); + else + propagate_incremental_marks(gc, 0, -1); + zero_weak_boxes(gc, 1, 0); + + check_finalizers(gc, 3, old_gen); + if (!old_gen) + propagate_marks(gc); + else + propagate_incremental_marks(gc, 0, -1); + + if (gc->GC_post_propagate_hook) + gc->GC_post_propagate_hook(gc); + + /* for any new ones that appeared: */ + zero_weak_boxes(gc, 0, 1); + zero_weak_boxes(gc, 1, 1); + zero_weak_arrays(gc, 1); + zero_remaining_ephemerons(gc); + + if (old_gen) + gc->fnl_gen1 = 0; + + TIME_STEP("finalized"); +} + +static void mark_and_finalize_all_incremental(NewGC *gc) +{ + int save_inc, save_check; + + GC_ASSERT(gc->mark_gen1); + + save_inc = gc->inc_gen1; + save_check = gc->check_gen1; + + gc->inc_gen1 = 1; + gc->check_gen1 = 1; + + mark_and_finalize_all(gc, 1); + + gc->inc_gen1 = save_inc; + gc->check_gen1 = save_check; +} + /* Full GCs trigger finalization. Finalization releases data in the old generation. So one more full GC is needed to really clean up. The full_needed_for_finalization flag triggers @@ -5626,9 +5711,9 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin move_gen_half_pages_to_old(gc); - init_weak_boxes(gc); - init_weak_arrays(gc); - init_ephemerons(gc); + init_weak_boxes(gc, gc->gc_full); + init_weak_arrays(gc, gc->gc_full); + init_ephemerons(gc, gc->gc_full); /* at this point, the page map should only include pages that contain collectable objects */ @@ -5649,45 +5734,23 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (postmaster_and_master_gc(gc)) promote_marked_gen0_big_pages(gc); #endif - TIME_STEP("stacked"); /* now propagate/repair the marks we got from these roots, and do the finalizer passes */ + mark_and_finalize_all(gc, 0); - propagate_marks_plus_ephemerons(gc); - - check_finalizers(gc, 1); - propagate_marks_plus_ephemerons(gc); - - TIME_STEP("marked"); - - zero_weak_boxes(gc, 0, 0); - zero_weak_arrays(gc, 0); - zero_remaining_ephemerons(gc); - - TIME_STEP("zeroed"); - - check_finalizers(gc, 2); - propagate_marks(gc); - zero_weak_boxes(gc, 1, 0); - - check_finalizers(gc, 3); - propagate_marks(gc); - - if (gc->GC_post_propagate_hook) - gc->GC_post_propagate_hook(gc); - - /* for any new ones that appeared: */ - zero_weak_boxes(gc, 0, 1); - zero_weak_boxes(gc, 1, 1); - zero_weak_arrays(gc, 1); - zero_remaining_ephemerons(gc); - - if (do_incremental) - propagate_incremental_marks(gc, INCREMENTAL_COLLECT_FUEL); - - TIME_STEP("finalized2"); + if (do_incremental && !gc->finishing_incremental) { + propagate_incremental_marks(gc, 1, INCREMENTAL_COLLECT_FUEL); + if (mark_stack_is_empty(gc->inc_mark_stack)) { + /* If we run out of incremental marking work, + perform major-GC finalization in one go. */ + mark_and_finalize_all_incremental(gc); + /* Plan is to switch to incrementally changing pages from `mark` bit mode + to `dead` bit mode before propagating marks again. */ + /* gc->finishing_incremental = 1; */ + } + } #if MZ_GC_BACKTRACE if (0) diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 1456f7603f..0a1cb47db0 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -200,6 +200,7 @@ typedef struct NewGC { unsigned char generations_available :1; unsigned char started_incremental :1; /* must stick with incremental until major GC */ + unsigned char finishing_incremental :1; /* finalized already */ unsigned char in_unsafe_allocation_mode :1; unsigned char full_needed_for_finalization :1; unsigned char no_further_modifications :1; @@ -208,9 +209,10 @@ 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 check_gen1 :1; /* check marks bit for old generation (insteda of claiming always marked) */ + unsigned char mark_gen1 :1; /* set mark bits for old generation */ + unsigned char inc_gen1 :1; /* during incremental marking of old generation */ + unsigned char fnl_gen1 :1; /* during incremental finalization of old generation */ unsigned char during_backpointer :1; unsigned char incremental_requested :1; diff --git a/racket/src/racket/gc2/weak.c b/racket/src/racket/gc2/weak.c index 7e4596a999..a1e65f0715 100644 --- a/racket/src/racket/gc2/weak.c +++ b/racket/src/racket/gc2/weak.c @@ -42,7 +42,7 @@ static int mark_weak_array(void *p, struct NewGC *gc) if (gc->doing_memory_accounting) { /* skip */ - } else if (gc->inc_gen1) { + } else if (gc->inc_gen1 && !gc->fnl_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; @@ -130,8 +130,8 @@ static void rechain_inc_weak_arrays(GC_Weak_Array *w) } } -static void init_weak_arrays(GCTYPE *gc) { - if (gc->gc_full) { +static void init_weak_arrays(GCTYPE *gc, int old_gen) { + if (old_gen) { rechain_inc_weak_arrays(gc->inc_weak_arrays); gc->weak_arrays = gc->inc_weak_arrays; gc->inc_weak_arrays = NULL; @@ -235,7 +235,7 @@ static int mark_weak_box(void *p, struct NewGC *gc) if (gc->doing_memory_accounting) { /* skip */ - } else if (gc->inc_gen1) { + } else if (gc->inc_gen1 && !gc->fnl_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; @@ -305,8 +305,8 @@ static void rechain_inc_weak_boxes(GC_Weak_Box *wb) } } -static void init_weak_boxes(GCTYPE *gc) { - if (gc->gc_full) { +static void init_weak_boxes(GCTYPE *gc, int old_gen) { + if (old_gen) { 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]; @@ -407,7 +407,7 @@ static int mark_ephemeron(void *p, struct NewGC *gc) if (eph->val) { GC_ASSERT(!gc->doing_memory_accounting); - if (gc->inc_gen1) { + if (gc->inc_gen1 && !gc->fnl_gen1) { eph->inc_next = gc->inc_ephemerons; gc->inc_ephemerons = eph; } else if (gc->during_backpointer) { @@ -482,8 +482,8 @@ static void rechain_inc_ephemerons(GC_Ephemeron *e) } } -void init_ephemerons(GCTYPE *gc) { - if (gc->gc_full) { +void init_ephemerons(GCTYPE *gc, int old_gen) { + if (old_gen) { rechain_inc_ephemerons(gc->inc_ephemerons); gc->ephemerons = gc->inc_ephemerons; gc->inc_ephemerons = NULL; From a0576e0378fba609178ec031aa97da748c3b6911 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 26 Nov 2015 17:06:15 -0700 Subject: [PATCH 094/369] make the clean-up phase of a major GC incremental Incremental GC now works well enough to be useful for some programs (e.g., games). Memory accounting is still not incremental, so DrRacket (and running programs in DrRacket) does not really support incremental collection, although pause times can be much shorter in incremental mode than by default. --- racket/src/racket/gc2/fnls.c | 15 +- racket/src/racket/gc2/gc2.h | 2 + racket/src/racket/gc2/mem_account.c | 5 +- racket/src/racket/gc2/newgc.c | 362 +++++++++++++++++++++------- racket/src/racket/gc2/newgc.h | 10 +- racket/src/racket/gc2/weak.c | 15 +- racket/src/racket/src/eval.c | 8 + 7 files changed, 323 insertions(+), 94 deletions(-) diff --git a/racket/src/racket/gc2/fnls.c b/racket/src/racket/gc2/fnls.c index 1eb83396f2..755d0047ee 100644 --- a/racket/src/racket/gc2/fnls.c +++ b/racket/src/racket/gc2/fnls.c @@ -186,5 +186,18 @@ static void reset_finalizer_tree(GCTYPE *gc) else add_finalizer(fnl, 0, gc); } - +} + +static void reset_gen1_finalizer_tree(GCTYPE *gc) +{ + Fnl *fnl, *next; + + fnl = gc->finalizers; + gc->finalizers = NULL; + gc->splayed_finalizers = NULL; + + for (; fnl; fnl = next) { + next = fnl->next; + add_finalizer(fnl, 0, gc); + } } diff --git a/racket/src/racket/gc2/gc2.h b/racket/src/racket/gc2/gc2.h index 9925bee0cc..19d46c00e1 100644 --- a/racket/src/racket/gc2/gc2.h +++ b/racket/src/racket/gc2/gc2.h @@ -37,6 +37,7 @@ typedef void (*GC_collect_inform_callback_Proc)(int master_gc, int major_gc, intptr_t post_child_places_used); typedef uintptr_t (*GC_get_thread_stack_base_Proc)(void); typedef void (*GC_Post_Propagate_Hook_Proc)(struct NewGC *); +typedef int (*GC_Treat_As_Incremental_Mark_Proc)(void *p); /* Types of the traversal procs (supplied by Racket); see overview in README for information about traversals. The return value is the size of @@ -119,6 +120,7 @@ GC2_EXTERN GC_collect_start_callback_Proc GC_set_collect_start_callback(GC_colle GC2_EXTERN GC_collect_end_callback_Proc GC_set_collect_end_callback(GC_collect_end_callback_Proc); GC2_EXTERN void GC_set_collect_inform_callback(GC_collect_inform_callback_Proc); GC2_EXTERN void GC_set_post_propagate_hook(GC_Post_Propagate_Hook_Proc); +GC2_EXTERN void GC_set_treat_as_incremental_mark(short tag, GC_Treat_As_Incremental_Mark_Proc); /* Sets callbacks called by GC before/after performing a collection. Used by Racket to zero out some data and record collection times. The end diff --git a/racket/src/racket/gc2/mem_account.c b/racket/src/racket/gc2/mem_account.c index 803de60775..4a5257ddb2 100644 --- a/racket/src/racket/gc2/mem_account.c +++ b/racket/src/racket/gc2/mem_account.c @@ -88,7 +88,7 @@ inline static void clean_up_thread_list(NewGC *gc) GC_Thread_Info *prev = NULL; while(work) { - if(!pagemap_find_page(gc->page_maps, work->thread) || marked(gc, work->thread)) { + if (marked(gc, work->thread)) { work->thread = GC_resolve2(work->thread, gc); prev = work; work = work->next; @@ -531,6 +531,9 @@ static void BTC_do_accounting(NewGC *gc) int owner = custodian_to_owner_set(gc, cur); uintptr_t save_count = gc->phantom_count; + GC_ASSERT(owner >= 0); + GC_ASSERT(owner <= gc->owner_table_size); + gc->phantom_count = 0; gc->current_mark_owner = owner; diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index e5706d1749..f46ec13c8f 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -242,6 +242,10 @@ MAYBE_UNUSED static void GCVERBOSEprintf(NewGC *gc, const char *fmt, ...) { full collection. */ #define FULL_COLLECTION_SIZE_RATIO 2 +/* Extra factor allowed before forcing a non-incremental full collection + when incremental model is started: */ +#define INCREMENTAL_EXTRA_SIZE_RATIO 1.5 + /* 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: */ @@ -249,7 +253,8 @@ MAYBE_UNUSED static void GCVERBOSEprintf(NewGC *gc, const char *fmt, ...) { /* Incremental mode */ #define ALWAYS_COLLECT_INCREMENTAL_ON_MINOR 0 -#define INCREMENTAL_COLLECT_FUEL (16 * 1024) +#define INCREMENTAL_COLLECT_FUEL_PER_100M (24 * 1024) +#define INCREMENTAL_REPAIR_FUEL_PER_100M 512 /* Conservatively force a major GC after a certain number of minor GCs. It should be ok to set this value @@ -307,6 +312,12 @@ void GC_set_collect_inform_callback(GC_collect_inform_callback_Proc func) { gc->GC_collect_inform_callback = func; } +void GC_set_treat_as_incremental_mark(short tag, GC_Treat_As_Incremental_Mark_Proc func) { + NewGC *gc = GC_get_GC(); + gc->treat_as_incremental_mark_hook = func; + gc->treat_as_incremental_mark_tag = tag; +} + void GC_set_post_propagate_hook(GC_Post_Propagate_Hook_Proc func) { NewGC *gc = GC_get_GC(); gc->GC_post_propagate_hook = func; @@ -2025,13 +2036,18 @@ inline static int marked(NewGC *gc, const void *p) if(!(page = pagemap_find_page_for_marking(gc, p, gc->check_gen1))) return 1; switch(page->size_class) { case SIZE_CLASS_SMALL_PAGE: - if (page->generation >= AGE_GEN_1) { - if((NUM(page->addr) + page->scan_boundary) > NUM(p)) + if ((page->generation >= AGE_GEN_1) && !gc->inc_gen1) { + if ((NUM(page->addr) + page->scan_boundary) > NUM(p)) return 1; } /* else FALLTHROUGH */ case SIZE_CLASS_MED_PAGE: /* FALLTHROUGH */ - return OBJPTR_TO_OBJHEAD(p)->mark; + if (page->non_dead_as_mark) { + /* Shouldn't reference a dead object! */ + GC_ASSERT(!OBJPTR_TO_OBJHEAD(p)->dead); + return 1; + } else + return OBJPTR_TO_OBJHEAD(p)->mark; break; case SIZE_CLASS_BIG_PAGE: return 0; @@ -2410,27 +2426,42 @@ static int is_finalizable_page(NewGC *gc, void *p) #include "fnls.c" -inline static void mark_finalizer_structs(NewGC *gc) +inline static void mark_finalizer_structs(NewGC *gc, int old_gen) { Fnl *fnl; set_backtrace_source(gc, &gc->gen0_finalizers, BT_ROOT); - gcMARK2(gc->gen0_finalizers, gc); - for(fnl = gc->gen0_finalizers; fnl; fnl = fnl->next) { + if (old_gen) + gcMARK2(gc->finalizers, gc); + else + gcMARK2(gc->gen0_finalizers, gc); + for(fnl = (old_gen ? gc->finalizers : gc->gen0_finalizers); fnl; fnl = fnl->next) { set_backtrace_source(gc, fnl, BT_FINALIZER); gcMARK2(fnl->data, gc); set_backtrace_source(gc, &gc->gen0_finalizers, BT_ROOT); gcMARK2(fnl->next, 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->gen0_finalizers, BT_ROOT); - gcMARK2(fnl->next, gc); + + if (!old_gen) { + 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->run_queue, BT_ROOT); + gcMARK2(fnl->next, gc); + } + + set_backtrace_source(gc, &gc->inc_run_queue, BT_ROOT); + gcMARK2(gc->inc_run_queue, gc); + for(fnl = gc->inc_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->inc_run_queue, BT_ROOT); + gcMARK2(fnl->next, gc); + } } } @@ -2441,6 +2472,9 @@ inline static void repair_finalizer_structs(NewGC *gc) /* repair the base parts of the list */ gcFIXUP2(gc->gen0_finalizers, gc); gcFIXUP2(gc->run_queue, gc); + gcFIXUP2(gc->last_in_queue, gc); + gcFIXUP2(gc->inc_run_queue, gc); + gcFIXUP2(gc->inc_last_in_queue, gc); /* then repair the stuff inside them */ for(fnl = gc->gen0_finalizers; fnl; fnl = fnl->next) { gcFIXUP2(fnl->data, gc); @@ -2453,6 +2487,23 @@ inline static void repair_finalizer_structs(NewGC *gc) gcFIXUP2(fnl->p, gc); gcFIXUP2(fnl->next, gc); } + for(fnl = gc->inc_run_queue; fnl; fnl = fnl->next) { + gcFIXUP2(fnl->data, gc); + gcFIXUP2(fnl->p, gc); + gcFIXUP2(fnl->next, gc); + } +} + +static void merge_run_queues(NewGC *gc) +{ + if (gc->inc_run_queue) { + gc->inc_last_in_queue->next = gc->run_queue; + gc->run_queue = gc->inc_run_queue; + if (!gc->last_in_queue) + gc->last_in_queue = gc->inc_last_in_queue; + gc->inc_run_queue = NULL; + gc->inc_last_in_queue = NULL; + } } inline static void check_finalizers(NewGC *gc, int level, int old_gen) @@ -2483,10 +2534,17 @@ inline static void check_finalizers(NewGC *gc, int level, int old_gen) work->prev = NULL; /* queue is singly-linked */ work->left = NULL; work->right = NULL; - if (gc->last_in_queue) - gc->last_in_queue = gc->last_in_queue->next = work; - else - gc->run_queue = gc->last_in_queue = work; + if (old_gen) { + if (gc->inc_last_in_queue) + gc->inc_last_in_queue = gc->inc_last_in_queue->next = work; + else + gc->inc_run_queue = gc->inc_last_in_queue = work; + } else { + if (gc->last_in_queue) + gc->last_in_queue = gc->last_in_queue->next = work; + else + gc->run_queue = gc->last_in_queue = work; + } work->next = NULL; --gc->num_fnls; @@ -2635,7 +2693,9 @@ static void push_ptr(NewGC *gc, void *ptr, int inc_gen1) static int mark_stack_is_empty(MarkSegment *mark_stack) { - if (mark_stack->top == MARK_STACK_START(mark_stack)) { + if (!mark_stack) + return 1; + else if (mark_stack->top == MARK_STACK_START(mark_stack)) { if (mark_stack->prev) return 0; else @@ -2838,8 +2898,25 @@ static inline void propagate_marks_worker(NewGC *gc, void *pp, int inc_gen1); #ifdef NEWGC_BTC_ACCOUNT # include "mem_account.c" -#else -# define clean_up_thread_list() /* */ + +static void BTC_clean_up_gen1(NewGC *gc) +{ + if (gc->started_incremental && !gc->gc_full) { + /* Need to check marked() for old generation, too */ + GC_ASSERT(!gc->check_gen1); + GC_ASSERT(!gc->inc_gen1); + gc->check_gen1 = 1; + gc->inc_gen1 = 1; + } + + BTC_clean_up(gc); + + if (gc->started_incremental && !gc->gc_full) { + gc->check_gen1 = 0; + gc->inc_gen1 = 0; + } +} + #endif void GC_register_root_custodian(void *c) @@ -3258,7 +3335,6 @@ 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; @@ -3553,7 +3629,7 @@ static void check_incremental_unprotect(NewGC *gc, mpage *page) 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 */ + page->reprotect = 1; } } @@ -3722,6 +3798,14 @@ void GC_mark2(void *pp, struct NewGC *gc) int inc_gen1; if (info->mark) { GCDEBUG((DEBUGOUTF,"Not marking %p (already marked)\n", p)); + GC_ASSERT(!page->non_dead_as_mark); + RELEASE_PAGE_LOCK(is_a_master_page, page); + return; + } + if (page->non_dead_as_mark) { + GC_ASSERT(gc->mark_gen1); + GC_ASSERT(page->generation >= AGE_GEN_1); + GC_ASSERT(!info->dead); RELEASE_PAGE_LOCK(is_a_master_page, page); return; } @@ -3750,6 +3834,7 @@ void GC_mark2(void *pp, struct NewGC *gc) if(ohead->mark) { GCDEBUG((DEBUGOUTF,"Not marking %p (already marked)\n", p)); + GC_ASSERT(!page->non_dead_as_mark); RELEASE_PAGE_LOCK(is_a_master_page, page); if (ohead->moved) *(void **)pp = *(void **)p; @@ -3765,6 +3850,14 @@ void GC_mark2(void *pp, struct NewGC *gc) is add the pointer to the mark queue and note on the page that we marked something on it */ int inc_gen1; + if (page->non_dead_as_mark) { + GC_ASSERT(gc->mark_gen1); + GC_ASSERT(page->generation >= AGE_GEN_1); + GC_ASSERT(!ohead->dead); + GC_ASSERT(!ohead->moved); + RELEASE_PAGE_LOCK(is_a_master_page, page); + return; + } if ((NUM(page->addr) + page->scan_boundary) <= NUM(p)) { GC_ASSERT(!gc->inc_gen1); GCDEBUG((DEBUGOUTF, "Marking %p (leaving alone)\n", p)); @@ -3822,7 +3915,8 @@ void GC_mark2(void *pp, struct NewGC *gc) work = gc->gen1_pages[type]; /* search for a page with the space to spare */ - if (work && ((work->size + size) >= APAGE_SIZE)) + if (work && (((work->size + size) >= APAGE_SIZE) + || work->non_dead_as_mark)) work = NULL; /* now either fetch where we're going to put this object or make @@ -4083,7 +4177,7 @@ void GC_fixup2(void *pp, struct NewGC *gc) if (!p || (NUM(p) & 0x1)) return; - page = pagemap_find_page_for_marking(gc, p, gc->mark_gen1); + page = pagemap_find_page_for_marking(gc, p, gc->check_gen1); if (page) { objhead *info; @@ -4540,9 +4634,14 @@ static void mark_backpointers(NewGC *gc) while (start < end) { objhead *info = (objhead *)start; if (!info->dead) { - if (info->mark) + if (info->mark || work->non_dead_as_mark) mark_traverse_object(gc, PPTR(OBJHEAD_TO_OBJPTR(start)), PPTR(info) + info->size, info->type); - else if (!gc->gc_full) + else if (!gc->gc_full + /* Totally ad hoc; supports closure prefixes */ + || ((info->type == PAGE_TAGGED) + && gc->treat_as_incremental_mark_hook + && (gc->treat_as_incremental_mark_tag == *(short *)OBJHEAD_TO_OBJPTR(start)) + && gc->treat_as_incremental_mark_hook(OBJHEAD_TO_OBJPTR(start)))) mark_traverse_object_no_gen1(gc, PPTR(OBJHEAD_TO_OBJPTR(start)), PPTR(info) + info->size, info->type); } start += info->size; @@ -4558,7 +4657,7 @@ static void mark_backpointers(NewGC *gc) while (start <= end) { objhead *info = (objhead *)start; if (!info->dead) { - if (info->mark) + if (info->mark || work->non_dead_as_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); @@ -4598,6 +4697,7 @@ static void mark_backpointers(NewGC *gc) } gc->inc_modified_next = NULL; + gc->inc_repair_next = NULL; } gc->during_backpointer = 0; @@ -4696,6 +4796,8 @@ inline static void do_heap_compact(NewGC *gc) avail = gcBYTES_TO_WORDS(APAGE_SIZE - npage->size); newplace = PPTR(NUM(npage->addr) + npage->size); + GC_ASSERT(!work->non_dead_as_mark); + while (start < end) { objhead *info = (objhead *)start; @@ -4843,6 +4945,7 @@ static int unmark_range(void **start, void **end) objhead *info = (objhead *)start; if (info->mark) { + GC_ASSERT(!info->dead); info->mark = 0; live_size += info->size; } else @@ -4970,7 +5073,7 @@ static void repair_heap(NewGC *gc) memory_in_use += page->size; } else if (page->size_class == SIZE_CLASS_SMALL_PAGE) { - int need_unmark = 0; + int need_unmark = 0, need_fixup_now = need_fixup; /* ------ small page ------ */ if (minor_for_incremental) { /* leave marks as-is */ @@ -4983,16 +5086,21 @@ static void repair_heap(NewGC *gc) 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 (!page->non_dead_as_mark) { + 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 = !page->non_dead_as_mark; + if (!need_unmark && !page->back_pointers) + need_fixup_now = 0; + } + page->non_dead_as_mark = 0; } - if (need_fixup) { + if (need_fixup_now) { /* fixup should walk the full page: */ void **start = PPTR(NUM(page->addr) + PREFIX_SIZE); void **end = PAGE_END_VSS(page); @@ -5082,7 +5190,7 @@ static void repair_heap(NewGC *gc) break; } - if (page->page_type != PAGE_ATOMIC) + if (need_unmark && (page->page_type != PAGE_ATOMIC)) page->live_size = live_size; } @@ -5092,6 +5200,7 @@ static void repair_heap(NewGC *gc) memory_in_use += page->size; } else { /* ------ medium page ------ */ + int need_fixup_now = need_fixup; GC_ASSERT(page->size_class == SIZE_CLASS_MED_PAGE); if (minor_for_incremental) { @@ -5110,14 +5219,19 @@ static void repair_heap(NewGC *gc) } } 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 (!page->non_dead_as_mark) { + 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; + } else { + need_fixup_now = page->back_pointers; + page->non_dead_as_mark = 0; + } } } - if (need_fixup) + if (need_fixup_now) repair_mixed_page(gc, page, PPTR(NUM(page->addr) + APAGE_SIZE - page->obj_size)); memory_in_use += page->live_size; @@ -5145,6 +5259,7 @@ static void repair_heap(NewGC *gc) } else { page->reprotect_next = gc->reprotect_next; gc->reprotect_next = page; + page->reprotect = 1; } } } @@ -5163,7 +5278,6 @@ static void repair_heap(NewGC *gc) 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 @@ -5214,6 +5328,49 @@ static void repair_heap(NewGC *gc) #endif } +static void incremental_repair_pages(NewGC *gc, int fuel) +{ + mpage *page; + +#if 0 + /* Make sure `gc->inc_repair_next` is a tail of `gc->inc_modified_next` */ + for (page = gc->inc_modified_next; page != gc->inc_repair_next; page = page->inc_modified_next) { + } + GC_ASSERT(page == gc->inc_repair_next); +#endif + + while (fuel && gc->inc_repair_next) { + page = gc->inc_repair_next; + gc->inc_repair_next = page->inc_modified_next; + GC_ASSERT(page->generation >= AGE_GEN_1); + if (page->generation == AGE_VACATED) { + /* skip */ + } else if (page->size_class >= SIZE_CLASS_BIG_PAGE) { + /* skip */ + } else { + if (page->non_dead_as_mark) { + /* hit already-repaired tail; no more to repair */ + gc->inc_repair_next = NULL; + } else { + int live_size; + check_incremental_unprotect(gc, page); + if (page->size_class == SIZE_CLASS_SMALL_PAGE) { + GC_ASSERT(page->scan_boundary == page->size); + live_size = unmark_range(PPTR(NUM(page->addr) + PREFIX_SIZE), + PAGE_END_VSS(page)); + } else { + GC_ASSERT(page->size_class == SIZE_CLASS_MED_PAGE); + live_size = unmark_range(PPTR(NUM(page->addr) + PREFIX_SIZE), + PPTR(NUM(page->addr) + APAGE_SIZE - page->obj_size)); + } + page->live_size = live_size; + page->non_dead_as_mark = 1; + --fuel; + } + } + } +} + static inline void cleanup_vacated_pages(NewGC *gc) { mpage *pages = gc->release_pages; PageMap pagemap = gc->page_maps; @@ -5376,6 +5533,12 @@ static void unprotect_old_pages(NewGC *gc) } mmu_flush_write_unprotect_ranges(mmu); + + /* Clear out ignored list of reprotects */ + for (page = gc->reprotect_next; page; page = page->reprotect_next) { + page->reprotect = 0; + } + gc->reprotect_next = NULL; } #endif @@ -5395,8 +5558,10 @@ static void protect_old_pages(NewGC *gc) 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) + if (!page->mprotected) { count++; + GC_ASSERT(page->reprotect); + } } } } @@ -5404,8 +5569,10 @@ static void protect_old_pages(NewGC *gc) 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) + if (!page->mprotected) { count++; + GC_ASSERT(page->reprotect); + } } } @@ -5508,19 +5675,23 @@ 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_DECLS() double start, task_start, *_task_start = &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_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() if (SHOW_TIME_NOW) fprintf(stderr, " Total: %lf\n", scheme_get_inexact_milliseconds() - start) +# define TIME_FORMAL_ARGS , double start, double *_task_start +# define TIME_ARGS , start, _task_start #else # define TIME_DECLS() /**/ # define TIME_INIT() /**/ # define TIME_STEP(task) /**/ # define TIME_DONE() /**/ +# define TIME_FORMAL_ARGS /**/ +# define TIME_ARGS /**/ #endif -static void mark_and_finalize_all(NewGC *gc, int old_gen) +static void mark_and_finalize_all(NewGC *gc, int old_gen TIME_FORMAL_ARGS) { if (!old_gen) propagate_marks_plus_ephemerons(gc); @@ -5576,7 +5747,7 @@ static void mark_and_finalize_all(NewGC *gc, int old_gen) TIME_STEP("finalized"); } -static void mark_and_finalize_all_incremental(NewGC *gc) +static void mark_and_finalize_all_incremental(NewGC *gc TIME_FORMAL_ARGS) { int save_inc, save_check; @@ -5588,7 +5759,7 @@ static void mark_and_finalize_all_incremental(NewGC *gc) gc->inc_gen1 = 1; gc->check_gen1 = 1; - mark_and_finalize_all(gc, 1); + mark_and_finalize_all(gc, 1 TIME_ARGS); gc->inc_gen1 = save_inc; gc->check_gen1 = save_check; @@ -5605,7 +5776,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin uintptr_t old_gen0; uintptr_t old_mem_allocated; int next_gc_full; - int do_incremental = 0; + int do_incremental = 0, check_inc_repair; old_mem_use = gc->memory_in_use; /* includes gc->phantom_count */ old_gen0 = gc->gen0.current_size + gc->gen0_phantom_count; @@ -5622,21 +5793,21 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin 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)) + || (gc->memory_in_use > (FULL_COLLECTION_SIZE_RATIO + * gc->last_full_mem_use + * (gc->started_incremental + ? INCREMENTAL_EXTRA_SIZE_RATIO + : 1))) /* 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. */ + /* In incremental mode, GC earlier if we've done everything + that we can do 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))))); + && mark_stack_is_empty(gc->inc_mark_stack) + && gc->finishing_incremental + && !gc->inc_repair_next)); if (gc->gc_full && no_full) { return; @@ -5723,7 +5894,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin /* mark and repair the roots for collection */ mark_backpointers(gc); TIME_STEP("backpointered"); - mark_finalizer_structs(gc); + mark_finalizer_structs(gc, 0); TIME_STEP("pre-rooted"); mark_roots(gc); mark_immobiles(gc); @@ -5738,20 +5909,30 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin /* now propagate/repair the marks we got from these roots, and do the finalizer passes */ - mark_and_finalize_all(gc, 0); - - if (do_incremental && !gc->finishing_incremental) { - propagate_incremental_marks(gc, 1, INCREMENTAL_COLLECT_FUEL); - if (mark_stack_is_empty(gc->inc_mark_stack)) { - /* If we run out of incremental marking work, - perform major-GC finalization in one go. */ - mark_and_finalize_all_incremental(gc); - /* Plan is to switch to incrementally changing pages from `mark` bit mode - to `dead` bit mode before propagating marks again. */ - /* gc->finishing_incremental = 1; */ - } - } + mark_and_finalize_all(gc, 0 TIME_ARGS); + if (do_incremental) { + if (!gc->finishing_incremental) { + int fuel = INCREMENTAL_COLLECT_FUEL_PER_100M * ((gc->memory_in_use / (1024 * 1024 * 100)) + 1); + mark_finalizer_structs(gc, 1); + propagate_incremental_marks(gc, 1, fuel); + if (mark_stack_is_empty(gc->inc_mark_stack)) { + /* If we run out of incremental marking work, + perform major-GC finalization in one go. */ + mark_and_finalize_all_incremental(gc TIME_ARGS); + BTC_clean_up_gen1(gc); + reset_gen1_finalizer_tree(gc); + /* Switch to incrementally reparing pages before propagating + marks again. */ + gc->finishing_incremental = 1; + gc->inc_repair_next = gc->inc_modified_next; + } + check_inc_repair = 0; + } else + check_inc_repair = 1; + } else + check_inc_repair = 0; + #if MZ_GC_BACKTRACE if (0) #endif @@ -5779,10 +5960,23 @@ 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); + repair_heap(gc); TIME_STEP("repaired"); + if (check_inc_repair) { + if (!gc->inc_repair_next) { + /* Didn't fire a full GC? Go back to incremental marking: */ + gc->finishing_incremental = 0; + } else { + int fuel = INCREMENTAL_REPAIR_FUEL_PER_100M * ((gc->memory_in_use / (1024 * 1024 * 100)) + 1); + incremental_repair_pages(gc, fuel); + TIME_STEP("inc-repaired"); + } + } + clean_up_heap(gc); TIME_STEP("cleaned heap"); + clean_gen_half(gc); #ifdef MZ_USE_PLACES if (postmaster_and_master_gc(gc) && !switching_master) { @@ -5797,6 +5991,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin BTC_do_accounting(gc); #endif TIME_STEP("accounted"); + if (gc->generations_available) { #ifdef MZ_USE_PLACES if (postmaster_and_master_gc(gc) || switching_master) @@ -5806,6 +6001,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin protect_old_pages(gc); } TIME_STEP("protect"); + if (gc->gc_full) mmu_flush_freed_pages(gc->mmu); reset_finalizer_tree(gc); @@ -5844,11 +6040,6 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin } 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; } @@ -5886,6 +6077,9 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin dump_page_map(gc, "post"); + if (gc->gc_full) + merge_run_queues(gc); + if (!gc->run_queue) next_gc_full = 0; diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 0a1cb47db0..ae71bd8521 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -50,6 +50,7 @@ typedef struct mpage { unsigned char has_new :1; unsigned char mprotected :1; unsigned char reprotect :1; /* in reprotect_next chain already */ + unsigned char non_dead_as_mark :1; /* already repaired in incremental pass */ } mpage; typedef struct Gen0 { @@ -168,6 +169,8 @@ typedef struct NewGC { struct mpage *modified_next; /* pages marked incrementally: */ struct mpage *inc_modified_next; + /* tail of inc_modified_next being repaired incrementally */ + struct mpage *inc_repair_next; /* linked list of pages that need to be given write protection at the end of the GC cycle: */ struct mpage *reprotect_next; @@ -175,8 +178,8 @@ typedef struct NewGC { MarkSegment *mark_stack, *inc_mark_stack; /* Finalization */ - Fnl *run_queue; - Fnl *last_in_queue; + Fnl *run_queue, *last_in_queue; + Fnl *inc_run_queue, *inc_last_in_queue; int mark_depth; @@ -233,7 +236,6 @@ 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; @@ -269,6 +271,8 @@ typedef struct NewGC { GC_collect_inform_callback_Proc GC_collect_inform_callback; uintptr_t (*GC_get_thread_stack_base)(void); GC_Post_Propagate_Hook_Proc GC_post_propagate_hook; + GC_Treat_As_Incremental_Mark_Proc treat_as_incremental_mark_hook; + short treat_as_incremental_mark_tag; GC_Immobile_Box *immobile_boxes; diff --git a/racket/src/racket/gc2/weak.c b/racket/src/racket/gc2/weak.c index a1e65f0715..3c1ce2c29e 100644 --- a/racket/src/racket/gc2/weak.c +++ b/racket/src/racket/gc2/weak.c @@ -130,14 +130,15 @@ static void rechain_inc_weak_arrays(GC_Weak_Array *w) } } -static void init_weak_arrays(GCTYPE *gc, int old_gen) { +static void init_weak_arrays(GCTYPE *gc, int old_gen) +{ + GC_ASSERT(!gc->bp_weak_arrays); if (old_gen) { 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) @@ -305,7 +306,10 @@ static void rechain_inc_weak_boxes(GC_Weak_Box *wb) } } -static void init_weak_boxes(GCTYPE *gc, int old_gen) { +static void init_weak_boxes(GCTYPE *gc, int old_gen) +{ + GC_ASSERT(!gc->bp_weak_boxes[0]); + GC_ASSERT(!gc->bp_weak_boxes[1]); if (old_gen) { rechain_inc_weak_boxes(gc->inc_weak_boxes[0]); rechain_inc_weak_boxes(gc->inc_weak_boxes[1]); @@ -317,8 +321,6 @@ static void init_weak_boxes(GCTYPE *gc, int old_gen) { 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) @@ -367,6 +369,9 @@ 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); + page->reprotect_next = gc->reprotect_next; + gc->reprotect_next = page; + page->reprotect = 1; } p = (void **)GC_resolve2(wb->secondary_erase, gc); *(p + wb->soffset) = NULL; diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index 917192591c..3e61decd80 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -272,6 +272,7 @@ void scheme_escape_to_continuation(Scheme_Object *obj, int num_rands, Scheme_Obj #ifdef MZ_PRECISE_GC static void mark_pruned_prefixes(struct NewGC *gc); +static int check_pruned_prefix(void *p); #endif #define cons(x,y) scheme_make_pair(x,y) @@ -414,6 +415,7 @@ void scheme_init_eval_places() 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); + GC_set_treat_as_incremental_mark(scheme_prefix_type, check_pruned_prefix); #endif #ifdef DEBUG_CHECK_STACK_FRAME_SIZE (void)scheme_do_eval(SCHEME_TAIL_CALL_WAITING, 0, NULL, 0); @@ -6189,6 +6191,12 @@ static void mark_pruned_prefixes(struct NewGC *gc) XFORM_SKIP_PROC } } } + +int check_pruned_prefix(void *p) XFORM_SKIP_PROC +{ + Scheme_Prefix *pf = (Scheme_Prefix *)p; + return SCHEME_PREFIX_FLAGS(pf) & 0x1; +} #endif /*========================================================================*/ From ba8103bbde441e38df8dce16e6cbfd36f72c1ce0 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 27 Nov 2015 07:51:44 -0700 Subject: [PATCH 095/369] add PLT_INCREMENTAL_GC Although calling `(collect-garbage 'incremental)` in a program with a periodic task is the best way to request incremental collection, it's handy for some experiments to have an environment variable that turns it on permanently. This change also makes incremental-mode minor collections log as "mIn" instead of "min", and it changes the first field of the logged `gc-info` structure to be a mode symbol instead of a boolean. --- .../scribblings/reference/memory.scrbl | 34 ++++++++++++++----- racket/src/racket/cmdline.inc | 3 ++ racket/src/racket/gc2/gc2.h | 6 +++- racket/src/racket/gc2/newgc.c | 13 ++++--- racket/src/racket/include/mzwin.def | 1 + racket/src/racket/include/mzwin3m.def | 1 + racket/src/racket/include/racket.exp | 1 + racket/src/racket/include/racket3m.exp | 1 + racket/src/racket/src/salloc.c | 7 ++++ 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/thread.c | 10 +++--- 14 files changed, 63 insertions(+), 18 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/memory.scrbl b/pkgs/racket-doc/scribblings/reference/memory.scrbl index 740124e485..b91df7dc20 100644 --- a/pkgs/racket-doc/scribblings/reference/memory.scrbl +++ b/pkgs/racket-doc/scribblings/reference/memory.scrbl @@ -199,7 +199,11 @@ execution. Otherwise, @racket[#f] is returned.} @section[#:tag "garbagecollection"]{Garbage Collection} Set the @as-index{@envvar{PLTDISABLEGC}} environment variable (to any -value) before Racket starts to disable @tech{garbage collection}. +value) before Racket starts to disable @tech{garbage collection}. Set +the @as-index{@envvar{PLT_INCREMENTAL_GC}} environment variable to +request incremental mode at all times, but calling +@racket[(collect-garbage 'incremental)] in a program with a periodic +task is generally a better mechanism for requesting incremental mode. In Racket 3m (the main variant of Racket), each garbage collection logs a message (see @secref["logging"]) at the @racket['debug] level with topic @racket['GC]. @@ -209,18 +213,28 @@ versions of Racket may use a @racket[gc-info] @tech{prefab} structure with additional fields: @racketblock[ -(struct gc-info (major? pre-amount pre-admin-amount code-amount - post-amount post-admin-amount - start-process-time end-process-time - start-time end-time) +(struct gc-info (mode pre-amount pre-admin-amount code-amount + post-amount post-admin-amount + start-process-time end-process-time + start-time end-time) #:prefab) ] @itemlist[ - @item{The @racket[major?] field indicates whether the collection was - a ``major'' collection that inspects all memory or a ``minor'' - collection that mostly inspects just recent allocations.} + @item{The @racket[mode] field is a symbol @racket['major], + @racket['minor], or @racket['incremental]; @racket['major] + indicates a collection that inspects all memory, + @racket['minor] indicates collection that mostly inspects just + recent allocations, and @racket['incremental] indicates a minor + collection that performs extra work toward the next major + collection. + + @history[#:changed "6.3.0.7" @elem{Changed first field from a + boolean (@racket[#t] for + @racket['major], @racket[#f] + for @racket['minor]) to a + mode symbol.}]} @item{The @racket[pre-amount] field reports place-local memory use (i.e., not counting the memory use of child places) in bytes at @@ -286,6 +300,7 @@ collection mode, the text has the format @elem{Processor time since startup of garbage collection's start})) ]} +@history[#:changed "6.3.0.7" @elem{Added @envvar{PLT_INCREMENTAL_GC}.}] @defproc[(collect-garbage [request (or/c 'major 'minor 'incremental) 'major]) void?]{ @@ -314,7 +329,8 @@ garbage-collection mode, depending on @racket[request]: major collections any sooner than they would occur otherwise.} @item{@racket['incremental] --- Requests that each minor - collection performs incremental work toward a major collection. + collection performs incremental work toward a major collection + (but does not request an immediate minor collection). This incremental-mode request expires at the next major collection. diff --git a/racket/src/racket/cmdline.inc b/racket/src/racket/cmdline.inc index ba53a222b3..4e0a5914ef 100644 --- a/racket/src/racket/cmdline.inc +++ b/racket/src/racket/cmdline.inc @@ -1542,6 +1542,9 @@ static int run_from_cmd_line(int argc, char *_argv[], if (getenv("PLTDISABLEGC")) { scheme_enable_garbage_collection(0); } + if (getenv("PLT_INCREMENTAL_GC")) { + scheme_incremental_garbage_collection(1); + } #endif scheme_set_logging_spec(syslog_level, stderr_level); diff --git a/racket/src/racket/gc2/gc2.h b/racket/src/racket/gc2/gc2.h index 19d46c00e1..f5e6d68bdc 100644 --- a/racket/src/racket/gc2/gc2.h +++ b/racket/src/racket/gc2/gc2.h @@ -31,7 +31,7 @@ typedef int (*Fixup_Proc)(void *obj); typedef int (*Fixup2_Proc)(void *obj, struct NewGC *); typedef void (*GC_collect_start_callback_Proc)(void); typedef void (*GC_collect_end_callback_Proc)(void); -typedef void (*GC_collect_inform_callback_Proc)(int master_gc, int major_gc, +typedef void (*GC_collect_inform_callback_Proc)(int master_gc, int major_gc, int inc_gc, intptr_t pre_used, intptr_t post_used, intptr_t pre_admin, intptr_t post_admin, intptr_t post_child_places_used); @@ -174,6 +174,10 @@ GC2_EXTERN void GC_request_incremental_mode(void); /* Requests incremental mode; lasts until the next major collection. */ +GC2_EXTERN void GC_set_incremental_mode(int on); +/* + Sets whether incremental mode is the default. */ + GC2_EXTERN void GC_free_all(void); /* Releases all memory, removes all signal handlers, etc. diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index f46ec13c8f..45cb73cf02 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -252,7 +252,7 @@ MAYBE_UNUSED static void GCVERBOSEprintf(NewGC *gc, const char *fmt, ...) { #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 +static int always_collect_incremental_on_minor = 0; #define INCREMENTAL_COLLECT_FUEL_PER_100M (24 * 1024) #define INCREMENTAL_REPAIR_FUEL_PER_100M 512 @@ -3558,6 +3558,11 @@ void GC_request_incremental_mode(void) gc->incremental_requested = 1; } +void GC_set_incremental_mode(int on) +{ + always_collect_incremental_on_minor = 1; +} + void GC_enable_collection(int on) { NewGC *gc = GC_get_GC(); @@ -5847,7 +5852,7 @@ 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)); + || always_collect_incremental_on_minor)); if (!postmaster_and_place_gc(gc)) do_incremental = 0; @@ -6053,7 +6058,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin is_master = (gc == MASTERGC); #endif park_for_inform_callback(gc); - gc->GC_collect_inform_callback(is_master, gc->gc_full, + gc->GC_collect_inform_callback(is_master, gc->gc_full, do_incremental, old_mem_use + old_gen0, gc->memory_in_use, old_mem_allocated, mmu_memory_allocated(gc->mmu)+gc->phantom_count, gc->child_gc_total); @@ -6135,7 +6140,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (sub_lmi.ran) { if (gc->GC_collect_inform_callback) { park_for_inform_callback(gc); - gc->GC_collect_inform_callback(1, sub_lmi.full, + gc->GC_collect_inform_callback(1, sub_lmi.full, 0, sub_lmi.pre_used, sub_lmi.post_used, sub_lmi.pre_admin, sub_lmi.post_admin, 0); diff --git a/racket/src/racket/include/mzwin.def b/racket/src/racket/include/mzwin.def index f76f16ac0f..ede22b69ab 100644 --- a/racket/src/racket/include/mzwin.def +++ b/racket/src/racket/include/mzwin.def @@ -226,6 +226,7 @@ EXPORTS scheme_collect_garbage scheme_collect_garbage_minor scheme_enable_garbage_collection + scheme_incremental_garbage_collection scheme_malloc_immobile_box scheme_free_immobile_box scheme_add_gc_callback diff --git a/racket/src/racket/include/mzwin3m.def b/racket/src/racket/include/mzwin3m.def index 844b694200..8cada188d5 100644 --- a/racket/src/racket/include/mzwin3m.def +++ b/racket/src/racket/include/mzwin3m.def @@ -234,6 +234,7 @@ EXPORTS scheme_collect_garbage scheme_collect_garbage_minor scheme_enable_garbage_collection + scheme_incremental_garbage_collection GC_variable_stack GC_register_traversers GC_resolve diff --git a/racket/src/racket/include/racket.exp b/racket/src/racket/include/racket.exp index 831814d7b4..3cf3a31ea3 100644 --- a/racket/src/racket/include/racket.exp +++ b/racket/src/racket/include/racket.exp @@ -237,6 +237,7 @@ scheme_gc_ptr_ok scheme_collect_garbage scheme_collect_garbage_minor scheme_enable_garbage_collection +scheme_incremental_garbage_collection GC_register_traversers GC_resolve GC_mark diff --git a/racket/src/racket/include/racket3m.exp b/racket/src/racket/include/racket3m.exp index 84d9b9c58f..b20a398a31 100644 --- a/racket/src/racket/include/racket3m.exp +++ b/racket/src/racket/include/racket3m.exp @@ -241,6 +241,7 @@ scheme_gc_ptr_ok scheme_collect_garbage scheme_collect_garbage_minor scheme_enable_garbage_collection +scheme_incremental_garbage_collection GC_variable_stack GC_register_traversers GC_resolve diff --git a/racket/src/racket/src/salloc.c b/racket/src/racket/src/salloc.c index 2c449cba8a..5ecfc0377b 100644 --- a/racket/src/racket/src/salloc.c +++ b/racket/src/racket/src/salloc.c @@ -1658,6 +1658,13 @@ void scheme_enable_garbage_collection(int on) #endif } +void scheme_incremental_garbage_collection(int on) +{ +#ifdef MZ_PRECISE_GC + GC_set_incremental_mode(on); +#endif +} + MZ_DO_NOT_INLINE(uintptr_t scheme_get_deeper_address(void)); uintptr_t scheme_get_deeper_address(void) diff --git a/racket/src/racket/src/schemef.h b/racket/src/racket/src/schemef.h index ba990ea7cb..c315a9ec2a 100644 --- a/racket/src/racket/src/schemef.h +++ b/racket/src/racket/src/schemef.h @@ -464,6 +464,7 @@ MZ_EXTERN void scheme_gc_ptr_ok(void *p); MZ_EXTERN void scheme_collect_garbage(void); MZ_EXTERN void scheme_collect_garbage_minor(void); MZ_EXTERN void scheme_enable_garbage_collection(int on); +MZ_EXTERN void scheme_incremental_garbage_collection(int on); #ifdef MZ_PRECISE_GC # ifndef USE_THREAD_LOCAL diff --git a/racket/src/racket/src/schemex.h b/racket/src/racket/src/schemex.h index 4d95b96eb5..f7553b13d0 100644 --- a/racket/src/racket/src/schemex.h +++ b/racket/src/racket/src/schemex.h @@ -363,6 +363,7 @@ void (*scheme_gc_ptr_ok)(void *p); void (*scheme_collect_garbage)(void); void (*scheme_collect_garbage_minor)(void); void (*scheme_enable_garbage_collection)(int on); +void (*scheme_incremental_garbage_collection)(int on); #ifdef MZ_PRECISE_GC # ifndef USE_THREAD_LOCAL void **GC_variable_stack; diff --git a/racket/src/racket/src/schemex.inc b/racket/src/racket/src/schemex.inc index 741ff989cc..498a16334c 100644 --- a/racket/src/racket/src/schemex.inc +++ b/racket/src/racket/src/schemex.inc @@ -263,6 +263,7 @@ scheme_extension_table->scheme_collect_garbage = scheme_collect_garbage; scheme_extension_table->scheme_collect_garbage_minor = scheme_collect_garbage_minor; scheme_extension_table->scheme_enable_garbage_collection = scheme_enable_garbage_collection; + scheme_extension_table->scheme_incremental_garbage_collection = scheme_incremental_garbage_collection; #ifdef MZ_PRECISE_GC # ifndef USE_THREAD_LOCAL scheme_extension_table->GC_variable_stack = GC_variable_stack; diff --git a/racket/src/racket/src/schemexm.h b/racket/src/racket/src/schemexm.h index 318cad8505..cfd3512112 100644 --- a/racket/src/racket/src/schemexm.h +++ b/racket/src/racket/src/schemexm.h @@ -263,6 +263,7 @@ #define scheme_collect_garbage (scheme_extension_table->scheme_collect_garbage) #define scheme_collect_garbage_minor (scheme_extension_table->scheme_collect_garbage_minor) #define scheme_enable_garbage_collection (scheme_extension_table->scheme_enable_garbage_collection) +#define scheme_incremental_garbage_collection (scheme_extension_table->scheme_incremental_garbage_collection) #ifdef MZ_PRECISE_GC # ifndef USE_THREAD_LOCAL #define GC_variable_stack (scheme_extension_table->GC_variable_stack) diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index 80c0c8b4c6..08a6d60104 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -223,7 +223,7 @@ THREAD_LOCAL_DECL(static double end_this_gc_real_time); static void get_ready_for_GC(void); static void done_with_GC(void); #ifdef MZ_PRECISE_GC -static void inform_GC(int master_gc, int major_gc, intptr_t pre_used, intptr_t post_used, +static void inform_GC(int master_gc, int major_gc, int inc_gc, intptr_t pre_used, intptr_t post_used, intptr_t pre_admin, intptr_t post_admin, intptr_t post_child_places_used); #endif @@ -9252,7 +9252,7 @@ static char *gc_num(char *nums, intptr_t v) END_XFORM_SKIP; #endif -static void inform_GC(int master_gc, int major_gc, +static void inform_GC(int master_gc, int major_gc, int inc_gc, intptr_t pre_used, intptr_t post_used, intptr_t pre_admin, intptr_t post_admin, intptr_t post_child_places_used) @@ -9282,7 +9282,9 @@ static void inform_GC(int master_gc, int major_gc, vec = scheme_false; if (!master_gc && gc_info_prefab) { vec = scheme_make_vector(11, scheme_false); - SCHEME_VEC_ELS(vec)[1] = (major_gc ? scheme_true : scheme_false); + SCHEME_VEC_ELS(vec)[1] = (major_gc + ? major_symbol + : (inc_gc ? incremental_symbol : minor_symbol)); SCHEME_VEC_ELS(vec)[2] = scheme_make_integer(pre_used); SCHEME_VEC_ELS(vec)[3] = scheme_make_integer(pre_admin); SCHEME_VEC_ELS(vec)[4] = scheme_make_integer(scheme_code_page_total); @@ -9311,7 +9313,7 @@ static void inform_GC(int master_gc, int major_gc, #ifdef MZ_USE_PLACES scheme_current_place_id, #endif - (master_gc ? "MST" : (major_gc ? "MAJ" : "min")), + (master_gc ? "MST" : (major_gc ? "MAJ" : (inc_gc ? "mIn" : "min"))), gc_num(nums, pre_used), gc_num(nums, pre_admin - pre_used), gc_num(nums, scheme_code_page_total), gc_num(nums, delta), ((admin_delta < 0) ? "" : "+"), gc_num(nums, admin_delta), From 493eb1de7f5ea2962b3590f47decf2ccf81d1156 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 27 Nov 2015 14:26:09 -0700 Subject: [PATCH 096/369] tweak incremental-GC parameters Based on experiments with a few programs. --- racket/src/racket/gc2/newgc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 45cb73cf02..dcf4b4f987 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -244,7 +244,7 @@ MAYBE_UNUSED static void GCVERBOSEprintf(NewGC *gc, const char *fmt, ...) { /* Extra factor allowed before forcing a non-incremental full collection when incremental model is started: */ -#define INCREMENTAL_EXTRA_SIZE_RATIO 1.5 +#define INCREMENTAL_EXTRA_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 @@ -253,8 +253,8 @@ MAYBE_UNUSED static void GCVERBOSEprintf(NewGC *gc, const char *fmt, ...) { /* Incremental mode */ static int always_collect_incremental_on_minor = 0; -#define INCREMENTAL_COLLECT_FUEL_PER_100M (24 * 1024) -#define INCREMENTAL_REPAIR_FUEL_PER_100M 512 +#define INCREMENTAL_COLLECT_FUEL_PER_100M (32 * 1024) +#define INCREMENTAL_REPAIR_FUEL_PER_100M 256 /* Conservatively force a major GC after a certain number of minor GCs. It should be ok to set this value From ad2dd24fb8da16c60613389e7a9ac0b1a1c6cd3c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 28 Nov 2015 05:38:56 -0700 Subject: [PATCH 097/369] incremental GC: split "incremental" finalization to single step Don't finalize after performing some marking work, since finalization is in one chunk, so it's best to avoid combining that delay with others. --- racket/src/racket/gc2/newgc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index dcf4b4f987..d942249267 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -5918,11 +5918,12 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (do_incremental) { if (!gc->finishing_incremental) { - int fuel = INCREMENTAL_COLLECT_FUEL_PER_100M * ((gc->memory_in_use / (1024 * 1024 * 100)) + 1); mark_finalizer_structs(gc, 1); - propagate_incremental_marks(gc, 1, fuel); - if (mark_stack_is_empty(gc->inc_mark_stack)) { - /* If we run out of incremental marking work, + if (!mark_stack_is_empty(gc->inc_mark_stack)) { + int fuel = INCREMENTAL_COLLECT_FUEL_PER_100M * ((gc->memory_in_use / (1024 * 1024 * 100)) + 1); + propagate_incremental_marks(gc, 1, fuel); + } else { + /* We ran out of incremental marking work, so perform major-GC finalization in one go. */ mark_and_finalize_all_incremental(gc TIME_ARGS); BTC_clean_up_gen1(gc); From 46fe53fadb8a1a78b5b15ec89ee46d0c1d80fe2f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 27 Nov 2015 20:08:18 -0700 Subject: [PATCH 098/369] incremental GC: avoid extra traverals of weak-link lists When incremental mode has already gone through weak boxes and arrays, a major GC doesn't need to see them again. --- racket/src/racket/gc2/newgc.c | 33 ++++++----- racket/src/racket/gc2/newgc.h | 2 + racket/src/racket/gc2/weak.c | 105 +++++++++++++++++++++++++--------- 3 files changed, 99 insertions(+), 41 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index d942249267..185162c2f3 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -3390,6 +3390,8 @@ static NewGC *init_type_tags_worker(NewGC *inheritgc, NewGC *parentgc, GC_add_roots(&gc->park_fsave, (char *)&gc->park_fsave + sizeof(gc->park_fsave) + 1); GC_add_roots(&gc->park_isave, (char *)&gc->park_isave + sizeof(gc->park_isave) + 1); + gc->weak_incremental_done = WEAK_INCREMENTAL_DONE_1; + return gc; } @@ -5710,17 +5712,13 @@ static void mark_and_finalize_all(NewGC *gc, int old_gen TIME_FORMAL_ARGS) TIME_STEP("marked"); if (old_gen) { - /* move gen1 into active positions: */ - init_weak_boxes(gc, 1); - init_weak_arrays(gc, 1); - init_ephemerons(gc, 1); GC_ASSERT(!gc->fnl_gen1); gc->fnl_gen1 = 1; } - zero_weak_boxes(gc, 0, 0); - zero_weak_arrays(gc, 0); - zero_remaining_ephemerons(gc); + zero_weak_boxes(gc, 0, 0, old_gen); + zero_weak_arrays(gc, 0, old_gen); + zero_remaining_ephemerons(gc, old_gen); TIME_STEP("zeroed"); @@ -5729,7 +5727,7 @@ static void mark_and_finalize_all(NewGC *gc, int old_gen TIME_FORMAL_ARGS) propagate_marks(gc); else propagate_incremental_marks(gc, 0, -1); - zero_weak_boxes(gc, 1, 0); + zero_weak_boxes(gc, 1, 0, old_gen); check_finalizers(gc, 3, old_gen); if (!old_gen) @@ -5741,10 +5739,10 @@ static void mark_and_finalize_all(NewGC *gc, int old_gen TIME_FORMAL_ARGS) gc->GC_post_propagate_hook(gc); /* for any new ones that appeared: */ - zero_weak_boxes(gc, 0, 1); - zero_weak_boxes(gc, 1, 1); - zero_weak_arrays(gc, 1); - zero_remaining_ephemerons(gc); + zero_weak_boxes(gc, 0, 1, old_gen); + zero_weak_boxes(gc, 1, 1, old_gen); + zero_weak_arrays(gc, 1, old_gen); + zero_remaining_ephemerons(gc, old_gen); if (old_gen) gc->fnl_gen1 = 0; @@ -6024,8 +6022,17 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin gc->no_further_modifications = 0; - if (gc->gc_full) + if (gc->gc_full) { free_incremental_admin_pages(gc); + if (gc->started_incremental) { + /* Flip `weak_incremental_done`, so we can detect + whether a weak reference is handled on a given pass. */ + if (gc->weak_incremental_done == WEAK_INCREMENTAL_DONE_1) + gc->weak_incremental_done = WEAK_INCREMENTAL_DONE_2; + else + gc->weak_incremental_done = WEAK_INCREMENTAL_DONE_1; + } + } check_excessive_free_pages(gc); diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index ae71bd8521..24b649dcf5 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -312,6 +312,8 @@ typedef struct NewGC { GC_Ephemeron *ephemerons, *inc_ephemerons, *bp_ephemerons; int num_last_seen_ephemerons; + void *weak_incremental_done; + Allocator *saved_allocator; #ifdef MZ_USE_PLACES diff --git a/racket/src/racket/gc2/weak.c b/racket/src/racket/gc2/weak.c index 3c1ce2c29e..0bdb777a4f 100644 --- a/racket/src/racket/gc2/weak.c +++ b/racket/src/racket/gc2/weak.c @@ -21,6 +21,8 @@ Type_Tag */ +#define WEAK_INCREMENTAL_DONE_1 ((void *)0x1) +#define WEAK_INCREMENTAL_DONE_2 ((void *)0x3) /******************************************************************************/ /* weak arrays */ @@ -42,12 +44,17 @@ static int mark_weak_array(void *p, struct NewGC *gc) if (gc->doing_memory_accounting) { /* skip */ - } else if (gc->inc_gen1 && !gc->fnl_gen1) { + } 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) { + if (!gc->gc_full + || (gc->started_incremental + /* `a` must have been marked and must be in the old + generation, or we wouldn't get here; `a` may have been + fully processed in incremental mode, though */ + && (a->data[a->count] == gc->weak_incremental_done))) { /* Keep backpointered weak arrays separate, because we should not merge them to the incremental list in incremental mode. */ @@ -57,6 +64,8 @@ static int mark_weak_array(void *p, struct NewGC *gc) } else { a->next = gc->weak_arrays; gc->weak_arrays = a; + if (gc->gc_full) + a->data[a->count] = NULL; /* ensure not a future weak_incremental_done */ } #if CHECKS @@ -158,14 +167,16 @@ static GC_Weak_Array *append_weak_arrays(GC_Weak_Array *wa, GC_Weak_Array *bp_wa return bp_wa; } -static void zero_weak_arrays(GCTYPE *gc, int force_zero) +static void zero_weak_arrays(GCTYPE *gc, int force_zero, int from_inc) { GC_Weak_Array *wa; 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 (from_inc) { + wa = gc->inc_weak_arrays; + num_gen0 = 0; + } else + wa = append_weak_arrays(gc->weak_arrays, gc->bp_weak_arrays, &num_gen0); if (gc->gc_full || !gc->started_incremental) num_gen0 = 0; @@ -191,12 +202,21 @@ static void zero_weak_arrays(GCTYPE *gc, int force_zero) } } - wa = wa->next; + if (from_inc) { + GC_Weak_Array *next; + next = (GC_Weak_Array *)wa->data[wa->count]; + wa->data[wa->count] = gc->weak_incremental_done; + wa = next; + } else + wa = wa->next; num_gen0--; } - - gc->weak_arrays = NULL; - gc->bp_weak_arrays = NULL; + if (from_inc) + gc->inc_weak_arrays = NULL; + else { + gc->weak_arrays = NULL; + gc->bp_weak_arrays = NULL; + } } /******************************************************************************/ @@ -236,12 +256,17 @@ static int mark_weak_box(void *p, struct NewGC *gc) if (gc->doing_memory_accounting) { /* skip */ - } else if (gc->inc_gen1 && !gc->fnl_gen1) { + } 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)) { + if ((!gc->gc_full + || (gc->started_incremental + /* see note with `gc->weak_incremental_done` for weak arrays */ + && (wb->inc_next == gc->weak_incremental_done) + && wb->val)) + && (wb->val || gc->started_incremental)) { /* Keep backpointered weak arrays separate, because we should not merge them to the incremental list in incremental mode. */ @@ -255,6 +280,8 @@ static int mark_weak_box(void *p, struct NewGC *gc) 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; + if (gc->gc_full) + wb->inc_next = NULL; /* ensure not a future weak_incremental_done */ } return gcBYTES_TO_WORDS(sizeof(GC_Weak_Box)); @@ -340,18 +367,21 @@ static GC_Weak_Box *append_weak_boxes(GC_Weak_Box *wb, GC_Weak_Box *bp_wb, int * return bp_wb; } -static void zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero) +static void zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero, int from_inc) { 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) + if (from_inc) { + wb = gc->inc_weak_boxes[is_late]; num_gen0 = 0; + } else { + 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; + } while (wb) { GC_ASSERT(is_marked(gc, wb)); @@ -384,17 +414,28 @@ static void zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero) if (!is_in_generation_half(gc, wb)) { /* For incremental mode, preserve this weak box in the incremental list for re-checking later. */ + check_weak_box_not_already_in_inc_chain(wb, gc->inc_weak_boxes[wb->is_late]); wb->inc_next = gc->inc_weak_boxes[is_late]; gc->inc_weak_boxes[is_late] = wb; } } - wb = wb->next; + if (from_inc) { + GC_Weak_Box *next; + next = wb->inc_next; + wb->inc_next = gc->weak_incremental_done; + wb = next; + } else + 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; + if (from_inc) { + gc->inc_weak_boxes[is_late] = NULL; + } else { + gc->weak_boxes[is_late] = NULL; + gc->bp_weak_boxes[is_late] = NULL; + } } /******************************************************************************/ @@ -412,7 +453,7 @@ static int mark_ephemeron(void *p, struct NewGC *gc) if (eph->val) { GC_ASSERT(!gc->doing_memory_accounting); - if (gc->inc_gen1 && !gc->fnl_gen1) { + if (gc->inc_gen1) { eph->inc_next = gc->inc_ephemerons; gc->inc_ephemerons = eph; } else if (gc->during_backpointer) { @@ -559,15 +600,23 @@ static int mark_ready_ephemerons(GCTYPE *gc, int inc_gen1) return did_one; } -static void zero_remaining_ephemerons(GCTYPE *gc) +static void zero_remaining_ephemerons(GCTYPE *gc, int from_inc) { GC_Ephemeron *eph; /* After level-1 finalization, any remaining ephemerons should be zeroed. */ - for (eph = gc->ephemerons; eph; eph = eph->next) { - eph->key = NULL; - eph->val = NULL; + if (from_inc) { + for (eph = gc->inc_ephemerons; eph; eph = eph->inc_next) { + eph->key = NULL; + eph->val = NULL; + } + gc->inc_ephemerons = NULL; + } else { + for (eph = gc->ephemerons; eph; eph = eph->next) { + eph->key = NULL; + eph->val = NULL; + } + gc->ephemerons = NULL; } - gc->ephemerons = NULL; } From d37bfd45aef704e42912854de24762991440b7ff Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 28 Nov 2015 06:09:05 -0700 Subject: [PATCH 099/369] avoid unnecessary closure-fixup work in incremental mode --- racket/src/racket/src/eval.c | 15 ++++----------- racket/src/racket/src/mzclpf_post.inc | 18 +++++++----------- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index 3e61decd80..c02a180cf5 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -6100,7 +6100,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, inc_fixup_mode; + int i, *use_bits, maxpos; scheme_prefix_finalize = (Scheme_Prefix *)0x1; while (pf != (Scheme_Prefix *)0x1) { @@ -6155,24 +6155,17 @@ 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; - if (!inc_fixup_mode) - next = cl->vals[closure_size - 1]; + 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; - if (!inc_fixup_mode) - next = cl->vals[closure_size - 1]; + next = cl->vals[closure_size - 1]; cl->vals[closure_size-1] = (Scheme_Object *)pf; } else { MZ_ASSERT(0); @@ -6180,7 +6173,7 @@ static void mark_pruned_prefixes(struct NewGC *gc) XFORM_SKIP_PROC } clo = (Scheme_Object *)GC_resolve2(next, gc); } - if (inc_fixup_mode) + if (SCHEME_PREFIX_FLAGS(pf) & 0x1) SCHEME_PREFIX_FLAGS(pf) -= 0x1; /* Next */ diff --git a/racket/src/racket/src/mzclpf_post.inc b/racket/src/racket/src/mzclpf_post.inc index 2bfd7f7182..3a1a642957 100644 --- a/racket/src/racket/src/mzclpf_post.inc +++ b/racket/src/racket/src/mzclpf_post.inc @@ -41,19 +41,15 @@ mark_stxes = 0; /* Add this closure to the chain to be repaired when the - prefix is marked (and potentially moved): */ - 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 { + prefix is marked and potentially moved; if we're here + in incremental mode, though, the prefix won't be moved: */ + if (gc_mode != GC_CURRENT_MODE_INCREMENTAL) { c->vals[closure_size - 1] = pf->fixup_chain; pf->fixup_chain = (Scheme_Object *)c; + } else { + /* Mark the prefix as reached in incremental mode, which + triggers special handling for bakpointers */ + SCHEME_PREFIX_FLAGS(pf) |= 0x1; } /* Mark just the elements of the prefix that are (newly) used: */ From ca0e9b8b2f06b0aa39113764153bd8cf3d4a00a7 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 28 Nov 2015 06:33:22 -0700 Subject: [PATCH 100/369] report timing of incremental step --- racket/src/racket/gc2/newgc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 185162c2f3..f9a0cd71ab 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -5920,6 +5920,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (!mark_stack_is_empty(gc->inc_mark_stack)) { int fuel = INCREMENTAL_COLLECT_FUEL_PER_100M * ((gc->memory_in_use / (1024 * 1024 * 100)) + 1); propagate_incremental_marks(gc, 1, fuel); + TIME_STEP("incremented"); } else { /* We ran out of incremental marking work, so perform major-GC finalization in one go. */ From 81e0636843c473dc421d835fe749eebd1af90e0c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 28 Nov 2015 08:25:37 -0700 Subject: [PATCH 101/369] fix counting of interior-pointer-allowed objects Words versus bytes. --- 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 f9a0cd71ab..ce9afe42ea 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -4672,7 +4672,7 @@ static void mark_backpointers(NewGC *gc) start += info->size; } - gc->memory_in_use -= work->live_size; + gc->memory_in_use -= gcWORDS_TO_BYTES(work->live_size); } traversed++; @@ -5241,7 +5241,7 @@ static void repair_heap(NewGC *gc) if (need_fixup_now) repair_mixed_page(gc, page, PPTR(NUM(page->addr) + APAGE_SIZE - page->obj_size)); - memory_in_use += page->live_size; + memory_in_use += gcWORDS_TO_BYTES(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): */ @@ -5468,7 +5468,7 @@ static void clean_up_heap(NewGC *gc) } /* For medium pages, generation-0 pages will appear first in each - list, so for a mnior GC, we can stop whenever we find a + list, so for a minor 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++) { @@ -5479,7 +5479,7 @@ static void clean_up_heap(NewGC *gc) next = work->next; if (work->marked_on) { work->marked_on = 0; - memory_in_use += work->live_size; + memory_in_use += gcWORDS_TO_BYTES(work->live_size); work->generation = AGE_GEN_1; prev = work; } else if (gc->gc_full || (work->generation == AGE_GEN_0)) { From e968cfbde40712c5c35de1e030e383b92b933c3c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 28 Nov 2015 08:47:11 -0700 Subject: [PATCH 102/369] fix accounting of phantom bytes for incremental GC Also fixes accounting when a phantom-bytes value is treated as potentially having a backpointer. --- racket/src/racket/gc2/newgc.c | 15 +++++++++++---- racket/src/racket/gc2/newgc.h | 1 + 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index ce9afe42ea..bc500379d5 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -2593,7 +2593,12 @@ static int mark_phantom(void *p, struct NewGC *gc) { Phantom_Bytes *pb = (Phantom_Bytes *)p; - gc->phantom_count = add_no_overflow(gc->phantom_count, pb->count); + if (!gc->during_backpointer) { + if (gc->inc_gen1) + gc->inc_phantom_count = add_no_overflow(gc->inc_phantom_count, pb->count); + else + gc->phantom_count = add_no_overflow(gc->phantom_count, pb->count); + } return gcBYTES_TO_WORDS(sizeof(Phantom_Bytes)); } @@ -3612,6 +3617,7 @@ intptr_t GC_get_memory_use(void *o) } #endif amt = add_no_overflow(gen0_size_in_use(gc), gc->memory_in_use); + amt = add_no_overflow(amt, gc->gen0_phantom_count); #ifdef MZ_USE_PLACES mzrt_mutex_lock(gc->child_total_lock); amt = add_no_overflow(amt, gc->child_gc_total); @@ -5839,9 +5845,10 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin 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) { + if (gc->gc_full) { + gc->phantom_count = gc->inc_phantom_count; + gc->inc_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; } diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 24b649dcf5..9b20c77c90 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -294,6 +294,7 @@ typedef struct NewGC { uintptr_t phantom_count; uintptr_t gen0_phantom_count; + uintptr_t inc_phantom_count; Roots roots; struct MMU *mmu; From c3ac1c6bf433282c2faf3ff6c87f66014a4ae396 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 28 Nov 2015 09:02:56 -0700 Subject: [PATCH 103/369] reduce incremental work on `(collect-garbage 'minor)` When `(collect-garbage 'minor)` is combined with incremental mode, do less incremental work. At the same time, don't skip an incremental GC just because a major GC is ready. --- racket/src/racket/gc2/newgc.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index bc500379d5..d290a72577 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -5804,7 +5804,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin fraction of the actual use by live data: */ || (gc->memory_in_use > (FULL_COLLECTION_SIZE_RATIO * gc->last_full_mem_use - * (gc->started_incremental + * ((gc->started_incremental && !no_full) ? INCREMENTAL_EXTRA_SIZE_RATIO : 1))) /* Just in case, for a full GC every so often, unless @@ -5816,7 +5816,8 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin || (gc->started_incremental && mark_stack_is_empty(gc->inc_mark_stack) && gc->finishing_incremental - && !gc->inc_repair_next)); + && !gc->inc_repair_next + && !no_full)); if (gc->gc_full && no_full) { return; @@ -5925,7 +5926,9 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (!gc->finishing_incremental) { mark_finalizer_structs(gc, 1); if (!mark_stack_is_empty(gc->inc_mark_stack)) { - int fuel = INCREMENTAL_COLLECT_FUEL_PER_100M * ((gc->memory_in_use / (1024 * 1024 * 100)) + 1); + int fuel = (no_full + ? INCREMENTAL_COLLECT_FUEL_PER_100M / 8 + : INCREMENTAL_COLLECT_FUEL_PER_100M * ((gc->memory_in_use / (1024 * 1024 * 100)) + 1)); propagate_incremental_marks(gc, 1, fuel); TIME_STEP("incremented"); } else { @@ -5980,7 +5983,9 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin /* Didn't fire a full GC? Go back to incremental marking: */ gc->finishing_incremental = 0; } else { - int fuel = INCREMENTAL_REPAIR_FUEL_PER_100M * ((gc->memory_in_use / (1024 * 1024 * 100)) + 1); + int fuel = (no_full + ? INCREMENTAL_REPAIR_FUEL_PER_100M / 8 + : INCREMENTAL_REPAIR_FUEL_PER_100M * ((gc->memory_in_use / (1024 * 1024 * 100)) + 1)); incremental_repair_pages(gc, fuel); TIME_STEP("inc-repaired"); } From 89807d178ef392cd2e90b4c139160778c6807fb6 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 28 Nov 2015 10:02:53 -0700 Subject: [PATCH 104/369] fix accounting of nursery for logging The pre-GC count didn't include the obejcts allocated on the most recent nursery page. --- racket/src/racket/gc2/newgc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index d290a72577..29eb834a98 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -5788,7 +5788,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin int do_incremental = 0, check_inc_repair; old_mem_use = gc->memory_in_use; /* includes gc->phantom_count */ - old_gen0 = gc->gen0.current_size + gc->gen0_phantom_count; + old_gen0 = gen0_size_in_use(gc) + gc->gen0_phantom_count; old_mem_allocated = mmu_memory_allocated(gc->mmu) + gc->phantom_count + gc->gen0_phantom_count; TIME_DECLS(); From 9407afa0a240e9780b504fb98dc69a495e941b1b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 28 Nov 2015 11:21:19 -0700 Subject: [PATCH 105/369] faster GC traversal of shared closure prefixes --- racket/src/racket/src/mzclpf_post.inc | 50 +++++++++++++++------------ 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/racket/src/racket/src/mzclpf_post.inc b/racket/src/racket/src/mzclpf_post.inc index 3a1a642957..1a0303a9f0 100644 --- a/racket/src/racket/src/mzclpf_post.inc +++ b/racket/src/racket/src/mzclpf_post.inc @@ -48,45 +48,49 @@ pf->fixup_chain = (Scheme_Object *)c; } else { /* Mark the prefix as reached in incremental mode, which - triggers special handling for bakpointers */ + triggers special handling for backpointers */ SCHEME_PREFIX_FLAGS(pf) |= 0x1; } /* 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; - for (i = 0; i < 31; i++) { - if (map & (1 << i)) { - if (!(use_bits[0] & (1 << i))) { - if ((i < pf->num_toplevels) || !pf->num_stxes) - gcMARK2(pf->a[i], gc); /* top level */ - else if (i == pf->num_toplevels) - mark_stxes = 1; /* any syntax object */ - else - gcMARK2(pf->a[i + pf->num_stxes], gc); /* lifted */ + map = (((uintptr_t)data->tl_map) >> 1) & 0x7FFFFFFF; + if ((use_bits[0] & map) != map) { + for (i = 0; i < 31; i++) { + if (map & (1 << i)) { + if (!(use_bits[0] & (1 << i))) { + if ((i < pf->num_toplevels) || !pf->num_stxes) + gcMARK2(pf->a[i], gc); /* top level */ + else if (i == pf->num_toplevels) + mark_stxes = 1; /* any syntax object */ + else + gcMARK2(pf->a[i + pf->num_stxes], gc); /* lifted */ + } } } + use_bits[0] |= map; } - use_bits[0] |= (map & 0x7FFFFFFF); } else { int *u = (int *)GC_resolve2(data->tl_map, gc), j, pos; for (i = u[0]; i--; ) { map = u[i+1]; - for (j = 0; j < 32; j++) { - if (map & (1 << j)) { - if (!(use_bits[i] & (1 << j))) { - pos = (i * 32) + j; - if ((pos < pf->num_toplevels) || !pf->num_stxes) - gcMARK2(pf->a[pos], gc); /* top level */ - else if (pos == pf->num_toplevels) - mark_stxes = 1; /* any syntax object */ - else - gcMARK2(pf->a[pos + pf->num_stxes], gc); /* lifted */ + if ((use_bits[i] & map) != map) { + for (j = 0; j < 32; j++) { + if (map & (1 << j)) { + if (!(use_bits[i] & (1 << j))) { + pos = (i * 32) + j; + if ((pos < pf->num_toplevels) || !pf->num_stxes) + gcMARK2(pf->a[pos], gc); /* top level */ + else if (pos == pf->num_toplevels) + mark_stxes = 1; /* any syntax object */ + else + gcMARK2(pf->a[pos + pf->num_stxes], gc); /* lifted */ + } } } + use_bits[i] |= map; } - use_bits[i] |= map; } } if (mark_stxes) { From c9e9b4e400543cc4ae476bef30989d749e32fe00 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 28 Nov 2015 11:55:43 -0700 Subject: [PATCH 106/369] add info on incremental GC mode to the Guide --- .../scribblings/guide/performance.scrbl | 61 ++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-doc/scribblings/guide/performance.scrbl b/pkgs/racket-doc/scribblings/guide/performance.scrbl index a827026c7f..555fd3345f 100644 --- a/pkgs/racket-doc/scribblings/guide/performance.scrbl +++ b/pkgs/racket-doc/scribblings/guide/performance.scrbl @@ -471,7 +471,7 @@ then the expansion of the @racket[let] form to implement automatically converts the closure to pass itself @racket[n] as an argument instead. -@section{Reachability and Garbage Collection} +@section[#:tag "Reachability and Garbage Collection"]{Reachability and Garbage Collection} In general, Racket re-uses the storage for a value when the garbage collector can prove that the object is unreachable from @@ -534,7 +534,7 @@ There are a number of exceptions, however: @item{Interned symbols are allocated only once (per place). A table inside Racket tracks this allocation so a symbol may not become garbage because that table holds onto it.} - @item{Reachability is only approximate with the CGC collector (i.e., + @item{Reachability is only approximate with the @tech{CGC} collector (i.e., a value may appear reachable to that collector when there is, in fact, no way to reach it anymore.}] @@ -577,3 +577,60 @@ occurrence of the variable @racket[_fishes]. That constitutes a reference to the list, ensuring that the list is not itself garbage collected, and thus the red fish is not either. + +@section{Reducing Garbage Collection Pauses} + +By default, Racket's @tech{generational garbage collector} creates +brief pauses for frequent @deftech{minor collections}, which inspect +only the most recently allocated objects, and long pauses for infrequent +@deftech{major collections}, which re-inspect all memory. Weak +references (as described in +@secref["Reachability\x20and\x20Garbage\x20Collection"]) are cleared +only by a major collection. + +For soft real-time applications, such as animations, games, and some +network services, long pauses due to a major collection can interfere +unacceptably with a program's operation. To reduce major-collection +pauses, the Racket garbage collector supports @deftech{incremental +garbage-collection} mode. In incremental mode, minor collections +create longer (but still relatively short) pauses by performing extra +work toward the next major collection. If all goes well, most of a +major collection's work has been performed by minor collections the +time that a major collection is needed, so the major collection's +pause is as short as a minor collection's pause. Incremental mode +tends to use more memory and run more slowly overall, but it can +provide much more consistent real-time behavior. + +If the @envvar{PLT_INCREMENTAL_GC} environment variable is set when +Racket starts, incremental mode is permanently enabled. Since +incremental mode is only useful for certain parts of some programs, +however, and since the need for incremental mode is a property of a +program rather than its environment, the preferred way to enable +incremental mode is with @racket[(collect-garbage 'incremental)]. + +Calling @racket[(collect-garbage 'incremental)] does not perform an +immediate garbage collection, but instead requests that each minor +collection perform incremental work up to the next major collection. +The request expires with the next major collection. Make a call to +@racket[(collect-garbage 'incremental)] in any periodic task within +an application that needs to be responsive in real time. + +To check whether incremental mode is use and how it affects pause +times, enable @tt{debug}-level logging output for the +@racketidfont{GC} topic. For example, + +@commandline{racket -W "debuG@"@"GC error" main.rkt} + +runs @filepath{main.rkt} with garbage-collection logging to stderr +(while preserving @tt{error}-level logging for all topics). Minor +collections are reported by @litchar{min} lines, increment-mode minor +collection are reported with @litchar{mIn} lines, and major +collections are reported with @litchar{MAJ} lines. + +Some Racket features can interfere with incremental mode. In +particular, memory accounting via @racket[custodian-limit-memory] +triggers an accounting pass during a major collection, and that pass +is not currently incremental. Note that DrRacket uses +@racket[custodian-limit-memory] to control the memory use of programs +run within DrRacket, so incremental mode is useful mainly outside of +DrRacket. (See also @secref["DrRacket-perf"].) From 86934d4a4fbb3e45f01482b8a3ac0c23555ab0ee Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 28 Nov 2015 13:45:17 -0600 Subject: [PATCH 107/369] adjust contract printing so that it looks like the constructors in print mode and so that it cooperates with pretty printing to get some newlines in there --- .../collects/racket/contract/private/guts.rkt | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/racket/collects/racket/contract/private/guts.rkt b/racket/collects/racket/contract/private/guts.rkt index 417b8a7cf6..aa57721056 100644 --- a/racket/collects/racket/contract/private/guts.rkt +++ b/racket/collects/racket/contract/private/guts.rkt @@ -55,14 +55,28 @@ set-some-basic-contracts!) -(define (contract-custom-write-property-proc stct port display?) - (write-string "#<" port) +(define (contract-custom-write-property-proc stct port mode) + (define (write-prefix) + (write-string "#<" port) + (cond + [(flat-contract-struct? stct) (write-string "flat-" port)] + [(chaperone-contract-struct? stct) (write-string "chaperone-" port)]) + (write-string "contract: " port)) + (define (write-suffix) + (write-string ">" port)) (cond - [(flat-contract-struct? stct) (write-string "flat-" port)] - [(chaperone-contract-struct? stct) (write-string "chaperone-" port)]) - (write-string "contract: " port) - (write-string (format "~.s" (contract-struct-name stct)) port) - (write-string ">" port)) + [(boolean? mode) + (write-prefix) + (write-string (format "~.s" (contract-struct-name stct)) port) + (write-suffix)] + [else + (cond + [(zero? mode) + (print (contract-struct-name stct) port 1)] + [else + (write-prefix) + (print (contract-struct-name stct) port 1) + (write-suffix)])])) (define (has-contract? v) (or (has-prop:contracted? v) From 8cc2e27ca7b777725d9a83298ea260257f3d22bf Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 28 Nov 2015 16:25:21 -0600 Subject: [PATCH 108/369] improve error checking in version/utils closes #1152 --- pkgs/racket-doc/version/version.scrbl | 8 +- racket/collects/version/utils.rkt | 110 +++++++++++++++++++++++--- 2 files changed, 104 insertions(+), 14 deletions(-) diff --git a/pkgs/racket-doc/version/version.scrbl b/pkgs/racket-doc/version/version.scrbl index 112d108235..e6c7f05eab 100644 --- a/pkgs/racket-doc/version/version.scrbl +++ b/pkgs/racket-doc/version/version.scrbl @@ -76,12 +76,12 @@ indicates the current state of the curent installation: utilities for dealing with version strings. Unless explicitly noted, these functions do not handle legacy versions of Racket.} -@defproc[(valid-version? [str string?]) boolean?]{ - Returns @racket[#t] if @racket[str] is a valid Racket version +@defproc[(valid-version? [v any/c]) boolean?]{ + Returns @racket[#t] if @racket[v] is a valid Racket version string, @racket[#f] otherwise.} @defproc[(version->list [str valid-version?]) - (list integer? integer? integer? integer?)]{ + (list/c integer? integer? integer? integer?)]{ Returns a list of four numbers that the given version string represent. @racket[str] is assumed to be a valid version.} @@ -99,7 +99,7 @@ indicates the current state of the curent installation: Returns @racket[#t] if the version that @racket[str] represents is an alpha version. @racket[str] is assumed to be a valid version.} -@defproc[(version->integer [str string?]) (or/c integer? false/c)]{ +@defproc[(version->integer [str string?]) (or/c integer? #f)]{ Converts the version string into an integer. For version @racket["X.YY.ZZZ.WWW"], the result will be @racketvalfont{XYYZZZWWW}. This function works also for legacy Racket versions, by diff --git a/racket/collects/version/utils.rkt b/racket/collects/version/utils.rkt index 001e2e2b68..9b702785d8 100644 --- a/racket/collects/version/utils.rkt +++ b/racket/collects/version/utils.rkt @@ -1,7 +1,5 @@ #lang racket/base - -(provide valid-version? version->list versioninteger) +(require (for-syntax racket/base)) (define rx:version ;; (this restricts the last component to be below 999 too, which is @@ -13,10 +11,21 @@ (define (valid-version? s) (and (string? s) (regexp-match? rx:version s))) -;; the following functions assume valid version string inputs +(define-syntax (define/version-inputs stx) + (syntax-case stx () + [(_ (f x ...) body ...) + #'(define (f x ...) + (check-version-inputs 'f (list x ...)) + body ...)])) +(define (check-version-inputs fn args) + (for ([arg (in-list args)] + [i (in-naturals)]) + (unless (valid-version? arg) + (apply raise-argument-error fn "valid-version?" i args)))) + ;; returns a list of 4 integers (see src/racket/src/schvers.h) -(define (version->list str) +(define/version-inputs (version->list str) (define ver (map string->number (regexp-split #rx"[.]" str))) (case (length ver) [(2) (append ver '(0 0))] @@ -24,17 +33,20 @@ [(4) ver] [else (error 'version->list "bad version: ~e" str)])) -(define (versionlist a)] [b (version->list b)]) (cond [(null? a) #f] [(< (car a) (car b)) #t] [(> (car a) (car b)) #f] [else (loop (cdr a) (cdr b))]))) -(define (version<=? a b) - (or (equal? a b) (versionlist v)) (or ((list-ref l 1) . >= . 90) ((list-ref l 2) . >= . 900) @@ -69,3 +81,81 @@ (and v (valid-version? v) (foldl (λ (ver mul acc) (+ ver (* mul acc))) 0 (version->list v) '(0 100 1000 1000)))) + +(define-syntax-rule + (provide+save-in-list exported-functions (x p?) ...) + (begin + (provide x ...) + (module+ test (define exported-functions (list (cons x p?) ...))))) + +(provide+save-in-list + exported-functions + (valid-version? boolean?) + (version->list (λ (x) (and (list? x) (= (length x) 4) (andmap integer? x)))) + (versioninteger (λ (x) (or (integer? x) (not x))))) + +(module+ test + (require racket/list) + + (define (random-argument) + (case (random 10) + [(1) + ;; random string of digits, periods lowercase letters, and greek letters + (define candidates + (append (build-list 10 (λ (x) (integer->char (+ x (char->integer #\a))))) + (build-list 10 (λ (x) (integer->char (+ x (char->integer #\0))))) + (build-list 10 (λ (x) (integer->char (+ x (char->integer #\α))))) + '(#\.))) + (apply + string + (for/list ([i (in-range (random 100))]) + (list-ref candidates (random (length candidates)))))] + [(0) + ;; kind of versionish (periods and digits in 100 chars) + (apply + string + (for/list ([i (in-range (random 100))]) + (case (random 4) + [(0) #\.] + [else (integer->char (+ (random 10) (char->integer #\0)))])))] + [else + ;; much closer to a version; + ;; at most 6 fields of digits that are + ;; between 1 and 4 chars in length + (apply + string-append + (add-between + (for/list ([i (in-range (+ 1 (random 5)))]) + (apply + string + (for/list ([i (in-range (random 4))]) + (integer->char (+ (random 10) (char->integer #\0)))))) + "."))])) + + (define (trial f+p) + (define f (car f+p)) + (define p (cdr f+p)) + (define args (for/list ([i (in-range (procedure-arity f))]) + (random-argument))) + (define (check-exn exn) + (define m (regexp-match #rx"^([^:]*):" (exn-message exn))) + (if (equal? (string->symbol (list-ref m 1)) + (object-name f)) + #f + args)) + (with-handlers ([exn:fail? check-exn]) + (if (p (apply f args)) + #f + args))) + + (time + (let/ec give-up + (for ([f+p (in-list exported-functions)]) + (for ([_ (in-range 100)]) + (define trial-result (trial f+p)) + (when trial-result + (eprintf "failed: ~s\n" (cons (object-name (car f+p)) trial-result)) + (give-up))))))) From 71d80bace5de0473f71b96cfe72202e08af6a4e4 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 28 Nov 2015 16:27:21 -0600 Subject: [PATCH 109/369] whoops: don't want to do the precondition check twice --- racket/collects/version/utils.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/version/utils.rkt b/racket/collects/version/utils.rkt index 9b702785d8..c69f5572d7 100644 --- a/racket/collects/version/utils.rkt +++ b/racket/collects/version/utils.rkt @@ -37,7 +37,7 @@ (-versionlist a)] [b (version->list b)]) From a3896785563501231c9ee83d79a7149190f0833e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 28 Nov 2015 14:06:50 -0700 Subject: [PATCH 110/369] improve interaction of incremental mode and finalization Really, just improve when majors GCs are forced to trigger further finalizations. This improvement makes `(collect-garbage)` followed by `(collect-garbage 'incremental)` move more reliably into incremental mode. --- pkgs/racket-doc/scribblings/guide/performance.scrbl | 5 ++++- racket/src/racket/gc2/newgc.c | 12 ++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/pkgs/racket-doc/scribblings/guide/performance.scrbl b/pkgs/racket-doc/scribblings/guide/performance.scrbl index 555fd3345f..6fade46141 100644 --- a/pkgs/racket-doc/scribblings/guide/performance.scrbl +++ b/pkgs/racket-doc/scribblings/guide/performance.scrbl @@ -613,7 +613,10 @@ immediate garbage collection, but instead requests that each minor collection perform incremental work up to the next major collection. The request expires with the next major collection. Make a call to @racket[(collect-garbage 'incremental)] in any periodic task within -an application that needs to be responsive in real time. +an application that needs to be responsive in real time. Force a +full collection with @racket[(collect-garbage)] just before an initial +@racket[(collect-garbage 'incremental)] to initiate incremental mode +from an optimal state. To check whether incremental mode is use and how it affects pause times, enable @tt{debug}-level logging output for the diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 29eb834a98..8fa4ac7f22 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -5811,6 +5811,9 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin incremental mode has been enabled: */ || ((gc->since_last_full > FORCE_MAJOR_AFTER_COUNT) && !gc->started_incremental) + || (gc->full_needed_for_finalization + && !gc->incremental_requested + && !gc->started_incremental) /* In incremental mode, GC earlier if we've done everything that we can do incrementally. */ || (gc->started_incremental @@ -5823,12 +5826,13 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin return; } - next_gc_full = gc->gc_full && !gc->started_incremental; + next_gc_full = (gc->gc_full + && !gc->started_incremental + && !gc->full_needed_for_finalization); - if (gc->full_needed_for_finalization) { + if (gc->full_needed_for_finalization && gc->gc_full) gc->full_needed_for_finalization= 0; - gc->gc_full = 1; - } + #ifdef GC_DEBUG_PAGES if (gc->gc_full == 1) { GCVERBOSEprintf(gc, "GC_FULL gc: %p MASTER: %p\n", gc, MASTERGC); From e7e75c2292d99ae0b5c69773819ddd00f04c3c3e Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sun, 29 Nov 2015 15:07:32 -0600 Subject: [PATCH 111/369] Fix exponentiation of negative single-floats and moderately large bignums. --- pkgs/racket-test-core/tests/racket/number.rktl | 3 +++ racket/src/racket/src/number.c | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/pkgs/racket-test-core/tests/racket/number.rktl b/pkgs/racket-test-core/tests/racket/number.rktl index 0d0cb70062..349a3c4100 100644 --- a/pkgs/racket-test-core/tests/racket/number.rktl +++ b/pkgs/racket-test-core/tests/racket/number.rktl @@ -572,6 +572,9 @@ (test -inf.0 expt -4.0 (add1 (expt 2 5000))) (test +inf.f expt -4.0f0 (expt 2 5000)) (test -inf.f expt -4.0f0 (add1 (expt 2 5000))) +;; exponent large enough to overflow singles, but not doubles +(test +inf.f expt -4.0f0 (lcm (exact-round -1.7976931348623151e+308))) +(test -inf.f expt -4.0f0 (add1 (lcm (exact-round -1.7976931348623151e+308)))) (define (inf-non-real? x) (and (not (real? x)) diff --git a/racket/src/racket/src/number.c b/racket/src/racket/src/number.c index 9feb28de65..31d14914f5 100644 --- a/racket/src/racket/src/number.c +++ b/racket/src/racket/src/number.c @@ -3634,7 +3634,16 @@ scheme_expt(int argc, Scheme_Object *argv[]) be converted to infinity, this would return a complex NaN. Instead, we want to return (positive of negative) infinity. See discussion in Github issue 1148. */ +#ifdef MZ_USE_SINGLE_FLOATS + if (sgl) { + /* Need to go through singles to get right overflow behavior. */ + e_dbl = (double)(scheme_bignum_to_float(e)); + } else { + e_dbl = scheme_bignum_to_double(e); + } +#else e_dbl = scheme_bignum_to_double(e); +#endif if ((d < 0.0) && MZ_IS_POS_INFINITY(e_dbl)) { if (SCHEME_TRUEP(scheme_odd_p(1, &e))) { return SELECT_EXPT_PRECISION(scheme_single_minus_inf_object, From 817fdad2d50681e17f336757edd762c8e497be9a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 29 Nov 2015 17:30:33 -0700 Subject: [PATCH 112/369] Windows with MinGW: Fix network address resolution Use the same code as for MSVC compilation, which is as simple as defining `HAVE_GETADDRINFO`. Closes PR 15192 --- racket/src/racket/src/network.c | 43 +++++---------------------------- 1 file changed, 6 insertions(+), 37 deletions(-) diff --git a/racket/src/racket/src/network.c b/racket/src/racket/src/network.c index 10af061f5b..76a42abdf8 100644 --- a/racket/src/racket/src/network.c +++ b/racket/src/racket/src/network.c @@ -398,6 +398,12 @@ SHARED_OK static struct protoent *proto; /* mz_addrinfo is defined in scheme.h */ +#if defined(__MINGW32__) && !defined(HAVE_GETADDRINFO) +/* Although `configure` didn't discover it, we do have getaddrinfo() + from Winsock */ +# define HAVE_GETADDRINFO +#endif + #ifdef HAVE_GETADDRINFO # define mzAI_PASSIVE AI_PASSIVE # define mz_getaddrinfo getaddrinfo @@ -411,24 +417,6 @@ static int mz_getaddrinfo(const char *nodename, const char *servname, { struct hostent *h; -#ifdef __MINGW32__ - { - HMODULE hm; - hm = LoadLibrary("ws2_32.dll"); - if (hm) { - gai_t gai; - gai = (gai_t)GetProcAddress(hm, "getaddrinfo"); - if (gai) { - int v; - v = gai(nodename, servname, hints, res); - if (!v && !(*res)->ai_addr) - (*res)->ai_addrlen = 0; - return v; - } - } - } -#endif - if (nodename) h = gethostbyname(nodename); else @@ -471,32 +459,13 @@ static int mz_getaddrinfo(const char *nodename, const char *servname, void mz_freeaddrinfo(struct mz_addrinfo *ai) XFORM_SKIP_PROC { -#ifdef __MINGW32__ - { - HMODULE hm; - hm = LoadLibrary("ws2_32.dll"); - if (hm) { - fai_t fai; - fai = (fai_t)GetProcAddress(hm, "freeaddrinfo"); - if (fai) { - fai(ai); - return; - } - } - } -#endif - free(ai->ai_addr); free(ai); } const char *mz_gai_strerror(int ecode) XFORM_SKIP_PROC { -#ifdef __MINGW32__ - return NULL; /* => use FormatMessageW(), instead */ -#else return hstrerror(ecode); -#endif } #endif From fc342924862be8b0f5e8d9ae1033ec622761bd04 Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Mon, 30 Nov 2015 08:30:18 -0500 Subject: [PATCH 113/369] Assume that files that start with . are not modules --- racket/collects/compiler/module-suffix.rkt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/racket/collects/compiler/module-suffix.rkt b/racket/collects/compiler/module-suffix.rkt index f600ef7967..8823915d54 100644 --- a/racket/collects/compiler/module-suffix.rkt +++ b/racket/collects/compiler/module-suffix.rkt @@ -52,7 +52,8 @@ (define suffixes (get-module-suffixes #:mode key #:group group #:namespace namespace)) (byte-pregexp - (bytes-append #"^(.*)\\.(?i:" + (bytes-append #"^([^.].*)\\.(?i:" (apply bytes-append (add-between suffixes #"|")) #")$"))) + From 734563a7f4e08d51cfeab75a44a31303d307de23 Mon Sep 17 00:00:00 2001 From: Phil Nguyen Date: Sun, 29 Nov 2015 16:49:43 -0500 Subject: [PATCH 114/369] =?UTF-8?q?remove=20duplicate=20examples=20in=20do?= =?UTF-8?q?c=20for=20`arity=3D=3F`=20and=20`arity-includes=3F`?= --- pkgs/racket-doc/scribblings/reference/procedures.scrbl | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/procedures.scrbl b/pkgs/racket-doc/scribblings/reference/procedures.scrbl index 87f5d93da1..9815a5a6e2 100644 --- a/pkgs/racket-doc/scribblings/reference/procedures.scrbl +++ b/pkgs/racket-doc/scribblings/reference/procedures.scrbl @@ -708,7 +708,6 @@ and @racket[(equal? (normalize-arity a) (normalize-arity b))]. (arity=? 1 (list 1)) (arity=? 1 (arity-at-least 1)) (arity=? (arity-at-least 1) 1) -(arity=? 1 (arity-at-least 1)) (arity=? (arity-at-least 1) (list 1 (arity-at-least 2))) (arity=? (list 1 (arity-at-least 2)) (arity-at-least 1)) (arity=? (arity-at-least 1) (list 1 (arity-at-least 3))) @@ -732,7 +731,6 @@ arguments that procedures with arity @racket[b] accept. (arity-includes? 1 (list 1)) (arity-includes? 1 (arity-at-least 1)) (arity-includes? (arity-at-least 1) 1) -(arity-includes? 1 (arity-at-least 1)) (arity-includes? (arity-at-least 1) (list 1 (arity-at-least 2))) (arity-includes? (list 1 (arity-at-least 2)) (arity-at-least 1)) (arity-includes? (arity-at-least 1) (list 1 (arity-at-least 3))) From fa3cabd6814866cacd00218cf132b33f21d51e6f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 30 Nov 2015 10:21:37 -0700 Subject: [PATCH 115/369] incremental GC: avoid allocating immobile on old-generation page The allocation strategy for immobile objects avoids some fragmentation in non-incremental mode, but it interferes with finishing up an incremental major collection, so trade some fragmentation for an earlier finish (which is far more likely to use less memory instead of more, despite extra fragmentation). --- racket/src/racket/gc2/newgc.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 8fa4ac7f22..c78bb6020f 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -2692,6 +2692,7 @@ static void push_ptr(NewGC *gc, void *ptr, int inc_gen1) #endif GC_ASSERT(inc_gen1 || !gc->inc_gen1); + GC_ASSERT(!inc_gen1 || !gc->finishing_incremental); push_ptr_at(ptr, inc_gen1 ? &gc->inc_mark_stack : &gc->mark_stack); } @@ -5501,7 +5502,11 @@ static void clean_up_heap(NewGC *gc) next = NULL; } } - gc->med_freelist_pages[ty][i] = prev; + if (gc->finishing_incremental) { + /* no more allocation on old pages */ + gc->med_freelist_pages[ty][i] = NULL; + } else + gc->med_freelist_pages[ty][i] = prev; } } @@ -5832,6 +5837,8 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (gc->full_needed_for_finalization && gc->gc_full) gc->full_needed_for_finalization= 0; + if (gc->gc_full) + gc->finishing_incremental = 0; #ifdef GC_DEBUG_PAGES if (gc->gc_full == 1) { @@ -5984,7 +5991,9 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin TIME_STEP("repaired"); if (check_inc_repair) { if (!gc->inc_repair_next) { - /* Didn't fire a full GC? Go back to incremental marking: */ + /* Didn't fire a full GC? This shouldn't happend, but if it + does, go back to incremental marking: */ + GC_ASSERT(gc->gc_full); gc->finishing_incremental = 0; } else { int fuel = (no_full From 7901962647d867f09d566c27e4d3b5c57e343f16 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 30 Nov 2015 11:12:36 -0700 Subject: [PATCH 116/369] incremental GC: fix phantom-byte counting --- .../tests/racket/phantom-bytes.rkt | 54 ++++++++++++ racket/src/racket/gc2/mem_account.c | 6 +- racket/src/racket/gc2/newgc.c | 82 ++++++++++++++++--- racket/src/racket/gc2/newgc.h | 7 +- racket/src/racket/src/thread.c | 19 +++-- 5 files changed, 141 insertions(+), 27 deletions(-) create mode 100644 pkgs/racket-test-core/tests/racket/phantom-bytes.rkt diff --git a/pkgs/racket-test-core/tests/racket/phantom-bytes.rkt b/pkgs/racket-test-core/tests/racket/phantom-bytes.rkt new file mode 100644 index 0000000000..9e656655ac --- /dev/null +++ b/pkgs/racket-test-core/tests/racket/phantom-bytes.rkt @@ -0,0 +1,54 @@ +#lang racket/base + +;; An extra test of phantom bytes. + +(define (make-one) + (make-phantom-bytes (expt 2 29))) + +(define pbs (list (make-one))) + +(define (check) + (unless (> (current-memory-use) (* (length pbs) + (expt 2 29))) + (error "failed")) + (for ([pb (in-list pbs)]) + (set-phantom-bytes! pb 0)) + (unless (< (current-memory-use) (expt 2 29)) + (error "failed after zeros:" (current-memory-use))) + (for ([pb (in-list pbs)]) + (set-phantom-bytes! pb (expt 2 29))) + (unless (> (current-memory-use) (* (length pbs) + (expt 2 29))) + (error "failed after restore:" (current-memory-use)))) + +(check) +(collect-garbage) +(check) + +(define mem (make-bytes (* 250 1024 1024))) +(check) +(collect-garbage) +(check) +(set! pbs (cons (make-one) pbs)) +(check) +(collect-garbage) +(check) +(collect-garbage) +(check) + +(void (bytes-length mem)) + +'ok + +(module test racket/base + (require compiler/find-exe + racket/system) + + (define exe (find-exe)) + (unless (system* exe "-l" "tests/racket/phantom-bytes") + (error "run failed")) + + ;; Also try in incremental mode + (void (putenv "PLT_INCREMENTAL_GC" "yes")) + (unless (system* exe "-l" "tests/racket/phantom-bytes") + (error "run failed"))) diff --git a/racket/src/racket/gc2/mem_account.c b/racket/src/racket/gc2/mem_account.c index 4a5257ddb2..fd96b7f691 100644 --- a/racket/src/racket/gc2/mem_account.c +++ b/racket/src/racket/gc2/mem_account.c @@ -529,12 +529,11 @@ static void BTC_do_accounting(NewGC *gc) last = cur; while(cur) { int owner = custodian_to_owner_set(gc, cur); - uintptr_t save_count = gc->phantom_count; GC_ASSERT(owner >= 0); GC_ASSERT(owner <= gc->owner_table_size); - gc->phantom_count = 0; + gc->acct_phantom_count = 0; gc->current_mark_owner = owner; GCDEBUG((DEBUGOUTF,"MARKING THREADS OF OWNER %i (CUST %p)\n", owner, cur)); @@ -550,8 +549,7 @@ static void BTC_do_accounting(NewGC *gc) owner_table = gc->owner_table; owner_table[owner]->memory_use = add_no_overflow(owner_table[owner]->memory_use, - gcBYTES_TO_WORDS(gc->phantom_count)); - gc->phantom_count = save_count; + gcBYTES_TO_WORDS(gc->acct_phantom_count)); } release_master_btc_mark(gc); diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index c78bb6020f..2c3c75273d 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -178,6 +178,7 @@ inline static int page_mmu_type(mpage *page); inline static int page_mmu_protectable(mpage *page); static void free_mpage(mpage *page); static void gen_half_free_mpage(NewGC *gc, mpage *work); +static int inc_marked_gen1(NewGC *gc, void *p); #if defined(MZ_USE_PLACES) && defined(GC_DEBUG_PAGES) static FILE* gcdebugOUT(NewGC *gc) { @@ -1647,10 +1648,19 @@ uintptr_t add_no_overflow(uintptr_t a, uintptr_t b) return c; } +uintptr_t subtract_no_underflow(uintptr_t a, uintptr_t b) +{ + if (a >= b) + return a-b; + else + return 0; +} + int GC_allocate_phantom_bytes(void *pb, intptr_t request_size_bytes) { NewGC *gc = GC_get_GC(); mpage *page; + int inc_count; #ifdef NEWGC_BTC_ACCOUNT if (request_size_bytes > 0) { @@ -1668,20 +1678,30 @@ int GC_allocate_phantom_bytes(void *pb, intptr_t request_size_bytes) page = pagemap_find_page(gc->page_maps, pb); + if (page->generation >= AGE_GEN_1) + inc_count = inc_marked_gen1(gc, pb); + else + inc_count = 0; + if (request_size_bytes < 0) { request_size_bytes = -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; + if (!page || (page->generation < AGE_GEN_1)) + gc->gen0_phantom_count = subtract_no_underflow(gc->gen0_phantom_count, request_size_bytes); + else { + gc->memory_in_use = subtract_no_underflow(gc->memory_in_use, request_size_bytes); + gc->phantom_count = subtract_no_underflow(gc->phantom_count, request_size_bytes); + if (inc_count) + gc->inc_phantom_count = subtract_no_underflow(gc->inc_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); - else + else { gc->memory_in_use = add_no_overflow(gc->memory_in_use, request_size_bytes); + gc->phantom_count = add_no_overflow(gc->phantom_count, request_size_bytes); + if (inc_count) + gc->inc_phantom_count = add_no_overflow(gc->inc_phantom_count, request_size_bytes); + } } /* If we've allocated enough phantom bytes, then force a GC */ @@ -2059,6 +2079,23 @@ inline static int marked(NewGC *gc, const void *p) } } +/* Used outside of GC when an incremental GC might be in progress */ +static int inc_marked_gen1(NewGC *gc, void *p) +{ + if (gc->started_incremental) { + int r; + GC_ASSERT(!gc->check_gen1); + GC_ASSERT(!gc->inc_gen1); + gc->check_gen1 = 1; + gc->inc_gen1 = 1; + r = marked(gc, p); + gc->check_gen1 = 0; + gc->inc_gen1 = 0; + return r; + } else + return 0; +} + static int is_in_generation_half(NewGC *gc, const void *p) { mpage *page; @@ -2594,10 +2631,22 @@ static int mark_phantom(void *p, struct NewGC *gc) Phantom_Bytes *pb = (Phantom_Bytes *)p; if (!gc->during_backpointer) { - if (gc->inc_gen1) + if (gc->doing_memory_accounting) + gc->acct_phantom_count = add_no_overflow(gc->acct_phantom_count, pb->count); + else if (gc->inc_gen1) gc->inc_phantom_count = add_no_overflow(gc->inc_phantom_count, pb->count); - else - gc->phantom_count = add_no_overflow(gc->phantom_count, pb->count); + else { + mpage *page = ((gc->use_gen_half && !gc->inc_gen1) + ? pagemap_find_page(gc->page_maps, pb) + : NULL); + if (page && (page->generation == AGE_GEN_HALF)) { + gc->gen0_phantom_count = add_no_overflow(gc->gen0_phantom_count, pb->count); + } else { + gc->phantom_count = add_no_overflow(gc->phantom_count, pb->count); + if (gc->started_incremental && !gc->gc_full) + gc->inc_phantom_count = add_no_overflow(gc->inc_phantom_count, pb->count); + } + } } return gcBYTES_TO_WORDS(sizeof(Phantom_Bytes)); @@ -5289,10 +5338,10 @@ static void repair_heap(NewGC *gc) } } + /* This calculation will be ignored for a full GC: */ 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 */ @@ -6093,8 +6142,15 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin #endif park_for_inform_callback(gc); gc->GC_collect_inform_callback(is_master, gc->gc_full, do_incremental, - old_mem_use + old_gen0, gc->memory_in_use, - old_mem_allocated, mmu_memory_allocated(gc->mmu)+gc->phantom_count, + /* original memory use: */ + old_mem_use + old_gen0, + /* new memory use; gen0_phantom_count can be non-zero due to + phantom-bytes record in generation 1/2: */ + gc->memory_in_use + gc->gen0_phantom_count, + /* original memory use, including adminstrative structures: */ + old_mem_allocated, + /* new memory use with adminstrative structures: */ + mmu_memory_allocated(gc->mmu)+gc->phantom_count+gc->gen0_phantom_count, gc->child_gc_total); unpark_for_inform_callback(gc); } diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 9b20c77c90..161cd563a8 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -292,9 +292,10 @@ typedef struct NewGC { unsigned short cust_box_tag; unsigned short phantom_tag; - uintptr_t phantom_count; - uintptr_t gen0_phantom_count; - uintptr_t inc_phantom_count; + uintptr_t phantom_count; /* old-generation count; included in `memory_in_use`, except during a minor collection */ + uintptr_t gen0_phantom_count; /* count for generation 0 + 1/2 */ + uintptr_t inc_phantom_count; /* accumulated count for an incremental collection */ + uintptr_t acct_phantom_count; /* count that is set during memory accounting */ Roots roots; struct MMU *mmu; diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index 08a6d60104..2a20f8517e 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -8325,8 +8325,10 @@ 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, pb->size)) + if (!GC_allocate_phantom_bytes(pb, pb->size)) { + pb->size = 0; scheme_raise_out_of_memory("make-phantom-bytes", NULL); + } # endif return (Scheme_Object *)pb; @@ -8335,7 +8337,7 @@ static Scheme_Object *make_phantom_bytes(int argc, Scheme_Object *argv[]) static Scheme_Object *set_phantom_bytes(int argc, Scheme_Object *argv[]) { Scheme_Phantom_Bytes *pb; - intptr_t amt; + intptr_t old_size, amt; if (!SAME_TYPE(SCHEME_TYPE(argv[0]), scheme_phantom_bytes_type)) scheme_wrong_contract("set-phantom-bytes!", "phantom-bytes?", 0, argc, argv); @@ -8345,13 +8347,16 @@ static Scheme_Object *set_phantom_bytes(int argc, Scheme_Object *argv[]) pb = (Scheme_Phantom_Bytes *)argv[0]; amt = SCHEME_INT_VAL(argv[1]); -# ifdef MZ_PRECISE_GC - if (!GC_allocate_phantom_bytes(pb, amt - pb->size)) - scheme_raise_out_of_memory("make-phantom-bytes", NULL); -# endif - + old_size = pb->size; pb->size = amt; +# ifdef MZ_PRECISE_GC + if (!GC_allocate_phantom_bytes(pb, amt - old_size)) { + pb->size = old_size; + scheme_raise_out_of_memory("make-phantom-bytes", NULL); + } +# endif + return scheme_void; } From e9c722cf2293833d5f1b9e983c5899998ba6a90c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 30 Nov 2015 14:23:42 -0700 Subject: [PATCH 117/369] re-tune incremental GC parameters With immobile-object allocation repaired, smaller increments work. --- racket/src/racket/gc2/newgc.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 2c3c75273d..e531030aa4 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -254,8 +254,9 @@ MAYBE_UNUSED static void GCVERBOSEprintf(NewGC *gc, const char *fmt, ...) { /* Incremental mode */ static int always_collect_incremental_on_minor = 0; -#define INCREMENTAL_COLLECT_FUEL_PER_100M (32 * 1024) -#define INCREMENTAL_REPAIR_FUEL_PER_100M 256 +#define INCREMENTAL_COLLECT_FUEL_PER_100M (16 * 1024) +#define INCREMENTAL_REPAIR_FUEL_PER_100M 128 +#define INCREMENTAL_MINOR_REQUEST_DIVISOR 4 /* Conservatively force a major GC after a certain number of minor GCs. It should be ok to set this value @@ -4177,7 +4178,9 @@ static void propagate_incremental_marks(NewGC *gc, int do_emph, int fuel) propagate_marks_worker(gc, p, 1); fuel--; } - } while (do_emph && mark_ready_ephemerons(gc, 1) && fuel); + } while (do_emph + && (fuel || mark_stack_is_empty(gc->inc_mark_stack)) + && mark_ready_ephemerons(gc, 1)); gc->inc_prop_count += (init_fuel - fuel); @@ -5873,12 +5876,10 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin || (gc->started_incremental && mark_stack_is_empty(gc->inc_mark_stack) && gc->finishing_incremental - && !gc->inc_repair_next - && !no_full)); + && !gc->inc_repair_next)); - if (gc->gc_full && no_full) { + if (gc->gc_full && no_full) return; - } next_gc_full = (gc->gc_full && !gc->started_incremental @@ -5987,7 +5988,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin mark_finalizer_structs(gc, 1); if (!mark_stack_is_empty(gc->inc_mark_stack)) { int fuel = (no_full - ? INCREMENTAL_COLLECT_FUEL_PER_100M / 8 + ? INCREMENTAL_COLLECT_FUEL_PER_100M / INCREMENTAL_MINOR_REQUEST_DIVISOR : INCREMENTAL_COLLECT_FUEL_PER_100M * ((gc->memory_in_use / (1024 * 1024 * 100)) + 1)); propagate_incremental_marks(gc, 1, fuel); TIME_STEP("incremented"); @@ -6039,18 +6040,11 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin repair_heap(gc); TIME_STEP("repaired"); if (check_inc_repair) { - if (!gc->inc_repair_next) { - /* Didn't fire a full GC? This shouldn't happend, but if it - does, go back to incremental marking: */ - GC_ASSERT(gc->gc_full); - gc->finishing_incremental = 0; - } else { - int fuel = (no_full - ? INCREMENTAL_REPAIR_FUEL_PER_100M / 8 - : INCREMENTAL_REPAIR_FUEL_PER_100M * ((gc->memory_in_use / (1024 * 1024 * 100)) + 1)); - incremental_repair_pages(gc, fuel); - TIME_STEP("inc-repaired"); - } + int fuel = (no_full + ? INCREMENTAL_REPAIR_FUEL_PER_100M / INCREMENTAL_MINOR_REQUEST_DIVISOR + : INCREMENTAL_REPAIR_FUEL_PER_100M * ((gc->memory_in_use / (1024 * 1024 * 100)) + 1)); + incremental_repair_pages(gc, fuel); + TIME_STEP("inc-repaired"); } clean_up_heap(gc); From d306ecdf3a2ab8a986d833c0332b06b2ba7e4295 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 30 Nov 2015 15:11:50 -0700 Subject: [PATCH 118/369] incremental GC: fix accumulation of page-repair work Too much work was being saved for the final step of a major GC. --- racket/src/racket/gc2/newgc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index e531030aa4..f5a22c2bc2 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -5408,6 +5408,8 @@ static void incremental_repair_pages(NewGC *gc, int fuel) while (fuel && gc->inc_repair_next) { page = gc->inc_repair_next; gc->inc_repair_next = page->inc_modified_next; + if (!gc->inc_repair_next) + gc->inc_repair_next = gc->inc_modified_next; GC_ASSERT(page->generation >= AGE_GEN_1); if (page->generation == AGE_VACATED) { /* skip */ From f30d8bd562ce0ac40bb0442152dac4cc45652731 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 30 Nov 2015 18:27:50 -0700 Subject: [PATCH 119/369] incremental GC: fix overcount of immobile objects --- racket/src/racket/gc2/newgc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index f5a22c2bc2..3cc8a8ad59 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -5276,12 +5276,16 @@ static void repair_heap(NewGC *gc) mark_backpointers. */ void **start = PPTR(NUM(page->addr) + PREFIX_SIZE); void **end = PPTR(NUM(page->addr) + APAGE_SIZE - page->obj_size); + int live_count = 0; while(start < end) { objhead *info = (objhead *)start; if (!info->mark) info->dead = 1; + else + live_count++; start += info->size; } + page->live_size = live_count * gcBYTES_TO_WORDS(page->obj_size); } } else { if ((page->generation == AGE_GEN_0) || gc->gc_full) { From 8363144818c988e91d0278589d9db481f8cf6b77 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 30 Nov 2015 19:12:04 -0700 Subject: [PATCH 120/369] incremental GC: make finalization more incremental --- racket/src/racket/gc2/newgc.c | 78 +++++++++++++++++++++++------------ racket/src/racket/gc2/weak.c | 21 +++++++++- 2 files changed, 70 insertions(+), 29 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 3cc8a8ad59..04c77559b9 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -4158,7 +4158,7 @@ static void propagate_marks_plus_ephemerons(NewGC *gc) } while (mark_ready_ephemerons(gc, 0)); } -static void propagate_incremental_marks(NewGC *gc, int do_emph, int fuel) +static int propagate_incremental_marks(NewGC *gc, int do_emph, int fuel) { if (gc->inc_mark_stack) { int save_inc, save_check, init_fuel = fuel; @@ -4187,6 +4187,8 @@ static void propagate_incremental_marks(NewGC *gc, int do_emph, int fuel) gc->inc_gen1 = save_inc; gc->check_gen1 = save_check; } + + return fuel; } #ifdef MZ_USE_PLACES @@ -5767,16 +5769,23 @@ extern double scheme_get_inexact_milliseconds(void); # define TIME_ARGS /**/ #endif -static void mark_and_finalize_all(NewGC *gc, int old_gen TIME_FORMAL_ARGS) +#define AS_100M(c) ((c / (1024 * 1024 * 100)) + 1) + +static int mark_and_finalize_all(NewGC *gc, int old_gen TIME_FORMAL_ARGS) { + int fuel = (INCREMENTAL_COLLECT_FUEL_PER_100M * AS_100M(gc->memory_in_use)) / 2; + if (!old_gen) propagate_marks_plus_ephemerons(gc); check_finalizers(gc, 1, old_gen); if (!old_gen) propagate_marks_plus_ephemerons(gc); - else - propagate_incremental_marks(gc, 1, -1); + else { + fuel = propagate_incremental_marks(gc, 1, fuel); + if (!fuel) + return 1; + } TIME_STEP("marked"); @@ -5785,8 +5794,16 @@ static void mark_and_finalize_all(NewGC *gc, int old_gen TIME_FORMAL_ARGS) gc->fnl_gen1 = 1; } - zero_weak_boxes(gc, 0, 0, old_gen); - zero_weak_arrays(gc, 0, old_gen); + fuel = zero_weak_boxes(gc, 0, 0, old_gen, (old_gen ? fuel : -1)); + if (old_gen && !fuel) { + gc->fnl_gen1 = 0; + return 1; + } + fuel = zero_weak_arrays(gc, 0, old_gen, (old_gen ? fuel : -1)); + if (old_gen && !fuel) { + gc->fnl_gen1 = 0; + return 1; + } zero_remaining_ephemerons(gc, old_gen); TIME_STEP("zeroed"); @@ -5795,33 +5812,35 @@ static void mark_and_finalize_all(NewGC *gc, int old_gen TIME_FORMAL_ARGS) if (!old_gen) propagate_marks(gc); else - propagate_incremental_marks(gc, 0, -1); - zero_weak_boxes(gc, 1, 0, old_gen); + (void)propagate_incremental_marks(gc, 0, -1); + (void)zero_weak_boxes(gc, 1, 0, old_gen, -1); check_finalizers(gc, 3, old_gen); if (!old_gen) propagate_marks(gc); else - propagate_incremental_marks(gc, 0, -1); + (void)propagate_incremental_marks(gc, 0, -1); if (gc->GC_post_propagate_hook) gc->GC_post_propagate_hook(gc); /* for any new ones that appeared: */ - zero_weak_boxes(gc, 0, 1, old_gen); - zero_weak_boxes(gc, 1, 1, old_gen); - zero_weak_arrays(gc, 1, old_gen); + (void)zero_weak_boxes(gc, 0, 1, old_gen, -1); + (void)zero_weak_boxes(gc, 1, 1, old_gen, -1); + (void)zero_weak_arrays(gc, 1, old_gen, -1); zero_remaining_ephemerons(gc, old_gen); if (old_gen) gc->fnl_gen1 = 0; TIME_STEP("finalized"); + + return 0; } -static void mark_and_finalize_all_incremental(NewGC *gc TIME_FORMAL_ARGS) +static int mark_and_finalize_all_incremental(NewGC *gc TIME_FORMAL_ARGS) { - int save_inc, save_check; + int save_inc, save_check, more_to_do; GC_ASSERT(gc->mark_gen1); @@ -5831,10 +5850,12 @@ static void mark_and_finalize_all_incremental(NewGC *gc TIME_FORMAL_ARGS) gc->inc_gen1 = 1; gc->check_gen1 = 1; - mark_and_finalize_all(gc, 1 TIME_ARGS); + more_to_do = mark_and_finalize_all(gc, 1 TIME_ARGS); gc->inc_gen1 = save_inc; gc->check_gen1 = save_check; + + return more_to_do; } /* Full GCs trigger finalization. Finalization releases data @@ -5987,7 +6008,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin /* now propagate/repair the marks we got from these roots, and do the finalizer passes */ - mark_and_finalize_all(gc, 0 TIME_ARGS); + (void)mark_and_finalize_all(gc, 0 TIME_ARGS); if (do_incremental) { if (!gc->finishing_incremental) { @@ -5995,19 +6016,22 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (!mark_stack_is_empty(gc->inc_mark_stack)) { int fuel = (no_full ? INCREMENTAL_COLLECT_FUEL_PER_100M / INCREMENTAL_MINOR_REQUEST_DIVISOR - : INCREMENTAL_COLLECT_FUEL_PER_100M * ((gc->memory_in_use / (1024 * 1024 * 100)) + 1)); - propagate_incremental_marks(gc, 1, fuel); + : INCREMENTAL_COLLECT_FUEL_PER_100M * AS_100M(gc->memory_in_use)); + (void)propagate_incremental_marks(gc, 1, fuel); TIME_STEP("incremented"); } else { /* We ran out of incremental marking work, so - perform major-GC finalization in one go. */ - mark_and_finalize_all_incremental(gc TIME_ARGS); - BTC_clean_up_gen1(gc); - reset_gen1_finalizer_tree(gc); - /* Switch to incrementally reparing pages before propagating - marks again. */ - gc->finishing_incremental = 1; - gc->inc_repair_next = gc->inc_modified_next; + perform major-GC finalization */ + if (mark_and_finalize_all_incremental(gc TIME_ARGS)) { + /* More finalizaton work to do */ + reset_gen1_finalizer_tree(gc); + } else { + BTC_clean_up_gen1(gc); + reset_gen1_finalizer_tree(gc); + /* Switch to incrementally reparing pages */ + gc->finishing_incremental = 1; + gc->inc_repair_next = gc->inc_modified_next; + } } check_inc_repair = 0; } else @@ -6048,7 +6072,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (check_inc_repair) { int fuel = (no_full ? INCREMENTAL_REPAIR_FUEL_PER_100M / INCREMENTAL_MINOR_REQUEST_DIVISOR - : INCREMENTAL_REPAIR_FUEL_PER_100M * ((gc->memory_in_use / (1024 * 1024 * 100)) + 1)); + : INCREMENTAL_REPAIR_FUEL_PER_100M * AS_100M(gc->memory_in_use)); incremental_repair_pages(gc, fuel); TIME_STEP("inc-repaired"); } diff --git a/racket/src/racket/gc2/weak.c b/racket/src/racket/gc2/weak.c index 0bdb777a4f..ec72239f86 100644 --- a/racket/src/racket/gc2/weak.c +++ b/racket/src/racket/gc2/weak.c @@ -167,7 +167,7 @@ static GC_Weak_Array *append_weak_arrays(GC_Weak_Array *wa, GC_Weak_Array *bp_wa return bp_wa; } -static void zero_weak_arrays(GCTYPE *gc, int force_zero, int from_inc) +static int zero_weak_arrays(GCTYPE *gc, int force_zero, int from_inc, int fuel) { GC_Weak_Array *wa; int i, num_gen0; @@ -192,6 +192,8 @@ static void zero_weak_arrays(GCTYPE *gc, int force_zero, int from_inc) else data[i] = GC_resolve2(p, gc); } + if (fuel > 0) + fuel = ((fuel > wa->count) ? (fuel - wa->count) : 0); if (num_gen0 > 0) { if (!is_in_generation_half(gc, wa)) { @@ -217,6 +219,8 @@ static void zero_weak_arrays(GCTYPE *gc, int force_zero, int from_inc) gc->weak_arrays = NULL; gc->bp_weak_arrays = NULL; } + + return fuel; } /******************************************************************************/ @@ -367,7 +371,7 @@ static GC_Weak_Box *append_weak_boxes(GC_Weak_Box *wb, GC_Weak_Box *bp_wb, int * return bp_wb; } -static void zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero, int from_inc) +static int zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero, int from_inc, int fuel) { GC_Weak_Box *wb; int num_gen0; @@ -426,7 +430,18 @@ static void zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero, int from_in wb = next; } else wb = wb->next; + num_gen0--; + + if (fuel >= 0) { + if (fuel > 0) + fuel--; + else { + GC_ASSERT(from_inc); + gc->inc_weak_boxes[is_late] = wb; + return 0; + } + } } /* reset, in case we have a second round */ @@ -436,6 +451,8 @@ static void zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero, int from_in gc->weak_boxes[is_late] = NULL; gc->bp_weak_boxes[is_late] = NULL; } + + return fuel; } /******************************************************************************/ From 03302c3f30edb18b73ecdf1ba2fb05f672fa5ea2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 30 Nov 2015 19:54:07 -0700 Subject: [PATCH 121/369] repair an assertion in the GC --- racket/src/racket/gc2/newgc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 04c77559b9..14683e8f75 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -3701,6 +3701,9 @@ static void page_newly_marked_on(NewGC *gc, mpage *page, int is_a_master_page, i { if (inc_gen1) { GC_ASSERT(!page->inc_marked_on); + /* If this page isn't already marked as old, it must be a medium page whose + generation will be updated in the clean-up phase */ + GC_ASSERT((page->generation >= AGE_GEN_1) || (page->size_class == SIZE_CLASS_MED_PAGE)); page->inc_marked_on = 1; page->inc_modified_next = gc->inc_modified_next; gc->inc_modified_next = page; @@ -5416,7 +5419,9 @@ static void incremental_repair_pages(NewGC *gc, int fuel) gc->inc_repair_next = page->inc_modified_next; if (!gc->inc_repair_next) gc->inc_repair_next = gc->inc_modified_next; - GC_ASSERT(page->generation >= AGE_GEN_1); + /* If this page isn't already marked as old, it must be a medium page whose + generation will be updated in the clean-up phase */ + GC_ASSERT((page->generation >= AGE_GEN_1) || (page->size_class == SIZE_CLASS_MED_PAGE)); if (page->generation == AGE_VACATED) { /* skip */ } else if (page->size_class >= SIZE_CLASS_BIG_PAGE) { From bef34606cb0f7987cf5cfbb5a9201d38d0e4283b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 1 Dec 2015 04:18:52 -0700 Subject: [PATCH 122/369] incremental GC: fix handling of ephemerons Fix the case that an old-generation finalizer ends up on a modified page after all old-generation marking is complete. Also, make sure epehemerons are checked after previous marking that may have left the stack empty. --- racket/src/racket/gc2/newgc.c | 40 +++++++++++++++++------------------ racket/src/racket/gc2/weak.c | 9 +++++++- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 14683e8f75..ed74ea0823 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -4163,33 +4163,29 @@ static void propagate_marks_plus_ephemerons(NewGC *gc) static int propagate_incremental_marks(NewGC *gc, int do_emph, int fuel) { - if (gc->inc_mark_stack) { - int save_inc, save_check, init_fuel = fuel; + int save_inc, save_check, init_fuel = fuel; - GC_ASSERT(gc->mark_gen1); + GC_ASSERT(gc->mark_gen1); - save_inc = gc->inc_gen1; - save_check = gc->check_gen1; + save_inc = gc->inc_gen1; + save_check = gc->check_gen1; - gc->inc_gen1 = 1; - gc->check_gen1 = 1; + gc->inc_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 (do_emph - && (fuel || mark_stack_is_empty(gc->inc_mark_stack)) - && mark_ready_ephemerons(gc, 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 (do_emph && fuel && mark_ready_ephemerons(gc, 1)); - gc->inc_prop_count += (init_fuel - fuel); + gc->inc_prop_count += (init_fuel - fuel); - gc->inc_gen1 = save_inc; - gc->check_gen1 = save_check; - } + gc->inc_gen1 = save_inc; + gc->check_gen1 = save_check; return fuel; } @@ -5782,6 +5778,8 @@ static int mark_and_finalize_all(NewGC *gc, int old_gen TIME_FORMAL_ARGS) if (!old_gen) propagate_marks_plus_ephemerons(gc); + else + (void)propagate_incremental_marks(gc, 1, -1); check_finalizers(gc, 1, old_gen); if (!old_gen) diff --git a/racket/src/racket/gc2/weak.c b/racket/src/racket/gc2/weak.c index ec72239f86..74aa1bcc00 100644 --- a/racket/src/racket/gc2/weak.c +++ b/racket/src/racket/gc2/weak.c @@ -474,7 +474,14 @@ static int mark_ephemeron(void *p, struct NewGC *gc) eph->inc_next = gc->inc_ephemerons; gc->inc_ephemerons = eph; } else if (gc->during_backpointer) { - if (!gc->gc_full) { + if (!gc->gc_full + /* If this old-generation object is not yet marked + and we're finishing an incremental pass, then + it won't get marked (and it can only refer to + other old-generation objects), so ignore in that case */ + && (gc->mark_gen1 + || !gc->started_incremental + || !gc->finishing_incremental)) { eph->next = gc->bp_ephemerons; gc->bp_ephemerons = eph; } From 7e949d55131d54bf9b8499089ceb061c2fcaed13 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 1 Dec 2015 08:14:38 -0700 Subject: [PATCH 123/369] GC: skip memory accounting if demand goes away Memory accounting is enabled on demand; if demand goes away --- as approximated by no live custodians having a limit or previously been queried for memory use --- then stop accounting until demand resumes. --- racket/src/racket/gc2/backtrace.c | 3 --- racket/src/racket/gc2/mem_account.c | 21 +++++++++++++++++---- racket/src/racket/gc2/newgc.h | 1 + racket/src/racket/include/schthread.h | 1 - racket/src/racket/src/schpriv.h | 1 + racket/src/racket/src/thread.c | 7 ------- 6 files changed, 19 insertions(+), 15 deletions(-) diff --git a/racket/src/racket/gc2/backtrace.c b/racket/src/racket/gc2/backtrace.c index 0d57afc930..0be2659c1c 100644 --- a/racket/src/racket/gc2/backtrace.c +++ b/racket/src/racket/gc2/backtrace.c @@ -12,7 +12,6 @@ trace_page_type TRACE_PAGE_TAGGED TRACE_PAGE_ARRAY - TRACE_PAGE_TAGGED_ARRAY TRACE_PAGE_ATOMIC TRACE_PAGE_PAIR TRACE_PAGE_MALLOCFREE @@ -73,8 +72,6 @@ static void *print_out_pointer(const char *prefix, void *p, what = NULL; } else if (trace_page_type(page) == TRACE_PAGE_ARRAY) { what = "ARRAY"; - } else if (trace_page_type(page) == TRACE_PAGE_TAGGED_ARRAY) { - what = "TARRAY"; } else if (trace_page_type(page) == TRACE_PAGE_ATOMIC) { what = "ATOMIC"; } else if (trace_page_type(page) == TRACE_PAGE_MALLOCFREE) { diff --git a/racket/src/racket/gc2/mem_account.c b/racket/src/racket/gc2/mem_account.c index fd96b7f691..ea3e8ffbdf 100644 --- a/racket/src/racket/gc2/mem_account.c +++ b/racket/src/racket/gc2/mem_account.c @@ -225,21 +225,27 @@ inline static void clean_up_owner_table(NewGC *gc) { OTEntry **owner_table = gc->owner_table; const int table_size = gc->owner_table_size; - int i; + int i, really_doing_accounting = 0; for(i = 1; i < table_size; i++) if(owner_table[i]) { /* repair or delete the originator */ if(!marked(gc, owner_table[i]->originator)) { owner_table[i]->originator = NULL; - } else + } else { owner_table[i]->originator = GC_resolve2(owner_table[i]->originator, gc); + if (((Scheme_Custodian *)owner_table[i]->originator)->really_doing_accounting) { + really_doing_accounting = 1; + } + } /* potential delete */ if(i != 1) if((owner_table[i]->memory_use == 0) && !owner_table[i]->originator) free_owner_set(gc, i); } + + gc->next_really_doing_accounting |= really_doing_accounting; } inline static uintptr_t custodian_usage(NewGC*gc, void *custodian) @@ -248,11 +254,13 @@ inline static uintptr_t custodian_usage(NewGC*gc, void *custodian) uintptr_t retval = 0; int i; + ((Scheme_Custodian *)custodian)->really_doing_accounting = 1; + if(!gc->really_doing_accounting) { if (!gc->avoid_collection) { CHECK_PARK_UNUSED(gc); gc->park[0] = custodian; - gc->really_doing_accounting = 1; + gc->next_really_doing_accounting = 1; garbage_collect(gc, 1, 0, 0, NULL); custodian = gc->park[0]; gc->park[0] = NULL; @@ -496,6 +504,9 @@ static void BTC_do_accounting(NewGC *gc) const int table_size = gc->owner_table_size; OTEntry **owner_table = gc->owner_table; + gc->really_doing_accounting = gc->next_really_doing_accounting; + gc->next_really_doing_accounting = 0; + if(gc->really_doing_accounting) { Scheme_Custodian *cur = owner_table[current_owner(gc, NULL)]->originator, *last, *parent; Scheme_Custodian_Reference *box = cur->global_next; @@ -584,12 +595,14 @@ inline static void BTC_add_account_hook(int type,void *c1,void *c2,uintptr_t b) NewGC *gc = GC_get_GC(); AccountHook *work; + ((Scheme_Custodian *)c1)->really_doing_accounting = 1; + if(!gc->really_doing_accounting) { if (!gc->avoid_collection) { CHECK_PARK_UNUSED(gc); gc->park[0] = c1; gc->park[1] = c2; - gc->really_doing_accounting = 1; + gc->next_really_doing_accounting = 1; garbage_collect(gc, 1, 0, 0, NULL); c1 = gc->park[0]; gc->park[0] = NULL; c2 = gc->park[1]; gc->park[1] = NULL; diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 161cd563a8..5ae5ca5a5f 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -222,6 +222,7 @@ typedef struct NewGC { /* blame the child */ unsigned int doing_memory_accounting :1; unsigned int really_doing_accounting :1; + unsigned int next_really_doing_accounting :1; unsigned int old_btc_mark :1; unsigned int new_btc_mark :1; unsigned int reset_limits :1; diff --git a/racket/src/racket/include/schthread.h b/racket/src/racket/include/schthread.h index e614cf1842..817f6a3c3e 100644 --- a/racket/src/racket/include/schthread.h +++ b/racket/src/racket/include/schthread.h @@ -267,7 +267,6 @@ typedef struct Thread_Local_Variables { intptr_t scheme_current_cont_mark_stack_; intptr_t scheme_current_cont_mark_pos_; struct Scheme_Custodian *main_custodian_; - struct Scheme_Custodian *last_custodian_; struct Scheme_Hash_Table *limited_custodians_; struct Scheme_Plumber *initial_plumber_; struct Scheme_Config *initial_config_; diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 3f7c44a964..a06b2eca72 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -755,6 +755,7 @@ struct Scheme_Custodian { int gc_owner_set; Scheme_Object *cust_boxes; int num_cust_boxes, checked_cust_boxes; + int really_doing_accounting; #endif }; diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index 2a20f8517e..6f74a870bf 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -191,7 +191,6 @@ THREAD_LOCAL_DECL(MZ_MARK_POS_TYPE scheme_current_cont_mark_pos); THREAD_LOCAL_DECL(int scheme_semaphore_fd_kqueue); THREAD_LOCAL_DECL(static Scheme_Custodian *main_custodian); -THREAD_LOCAL_DECL(static Scheme_Custodian *last_custodian); THREAD_LOCAL_DECL(static Scheme_Hash_Table *limited_custodians = NULL); READ_ONLY static Scheme_Object *initial_inspector; @@ -1084,8 +1083,6 @@ static void adjust_custodian_family(void *mgr, void *skip_move) /* Remove from global list: */ if (CUSTODIAN_FAM(r->global_next)) CUSTODIAN_FAM(CUSTODIAN_FAM(r->global_next)->global_prev) = CUSTODIAN_FAM(r->global_prev); - else - last_custodian = CUSTODIAN_FAM(r->global_prev); CUSTODIAN_FAM(CUSTODIAN_FAM(r->global_prev)->global_next) = CUSTODIAN_FAM(r->global_next); /* Add children to parent's list: */ @@ -1159,8 +1156,6 @@ void insert_custodian(Scheme_Custodian *m, Scheme_Custodian *parent) CUSTODIAN_FAM(parent->global_next) = m; if (next) CUSTODIAN_FAM(next->global_prev) = m; - else - last_custodian = m; } else { CUSTODIAN_FAM(m->global_next) = NULL; CUSTODIAN_FAM(m->global_prev) = NULL; @@ -7988,13 +7983,11 @@ static void make_initial_config(Scheme_Thread *p) init_param(cells, paramz, MZCONFIG_ERROR_PRINT_SRCLOC, scheme_true); REGISTER_SO(main_custodian); - REGISTER_SO(last_custodian); REGISTER_SO(limited_custodians); main_custodian = scheme_make_custodian(NULL); #ifdef MZ_PRECISE_GC GC_register_root_custodian(main_custodian); #endif - last_custodian = main_custodian; init_param(cells, paramz, MZCONFIG_CUSTODIAN, (Scheme_Object *)main_custodian); REGISTER_SO(initial_plumber); From b175241961a9b70ae7b85c39977ecae61743d159 Mon Sep 17 00:00:00 2001 From: Gustavo Massaccesi Date: Wed, 18 Nov 2015 00:20:22 -0300 Subject: [PATCH 124/369] Flatten nested begin and begin0 forms The nested begin/begin0 are flattened at read time, but some optimizations may create new instances. --- .../tests/racket/optimize.rktl | 26 ++++++ racket/src/racket/src/optimize.c | 92 ++++++++++++++++--- 2 files changed, 105 insertions(+), 13 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index 43a0abae7f..72366f37f0 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -1528,6 +1528,32 @@ (test-comp '(lambda () (begin (random 1) (random 2))) '(lambda () (cdr (cons (random 1) (random 2))))) +(test-comp '(lambda () (begin (random 1) (random 2) (random 3) (random 4))) + '(lambda () (begin (car (cons (random 1) (random 2))) (random 3) (random 4)))) ; +(test-comp '(lambda () (begin (random 1) (random 2) (random 3) (random 4))) + '(lambda () (begin (cdr (cons (random 1) (random 2))) (random 3) (random 4)))) +(test-comp '(lambda () (begin (random 1) (random 2) (random 3) (random 4))) + '(lambda () (begin (random 1) (car (cons (random 2) (random 3))) (random 4)))) ; +(test-comp '(lambda () (begin (random 1) (random 2) (random 3) (random 4))) + '(lambda () (begin (random 1) (cdr (cons (random 2) (random 3))) (random 4)))) +(test-comp '(lambda () (begin (random 1) (random 2) (begin0 (random 3) (random 4)))) + '(lambda () (begin (random 1) (random 2) (car (cons (random 3) (random 4)))))) +(test-comp '(lambda () (begin (random 1) (random 2) (random 3) (random 4))) + '(lambda () (begin (random 1) (random 2) (cdr (cons (random 3) (random 4)))))) + +(test-comp '(lambda () (begin0 (random 1) (random 2) (random 3) (random 4))) + '(lambda () (begin0 (car (cons (random 1) (random 2))) (random 3) (random 4)))) +(test-comp '(lambda () (begin0 (begin (random 1) (random 2)) (random 3) (random 4))) + '(lambda () (begin0 (cdr (cons (random 1) (random 2))) (random 3) (random 4)))) +(test-comp '(lambda () (begin0 (random 1) (random 2) (random 3) (random 4))) + '(lambda () (begin0 (random 1) (car (cons (random 2) (random 3))) (random 4)))) ; +(test-comp '(lambda () (begin0 (random 1) (random 2) (random 3) (random 4))) + '(lambda () (begin0 (random 1) (cdr (cons (random 2) (random 3))) (random 4)))) +(test-comp '(lambda () (begin0 (random 1) (random 2) (random 3) (random 4))) + '(lambda () (begin0 (random 1) (random 2) (car (cons (random 3) (random 4)))))) ; +(test-comp '(lambda () (begin0 (random 1) (random 2) (random 3) (random 4))) + '(lambda () (begin0 (random 1) (random 2) (cdr (cons (random 3) (random 4)))))) + (test-comp '(lambda (w) (begin (random) w)) '(lambda (w) diff --git a/racket/src/racket/src/optimize.c b/racket/src/racket/src/optimize.c index f1c0cd0cae..c3fdc6493a 100644 --- a/racket/src/racket/src/optimize.c +++ b/racket/src/racket/src/optimize.c @@ -71,7 +71,7 @@ struct Optimize_Info 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; + short inline_fuel, shift_fuel, flatten_fuel; char letrec_not_twice, enforce_const, use_psize, has_nonleaf; Scheme_Hash_Table *top_level_consts; @@ -100,6 +100,7 @@ struct Optimize_Info typedef struct Optimize_Info_Sequence { int init_shift_fuel, min_shift_fuel; + int init_flatten_fuel, min_flatten_fuel; } Optimize_Info_Sequence; #define OPT_IS_MUTATED 0x1 @@ -3949,6 +3950,62 @@ Scheme_Object *scheme_optimize_apply_values(Scheme_Object *f, Scheme_Object *e, } } +static Scheme_Object *flatten_sequence(Scheme_Object *o, Optimize_Info *info) +{ + Scheme_Sequence *s = (Scheme_Sequence *)o, *s2, *s3; + Scheme_Object *o3; + int i, j, k, count, extra = 0, split = 0, b0; + + if (SAME_TYPE(SCHEME_TYPE(o), scheme_splice_sequence_type)) + return o; + + if (!info->flatten_fuel) + return o; + + b0 = SAME_TYPE(SCHEME_TYPE(o), scheme_begin0_sequence_type); + count = s->count; + + /* exceptions: (begin ... (begin0 ...)) and (begin0 (begin ...) ...) */ + for (i = 0; i < count; i++) { + o3 = s->array[i]; + if ((SAME_TYPE(SCHEME_TYPE(o3), scheme_sequence_type) && !(!i && b0)) + || (SAME_TYPE(SCHEME_TYPE(o3), scheme_begin0_sequence_type) && !(i == count - 1 && !b0))) { + s3 = (Scheme_Sequence *)o3; + extra += s3->count; + split++; + } + } + + if (!split) + return o; + + info->flatten_fuel--; + info->size -= split; + + s2 = scheme_malloc_sequence(s->count + extra - split); + s2->so.type = s->so.type; + s2->count = s->count + extra - split; + k = 0; + + /* exceptions: (begin ... (begin0 ...)) and (begin0 (begin ...) ...) */ + for (i = 0; i < count; i++) { + o3 = s->array[i]; + if ((SAME_TYPE(SCHEME_TYPE(o3), scheme_sequence_type) && !(!i && b0)) + || (SAME_TYPE(SCHEME_TYPE(o3), scheme_begin0_sequence_type) && !(i == count - 1 && !b0))) { + s3 = (Scheme_Sequence *)o3; + for (j = 0; j < s3->count; j++) { + s2->array[k++] = s3->array[j]; + } + } else { + s2->array[k++] = o3; + } + } + + if (k != s2->count) scheme_signal_error("internal error: flatten failed"); + + return (Scheme_Object *)s2; +} + static Scheme_Object *optimize_sequence(Scheme_Object *o, Optimize_Info *info, int context) { Scheme_Sequence *s = (Scheme_Sequence *)o; @@ -3989,7 +4046,7 @@ static Scheme_Object *optimize_sequence(Scheme_Object *o, Optimize_Info *info, i single_result = info->single_result; preserves_marks = info->preserves_marks; - /* Move to last position in case the begin form is droped */ + /* Move to last position in case the begin form is dropped */ s->array[count - 1] = le; for (j = i; j < count - 1; j++) { drop++; @@ -4005,9 +4062,10 @@ static Scheme_Object *optimize_sequence(Scheme_Object *o, Optimize_Info *info, i info->preserves_marks = preserves_marks; info->single_result = single_result; - if (drop + 1 == s->count) { + if (drop + 1 == s->count) return s->array[drop]; - } else if (drop) { + + if (drop) { Scheme_Sequence *s2; int j = 0; @@ -4017,14 +4075,14 @@ static Scheme_Object *optimize_sequence(Scheme_Object *o, Optimize_Info *info, i for (i = 0; i < s->count; i++) { if (s->array[i]) { - s2->array[j++] = s->array[i]; + s2->array[j++] = s->array[i]; } } s = s2; } - return (Scheme_Object *)s; + return flatten_sequence((Scheme_Object *)s, info); } XFORM_NONGCING static int small_inline_number(Scheme_Object *o) @@ -5001,8 +5059,7 @@ case_lambda_shift(Scheme_Object *data, int delta, int after_depth) return data; } -static Scheme_Object * -begin0_optimize(Scheme_Object *obj, Optimize_Info *info, int context) +static Scheme_Object *begin0_optimize(Scheme_Object *obj, Optimize_Info *info, int context) { int i, count, drop = 0, prev_size, single_result = 0, preserves_marks = 0, kclock = 0, sclock = 0; Scheme_Sequence *s = (Scheme_Sequence *)obj; @@ -5066,7 +5123,7 @@ begin0_optimize(Scheme_Object *obj, Optimize_Info *info, int context) info->preserves_marks = 1; if (i != 0) { - /* We will ignore the first expresion too */ + /* We will ignore the first expression too */ le = optimize_ignored(s->array[0], info, 0, -1, 1, 5); if (!le) { drop++; @@ -5091,7 +5148,7 @@ begin0_optimize(Scheme_Object *obj, Optimize_Info *info, int context) s2->array[j++] = s->array[i]; } } - return (Scheme_Object *)s2; + return flatten_sequence((Scheme_Object *)s2, info); } info->preserves_marks = 1; @@ -5133,8 +5190,7 @@ begin0_optimize(Scheme_Object *obj, Optimize_Info *info, int context) s2->array[j++] = s->array[i]; } } - if (!info->escapes) - s2->array[j++] = expr; + s2->array[j++] = expr; expr = (Scheme_Object *)s2; } @@ -5162,7 +5218,7 @@ begin0_optimize(Scheme_Object *obj, Optimize_Info *info, int context) } info->size += 1; - + expr = flatten_sequence(expr, info); return replace_tail_inside(expr, inside, orig_first); } @@ -8402,6 +8458,7 @@ Optimize_Info *scheme_optimize_info_create(Comp_Prefix *cp, int get_logger) #endif info->inline_fuel = 32; info->shift_fuel = 16; + info->flatten_fuel = 16; info->cp = cp; if (get_logger) { @@ -8418,6 +8475,8 @@ static void optimize_info_seq_init(Optimize_Info *info, Optimize_Info_Sequence * { info_seq->init_shift_fuel = info->shift_fuel; info_seq->min_shift_fuel = info->shift_fuel; + info_seq->init_flatten_fuel = info->flatten_fuel; + info_seq->min_flatten_fuel = info->flatten_fuel; } static void optimize_info_seq_step(Optimize_Info *info, Optimize_Info_Sequence *info_seq) @@ -8425,12 +8484,17 @@ static void optimize_info_seq_step(Optimize_Info *info, Optimize_Info_Sequence * if (info->shift_fuel < info_seq->min_shift_fuel) info_seq->min_shift_fuel = info->shift_fuel; info->shift_fuel = info_seq->init_shift_fuel; + if (info->flatten_fuel < info_seq->min_flatten_fuel) + info_seq->min_flatten_fuel = info->flatten_fuel; + info->flatten_fuel = info_seq->init_flatten_fuel; } static void optimize_info_seq_done(Optimize_Info *info, Optimize_Info_Sequence *info_seq) { if (info->shift_fuel > info_seq->min_shift_fuel) info->shift_fuel = info_seq->min_shift_fuel; + if (info->flatten_fuel > info_seq->min_flatten_fuel) + info->flatten_fuel = info_seq->min_flatten_fuel; } void scheme_optimize_info_enforce_const(Optimize_Info *oi, int enforce_const) @@ -9043,6 +9107,7 @@ static Optimize_Info *optimize_info_add_frame(Optimize_Info *info, int orig, int naya->new_frame = current; naya->inline_fuel = info->inline_fuel; naya->shift_fuel = info->shift_fuel; + naya->flatten_fuel = info->flatten_fuel; naya->letrec_not_twice = info->letrec_not_twice; naya->enforce_const = info->enforce_const; naya->top_level_consts = info->top_level_consts; @@ -9091,6 +9156,7 @@ static void optimize_info_done(Optimize_Info *info, Optimize_Info *parent) parent->escapes = info->escapes; parent->psize += info->psize; parent->shift_fuel = info->shift_fuel; + parent->flatten_fuel = info->flatten_fuel; if (info->has_nonleaf) parent->has_nonleaf = 1; } From 67bf4349ca796e966dd294c5b2886131d5293188 Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Tue, 1 Dec 2015 14:17:50 -0500 Subject: [PATCH 125/369] Revert "Assume that files that start with . are not modules" This reverts commit fc342924862be8b0f5e8d9ae1033ec622761bd04. --- racket/collects/compiler/module-suffix.rkt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/racket/collects/compiler/module-suffix.rkt b/racket/collects/compiler/module-suffix.rkt index 8823915d54..f600ef7967 100644 --- a/racket/collects/compiler/module-suffix.rkt +++ b/racket/collects/compiler/module-suffix.rkt @@ -52,8 +52,7 @@ (define suffixes (get-module-suffixes #:mode key #:group group #:namespace namespace)) (byte-pregexp - (bytes-append #"^([^.].*)\\.(?i:" + (bytes-append #"^(.*)\\.(?i:" (apply bytes-append (add-between suffixes #"|")) #")$"))) - From d56e7309ad1b79420ec3aa62d81a93ef16113d83 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 1 Dec 2015 16:12:30 -0700 Subject: [PATCH 126/369] GC: fix yet another problem counting allocated bytes --- racket/src/racket/gc2/newgc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index ed74ea0823..decc2122fe 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -1353,7 +1353,9 @@ static int TAKE_SLOW_PATH() #endif inline static size_t gen0_size_in_use(NewGC *gc) { - return (gc->gen0.current_size + ((GC_gen0_alloc_page_ptr - NUM(gc->gen0.curr_alloc_page->addr)) - PREFIX_SIZE)); + return (gc->gen0.current_size + (gc->gen0.curr_alloc_page + ? ((GC_gen0_alloc_page_ptr - NUM(gc->gen0.curr_alloc_page->addr)) - PREFIX_SIZE) + : 0)); } #define BYTES_MULTIPLE_OF_WORD_TO_WORDS(sizeb) ((sizeb) >> gcLOG_WORD_SIZE) @@ -1405,7 +1407,9 @@ inline static uintptr_t allocate_slowpath(NewGC *gc, size_t allocate_size, uintp #ifdef INSTRUMENT_PRIMITIVES LOG_PRIM_START(((void*)garbage_collect)); #endif - + + gc->gen0.curr_alloc_page = NULL; /* so the memory use is not counted */ + collect_now(gc, 0, 0); #ifdef INSTRUMENT_PRIMITIVES From 345b1a8187a2b025f0c49d1fe3e7ea9cd6bb17ab Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 1 Dec 2015 17:47:29 -0700 Subject: [PATCH 127/369] refine the Guide section in incremental GC --- pkgs/racket-doc/scribblings/guide/performance.scrbl | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/pkgs/racket-doc/scribblings/guide/performance.scrbl b/pkgs/racket-doc/scribblings/guide/performance.scrbl index 6fade46141..d0a9970572 100644 --- a/pkgs/racket-doc/scribblings/guide/performance.scrbl +++ b/pkgs/racket-doc/scribblings/guide/performance.scrbl @@ -583,13 +583,10 @@ garbage collected, and thus the red fish is not either. By default, Racket's @tech{generational garbage collector} creates brief pauses for frequent @deftech{minor collections}, which inspect only the most recently allocated objects, and long pauses for infrequent -@deftech{major collections}, which re-inspect all memory. Weak -references (as described in -@secref["Reachability\x20and\x20Garbage\x20Collection"]) are cleared -only by a major collection. +@deftech{major collections}, which re-inspect all memory. -For soft real-time applications, such as animations, games, and some -network services, long pauses due to a major collection can interfere +For some applications, such as animations and games, +long pauses due to a major collection can interfere unacceptably with a program's operation. To reduce major-collection pauses, the Racket garbage collector supports @deftech{incremental garbage-collection} mode. In incremental mode, minor collections @@ -598,7 +595,7 @@ work toward the next major collection. If all goes well, most of a major collection's work has been performed by minor collections the time that a major collection is needed, so the major collection's pause is as short as a minor collection's pause. Incremental mode -tends to use more memory and run more slowly overall, but it can +tends to run more slowly overall, but it can provide much more consistent real-time behavior. If the @envvar{PLT_INCREMENTAL_GC} environment variable is set when @@ -612,7 +609,7 @@ Calling @racket[(collect-garbage 'incremental)] does not perform an immediate garbage collection, but instead requests that each minor collection perform incremental work up to the next major collection. The request expires with the next major collection. Make a call to -@racket[(collect-garbage 'incremental)] in any periodic task within +@racket[(collect-garbage 'incremental)] in any repeating task within an application that needs to be responsive in real time. Force a full collection with @racket[(collect-garbage)] just before an initial @racket[(collect-garbage 'incremental)] to initiate incremental mode From a6eb00a41cc29859424335f40ef9ae68c471c57a Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Tue, 1 Dec 2015 14:21:57 -0500 Subject: [PATCH 128/369] Avoid warning for unused variable. --- racket/src/racket/src/thread.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index 6f74a870bf..e06c1c27c5 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -8330,7 +8330,10 @@ static Scheme_Object *make_phantom_bytes(int argc, Scheme_Object *argv[]) static Scheme_Object *set_phantom_bytes(int argc, Scheme_Object *argv[]) { Scheme_Phantom_Bytes *pb; - intptr_t old_size, amt; + intptr_t amt; +# ifdef MZ_PRECISE_GC + intptr_t old_size; +# endif if (!SAME_TYPE(SCHEME_TYPE(argv[0]), scheme_phantom_bytes_type)) scheme_wrong_contract("set-phantom-bytes!", "phantom-bytes?", 0, argc, argv); @@ -8340,7 +8343,10 @@ static Scheme_Object *set_phantom_bytes(int argc, Scheme_Object *argv[]) pb = (Scheme_Phantom_Bytes *)argv[0]; amt = SCHEME_INT_VAL(argv[1]); +# ifdef MZ_PRECISE_GC old_size = pb->size; +#endif + pb->size = amt; # ifdef MZ_PRECISE_GC From 724dc2fdbfe65fbeecf3f5c331d5956b9ab5c50a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 2 Dec 2015 10:00:15 -0700 Subject: [PATCH 129/369] fix `namespace-mapped-symbols` forcing of lazy binding info --- .../racket-test-core/tests/racket/module.rktl | 33 +++++++++++++++++++ racket/src/racket/src/syntax.c | 26 +++++++-------- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/module.rktl b/pkgs/racket-test-core/tests/racket/module.rktl index dab843cf3f..32b05057a8 100644 --- a/pkgs/racket-test-core/tests/racket/module.rktl +++ b/pkgs/racket-test-core/tests/racket/module.rktl @@ -1670,6 +1670,39 @@ case of module-leve bindings; it doesn't cover local bindings. #;(log-error "go") (eval #f)))))) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check `namespace-mapped-symbols` and modidx shifting + +(let () + (define tmp (make-temporary-file "~a-module-test" 'directory)) + (parameterize ([current-directory tmp] + [current-load-relative-directory tmp]) + (make-directory "compiled") + (call-with-output-file* + "compiled/a_rkt.zo" + (lambda (o) (write (compile '(module a racket/base + (provide (all-defined-out)) + (define a 1) + (define b 2) + (define c 3))) + o))) + (call-with-output-file* + "compiled/b_rkt.zo" + (lambda (o) (write (compile '(module b racket/base + (require "a.rkt" + ;; Force saving of context, instead of + ;; reconstruction: + (only-in racket/base [car extra-car])))) + o)))) + (dynamic-require (build-path tmp "b.rkt") #f) + (define ns (module->namespace (build-path tmp "b.rkt"))) + (test #t + 'mapped-symbols + (and (for/and ([name '(a b c)]) + (member name (namespace-mapped-symbols ns))) + #t)) + (delete-directory/files tmp)) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index 51b9711a33..d3c84f460d 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -154,7 +154,8 @@ static void register_traversers(void); XFORM_NONGCING static int is_armed(Scheme_Object *v); static Scheme_Object *add_taint_to_stx(Scheme_Object *o, int *mutate); -static void unmarshal_module_context_additions(Scheme_Stx *stx, Scheme_Object *vec, Scheme_Scope_Set *scopes, Scheme_Object *replace_at); +static void unmarshal_module_context_additions(Scheme_Stx *stx, Scheme_Object *shifts, + Scheme_Object *vec, Scheme_Scope_Set *scopes, Scheme_Object *replace_at); static Scheme_Object *make_unmarshal_info(Scheme_Object *phase, Scheme_Object *prefix, Scheme_Object *excepts); XFORM_NONGCING static Scheme_Object *extract_unmarshal_phase(Scheme_Object *unmarshal_info); @@ -3491,7 +3492,7 @@ char *scheme_stx_describe_context(Scheme_Object *stx, Scheme_Object *phase, int return ""; } -static void add_scopes_mapped_names(Scheme_Scope_Set *scopes, Scheme_Hash_Table *mapped) +static void add_scopes_mapped_names(Scheme_Scope_Set *scopes, Scheme_Object *shifts, Scheme_Hash_Table *mapped) { int retry; Scheme_Hash_Tree *ht; @@ -3554,7 +3555,7 @@ static void add_scopes_mapped_names(Scheme_Scope_Set *scopes, Scheme_Hash_Table pes = SCHEME_BINDING_VAL(SCHEME_CAR(l)); if (PES_UNMARSHAL_DESCP(pes)) { if (SCHEME_TRUEP(SCHEME_VEC_ELS(pes)[0])) { - unmarshal_module_context_additions(NULL, pes, binding_scopes, l); + unmarshal_module_context_additions(NULL, shifts, pes, binding_scopes, l); retry = 1; } } else { @@ -3651,7 +3652,7 @@ static Scheme_Object *do_stx_lookup(Scheme_Stx *stx, Scheme_Scope_Set *scopes, /* Need unmarshal --- but only if the scope set is relevant */ if (scope_subset(binding_scopes, scopes)) { /* unmarshal and note that we must restart */ - unmarshal_module_context_additions(stx, pes, binding_scopes, l); + unmarshal_module_context_additions(stx, NULL, pes, binding_scopes, l); invalid = 1; /* Shouldn't encounter this on a second pass: */ STX_ASSERT(!check_subset); @@ -4289,7 +4290,9 @@ Scheme_Object *scheme_module_context_inspector(Scheme_Object *mc) void scheme_module_context_add_mapped_symbols(Scheme_Object *mc, Scheme_Hash_Table *mapped) { - add_scopes_mapped_names(scheme_module_context_scopes(mc), mapped); + add_scopes_mapped_names(scheme_module_context_scopes(mc), + SCHEME_VEC_ELS(mc)[3], /* list of shifts */ + mapped); } Scheme_Object *scheme_module_context_at_phase(Scheme_Object *mc, Scheme_Object *phase) @@ -4750,7 +4753,8 @@ static Scheme_Object *unmarshal_key_adjust(Scheme_Object *sym, Scheme_Object *pe return sym; } -static void unmarshal_module_context_additions(Scheme_Stx *stx, Scheme_Object *vec, Scheme_Scope_Set *scopes, Scheme_Object *replace_at) +static void unmarshal_module_context_additions(Scheme_Stx *stx, Scheme_Object *shifts, + 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; Scheme_Object *insp, *req_insp; @@ -4760,14 +4764,10 @@ static void unmarshal_module_context_additions(Scheme_Stx *stx, Scheme_Object *v insp = SCHEME_VEC_ELS(vec)[3]; req_insp = insp; - if (stx) { + 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; - } + else + modidx = apply_modidx_shifts(shifts, req_modidx, &insp, &export_registry); src_phase = SCHEME_VEC_ELS(vec)[1]; unmarshal_info = SCHEME_VEC_ELS(vec)[2]; From fef695f0668829ce1fe57c84fbd7332b4b017cf9 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 3 Dec 2015 08:05:17 -0700 Subject: [PATCH 130/369] fix `call-with-atomic-output-file` for pathless filename Closes #1156 --- .../scribblings/reference/filesystem.scrbl | 2 +- .../tests/racket/filelib.rktl | 38 +++++++++++++++++++ racket/collects/racket/file.rkt | 2 +- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/filesystem.scrbl b/pkgs/racket-doc/scribblings/reference/filesystem.scrbl index 06b107fa24..b25348c850 100644 --- a/pkgs/racket-doc/scribblings/reference/filesystem.scrbl +++ b/pkgs/racket-doc/scribblings/reference/filesystem.scrbl @@ -296,7 +296,7 @@ exists---to the path @racket[new]. If the file or directory is not renamed successfully, the @exnraise[exn:fail:filesystem]. This procedure can be used to move a file/directory to a different -directory (on the same disk) as well as rename a file/directory within +directory (on the same filesystem) as well as rename a file/directory within a directory. Unless @racket[exists-ok?] is provided as a true value, @racket[new] cannot refer to an existing file or directory. Even if @racket[exists-ok?] is true, @racket[new] cannot refer to an existing diff --git a/pkgs/racket-test-core/tests/racket/filelib.rktl b/pkgs/racket-test-core/tests/racket/filelib.rktl index 13c337682f..7ee5477730 100644 --- a/pkgs/racket-test-core/tests/racket/filelib.rktl +++ b/pkgs/racket-test-core/tests/racket/filelib.rktl @@ -181,6 +181,44 @@ (delete-file tempfile) (delete-file (make-lock-file-name tempfile)) +;;---------------------------------------------------------------------- +;; Atomic output + +(define (try-atomic-output fn) + (call-with-output-file* + fn + #:exists 'truncate + (lambda (o) (display "()" o))) + (define ts + (append + ;; Writers + (for/list ([i 10]) + (thread (lambda () + (for ([j 100]) + (call-with-atomic-output-file + fn + (lambda (o tmp-path) + (test (or (path-only fn) (current-directory)) + path-only tmp-path) + (display "(" o) + (flush-output o) + (sync (system-idle-evt)) + (display ")" o))))))) + ;; Readers + (for/list ([i 10]) + (thread (lambda () + (for ([j 100]) + (sync (system-idle-evt)) + (test '() call-with-input-file fn read))))))) + (for-each sync ts) + (delete-file fn)) + +(try-atomic-output (make-temporary-file)) +;; The user's add-on directory should be writable and might be a +;; different filesystem, so try that: +(parameterize ([current-directory (find-system-path 'addon-dir)]) + (try-atomic-output (format "atomic-output-~a" (current-inexact-milliseconds)))) + ;; ---------------------------------------- (report-errs) diff --git a/racket/collects/racket/file.rkt b/racket/collects/racket/file.rkt index aca31018d3..4339678606 100644 --- a/racket/collects/racket/file.rkt +++ b/racket/collects/racket/file.rkt @@ -213,7 +213,7 @@ (delete-file path))) (let ([bp (current-break-parameterization)] [tmp-path (parameterize ([current-security-guard (or guard (current-security-guard))]) - (make-temporary-file "tmp~a" #f (path-only path)))] + (make-temporary-file "tmp~a" #f (or (path-only path) (current-directory))))] [ok? #f]) (dynamic-wind void From f88ba77a5c7c515b816862bfe96d32ab9f306838 Mon Sep 17 00:00:00 2001 From: Leif Andersen Date: Fri, 4 Dec 2015 18:01:57 -0500 Subject: [PATCH 131/369] Fix travis to build against latest Racket build. --- racket/collects/pkg/private/new.rkt | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/racket/collects/pkg/private/new.rkt b/racket/collects/pkg/private/new.rkt index fff6f56fbe..5e7ae44c69 100644 --- a/racket/collects/pkg/private/new.rkt +++ b/racket/collects/pkg/private/new.rkt @@ -94,7 +94,7 @@ EOS ;; .travis.yml (with-output-to-file ".travis.yml" - (lambda () (display #<>` to install any required # packages without it getting stuck on a confirmation prompt. script: - - /usr/racket/bin/raco make main.rkt - - /usr/racket/bin/raco test -x . - -# NOTE: If your repo is a Racket package with an info.rkt that -# includes some `deps`, the following is more elegant: -# -# script: -# - cd .. # Travis did a cd into the dir. Back up, for the next: -# - /usr/racket/bin/raco pkg install --deps search-auto --link <> -# - /usr/racket/bin/raco test -x -p <> + - raco pkg install --deps search-auto + - raco test -x -p <> after_script: From d87e3ead7f8a58070bac7c8fe35493761b0152df Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 5 Dec 2015 14:41:22 -0500 Subject: [PATCH 132/369] fix test for the case that the addon dir is missing --- pkgs/racket-test-core/tests/racket/filelib.rktl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/filelib.rktl b/pkgs/racket-test-core/tests/racket/filelib.rktl index 7ee5477730..afbe933490 100644 --- a/pkgs/racket-test-core/tests/racket/filelib.rktl +++ b/pkgs/racket-test-core/tests/racket/filelib.rktl @@ -216,8 +216,10 @@ (try-atomic-output (make-temporary-file)) ;; The user's add-on directory should be writable and might be a ;; different filesystem, so try that: -(parameterize ([current-directory (find-system-path 'addon-dir)]) - (try-atomic-output (format "atomic-output-~a" (current-inexact-milliseconds)))) +(let ([addon-dir (find-system-path 'addon-dir)]) + (make-directory* addon-dir) + (parameterize ([current-directory addon-dir]) + (try-atomic-output (format "atomic-output-~a" (current-inexact-milliseconds))))) ;; ---------------------------------------- From 8b3369f81c710b0536f81da34960bc50baa6ba5a Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 5 Dec 2015 15:35:07 -0600 Subject: [PATCH 133/369] set up some information for TR --- .../collects/racket/contract/private/guts.rkt | 67 +++++++++++-------- .../collects/racket/contract/private/misc.rkt | 2 +- .../collects/racket/contract/private/orc.rkt | 2 +- .../racket/contract/private/types.rkt | 10 +++ 4 files changed, 50 insertions(+), 31 deletions(-) create mode 100644 racket/collects/racket/contract/private/types.rkt diff --git a/racket/collects/racket/contract/private/guts.rkt b/racket/collects/racket/contract/private/guts.rkt index aa57721056..b98a86a782 100644 --- a/racket/collects/racket/contract/private/guts.rkt +++ b/racket/collects/racket/contract/private/guts.rkt @@ -38,6 +38,7 @@ ;; helpers for adding properties that check syntax uses define/final-prop define/subexpression-pos-prop + define/subexpression-pos-prop/name make-predicate-contract @@ -332,6 +333,42 @@ (list (car (syntax-e stx))) '())))])))))])) +(define-syntax (define/subexpression-pos-prop/name stx) + (syntax-case stx () + [(_ ctc/proc header bodies ...) + (with-syntax ([ctc (if (identifier? #'header) + #'header + (car (syntax-e #'header)))]) + #'(begin + (define ctc/proc + (let () + (define header bodies ...) + ctc)) + (define-syntax (ctc stx) + (syntax-case stx () + [x + (identifier? #'x) + (syntax-property + #'ctc/proc + 'racket/contract:contract + (vector (gensym 'ctc) + (list stx) + '()))] + [(_ margs (... ...)) + (let ([this-one (gensym 'ctc)]) + (with-syntax ([(margs (... ...)) + (map (λ (x) (syntax-property x + 'racket/contract:positive-position + this-one)) + (syntax->list #'(margs (... ...))))] + [app (datum->syntax stx '#%app)]) + (syntax-property + #'(app ctc/proc margs (... ...)) + 'racket/contract:contract + (vector this-one + (list (car (syntax-e stx))) + '()))))]))))])) + (define-syntax (define/subexpression-pos-prop stx) (syntax-case stx () [(_ header bodies ...) @@ -339,35 +376,7 @@ #'header (car (syntax-e #'header)))]) (with-syntax ([ctc/proc (string->symbol (format "~a/proc" (syntax-e #'ctc)))]) - #'(begin - (define ctc/proc - (let () - (define header bodies ...) - ctc)) - (define-syntax (ctc stx) - (syntax-case stx () - [x - (identifier? #'x) - (syntax-property - #'ctc/proc - 'racket/contract:contract - (vector (gensym 'ctc) - (list stx) - '()))] - [(_ margs (... ...)) - (let ([this-one (gensym 'ctc)]) - (with-syntax ([(margs (... ...)) - (map (λ (x) (syntax-property x - 'racket/contract:positive-position - this-one)) - (syntax->list #'(margs (... ...))))] - [app (datum->syntax stx '#%app)]) - (syntax-property - #'(app ctc/proc margs (... ...)) - 'racket/contract:contract - (vector this-one - (list (car (syntax-e stx))) - '()))))])))))])) + #'(define/subexpression-pos-prop/name ctc/proc header bodies ...)))])) ;; build-compound-type-name : (union contract symbol) ... -> (-> sexp) (define (build-compound-type-name . fs) diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index a702633c58..f01fd1c6b2 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -307,7 +307,7 @@ (identifier? #'x) #'real-and/c])) -(define/subexpression-pos-prop (real-and/c . raw-fs) +(define/subexpression-pos-prop/name real-and/c-name (real-and/c . raw-fs) (let ([contracts (coerce-contracts 'and/c raw-fs)]) (cond [(null? contracts) any/c] diff --git a/racket/collects/racket/contract/private/orc.rkt b/racket/collects/racket/contract/private/orc.rkt index 1dca65b0f3..d61f49dbb0 100644 --- a/racket/collects/racket/contract/private/orc.rkt +++ b/racket/collects/racket/contract/private/orc.rkt @@ -12,7 +12,7 @@ blame-add-ior-context (rename-out [_flat-rec-contract flat-rec-contract])) -(define/subexpression-pos-prop or/c +(define/subexpression-pos-prop/name or/c-name or/c (case-lambda [() (make-none/c '(or/c))] [(x) (coerce-contract 'or/c x)] diff --git a/racket/collects/racket/contract/private/types.rkt b/racket/collects/racket/contract/private/types.rkt new file mode 100644 index 0000000000..d625f2da65 --- /dev/null +++ b/racket/collects/racket/contract/private/types.rkt @@ -0,0 +1,10 @@ +#lang racket/base +(provide types) +(define types + (hash '(real-and/c-name racket/contract/private/misc) + '(->* () #:rest Contract Contract) + + '(or/c-name racket/contract/private/orc) + '(->* () #:rest Contract Contract))) + +;; cast : alpha ( ctc) -> beta \ No newline at end of file From e814d742a70b579004b3d2b7d7ed842a5218139c Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 5 Dec 2015 23:03:06 -0600 Subject: [PATCH 134/369] fix the late-neg construction for flat contracts Thanks to Sam for finding this problem! --- .../collects/racket/contract/private/prop.rkt | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/racket/collects/racket/contract/private/prop.rkt b/racket/collects/racket/contract/private/prop.rkt index cadcc3074d..3c11ea0c82 100644 --- a/racket/collects/racket/contract/private/prop.rkt +++ b/racket/collects/racket/contract/private/prop.rkt @@ -270,11 +270,11 @@ #:list-contract? [list-contract? (λ (c) #f)]) ;; this code is here to help me find the combinators that - ;; are still using only #:projection and not #:val-first-projection + ;; are still using only #:projection and not #:late-neg-projection #; (when (and get-projection - (not get-val-first-projection)) - (printf "missing val-first-projection ~s\n" + (not get-late-neg-projection)) + (printf "missing late-neg-projection ~s\n" get-projection)) (let* ([get-name (or get-name (lambda (c) default-name))] @@ -283,6 +283,10 @@ (or get-val-first-projection (and (not get-projection) (get-val-first-first-order-projection get-name get-first-order)))] + [get-late-neg-projection + (or get-late-neg-projection + (and (not get-projection) + (get-late-neg-first-order-projection get-name get-first-order)))] [get-projection (cond [get-projection @@ -462,6 +466,9 @@ [val-first-projection (or val-first-projection (and (not projection) (val-first-first-order-projection name first-order)))] + [late-neg-projection (or late-neg-projection + (and (not projection) + (late-neg-first-order-projection name first-order)))] [stronger (or stronger as-strong?)]) (mk name first-order @@ -473,6 +480,9 @@ (define ((get-val-first-first-order-projection get-name get-first-order) c) (val-first-first-order-projection (get-name c) (get-first-order c))) +(define ((get-late-neg-first-order-projection get-name get-first-order) c) + (late-neg-first-order-projection (get-name c) (get-first-order c))) + (define (val-first-first-order-projection name p?) (λ (b) (λ (v) @@ -486,6 +496,18 @@ name v)))))) +(define (late-neg-first-order-projection name p?) + (λ (b) + (λ (v neg-party) + (if (p? v) + v + (raise-blame-error + b #:missing-party neg-party + v + '(expected: "~s" given: "~e") + name + v))))) + (define (as-strong? a b) (procedure-closure-contents-eq? (contract-struct-projection a) From b8d4248053de632d94cdceed4df603938964d925 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Sun, 6 Dec 2015 10:31:01 -0500 Subject: [PATCH 135/369] Copy immutable vector more efficiently. Thanks to @mflatt for the suggestion. --- racket/collects/racket/contract/private/vector.rkt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/racket/collects/racket/contract/private/vector.rkt b/racket/collects/racket/contract/private/vector.rkt index f5db23de87..45ffd86973 100644 --- a/racket/collects/racket/contract/private/vector.rkt +++ b/racket/collects/racket/contract/private/vector.rkt @@ -179,9 +179,9 @@ (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))) + (vector->immutable-vector + (for/vector #:length (vector-length val) ([e (in-vector val)]) + (elem-pos-proj e neg-party))) (chaperone-or-impersonate-vector val (checked-ref neg-party) From 21316e3ebfc5f9109483e23de38d29379bb13e2c Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Sun, 6 Dec 2015 10:45:13 -0500 Subject: [PATCH 136/369] Don't copy immutable vectors in `vectorof` if not needed. This happens only if the element contract is a flat contract. --- .../scribblings/reference/contracts.scrbl | 7 ++- .../racket/contract/private/vector.rkt | 48 +++++++++++++------ 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index 547a55de35..6339c80ddd 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -366,7 +366,12 @@ is a chaperone contract, then the result will be a chaperone contract. When a higher-order @racket[vectorof] contract is applied to a vector, the result is not @racket[eq?] to the input. The result will be a copy for immutable vectors -and a @tech{chaperone} or @tech{impersonator} of the input for mutable vectors.} +and a @tech{chaperone} or @tech{impersonator} of the input for mutable vectors, +unless the @racket[c] argument is a flat contract and the vector is immutable, +in which case the result is the original vector. + +@history[#:changed "6.3.0.5" @list{Changed flat vector contracts to not copy + immutable vectors.}]} @defproc[(vector-immutableof [c contract?]) contract?]{ diff --git a/racket/collects/racket/contract/private/vector.rkt b/racket/collects/racket/contract/private/vector.rkt index 45ffd86973..4adadcab78 100644 --- a/racket/collects/racket/contract/private/vector.rkt +++ b/racket/collects/racket/contract/private/vector.rkt @@ -173,21 +173,39 @@ (with-continuation-mark contract-continuation-mark-key (cons neg-blame neg-party) (elem-neg-proj val 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))) - (vector->immutable-vector - (for/vector #:length (vector-length val) ([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))))))) + (cond + [(flat-contract? elem-ctc) + (define p? (flat-contract-predicate elem-ctc)) + (λ (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))) + (begin (for ([e (in-vector val)]) + (unless (p? e) + (elem-pos-proj e neg-party))) + val) + (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))))] + [else + (λ (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))) + (vector->immutable-vector + (for/vector #:length (vector-length val) ([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)) From a0c09c19acd919c972aea83424a4863a4eee8ada Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Sun, 6 Dec 2015 12:22:37 -0500 Subject: [PATCH 137/369] Add test for 21316e3ebf. --- pkgs/racket-test/tests/racket/contract/vector.rkt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-test/tests/racket/contract/vector.rkt b/pkgs/racket-test/tests/racket/contract/vector.rkt index b1971d94c2..cc61440459 100644 --- a/pkgs/racket-test/tests/racket/contract/vector.rkt +++ b/pkgs/racket-test/tests/racket/contract/vector.rkt @@ -127,7 +127,14 @@ 0 #f))) (test/pos-blame - 'vector/c6 + 'vector/c7 '(contract (vector/c integer? #:immutable #t) (vector-immutable #f) - 'pos 'neg))) + 'pos 'neg)) + + (test/spec-passed/result + 'vector/immutable-flat + '(let ([x (vector-immutable 1 2 3)]) + (eq? (contract (vectorof integer?) x 'pos 'neg) + x)) + '#true)) From b5131321d7a3f7364a841cacca77e2bd31679ef8 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 4 Dec 2015 13:37:25 -0700 Subject: [PATCH 138/369] force non-inremental GC if excessive fragmentation Increemntal GC skips the old-generation compaction phase. For most applications, that's ok, but it's possible for fragmentation to get out of hand. Detect that situation and fall back to non-incremental mode for one major GC. --- racket/src/racket/gc2/newgc.c | 76 +++++++++++++++++++++++++++++++---- racket/src/racket/gc2/newgc.h | 1 + racket/src/racket/gc2/vm.c | 9 ++++- 3 files changed, 78 insertions(+), 8 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index decc2122fe..1dc1769e01 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -247,6 +247,9 @@ MAYBE_UNUSED static void GCVERBOSEprintf(NewGC *gc, const char *fmt, ...) { when incremental model is started: */ #define INCREMENTAL_EXTRA_SIZE_RATIO 2 +/* Avoid incremental GC if the heap seems to be getting too fragmented: */ +#define HIGH_FRAGMENTATION_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: */ @@ -3980,6 +3983,7 @@ void GC_mark2(void *pp, struct NewGC *gc) } newplace = PTR(NUM(work->addr) + work->size); work->size += size; + work->live_size += gcBYTES_TO_WORDS(size); new_type = 1; /* i.e., in gen 1/2 */ } else { /* now set us up for the search for where to put this thing in gen 1 */ @@ -3996,7 +4000,7 @@ void GC_mark2(void *pp, struct NewGC *gc) if (!work->marked_on) { work->marked_on = 1; if (!work->marked_from) { - gc->memory_in_use -= work->size; + gc->memory_in_use -= gcWORDS_TO_BYTES(work->live_size); work->modified_next = gc->modified_next; gc->modified_next = work; } @@ -4032,6 +4036,7 @@ void GC_mark2(void *pp, struct NewGC *gc) /* update the size */ work->size += size; + work->live_size += gcBYTES_TO_WORDS(size); work->has_new = 1; new_type = 0; /* i.e., not in gen 1/2 */ } @@ -4717,7 +4722,7 @@ static void mark_backpointers(NewGC *gc) } start += info->size; } - gc->memory_in_use -= work->size; + gc->memory_in_use -= gcWORDS_TO_BYTES(work->live_size); } else { /* medium page */ void **start = PPTR(NUM(work->addr) + PREFIX_SIZE); @@ -5268,7 +5273,7 @@ static void repair_heap(NewGC *gc) /* everything on this page is now old-generation: */ page->scan_boundary = page->size; - memory_in_use += page->size; + memory_in_use += gcWORDS_TO_BYTES(page->live_size); } else { /* ------ medium page ------ */ int need_fixup_now = need_fixup; @@ -5442,7 +5447,9 @@ static void incremental_repair_pages(NewGC *gc, int fuel) live_size = unmark_range(PPTR(NUM(page->addr) + PREFIX_SIZE), PPTR(NUM(page->addr) + APAGE_SIZE - page->obj_size)); } + gc->memory_in_use -= gcWORDS_TO_BYTES(page->live_size); page->live_size = live_size; + gc->memory_in_use += gcWORDS_TO_BYTES(live_size); page->non_dead_as_mark = 1; --fuel; } @@ -5531,7 +5538,10 @@ static void clean_up_heap(NewGC *gc) } else { GCVERBOSEPAGE(gc, "clean_up_heap BIG PAGE ALIVE", work); work->marked_on = 0; - memory_in_use += work->size; + if (work->size_class == SIZE_CLASS_SMALL_PAGE) + memory_in_use += gcWORDS_TO_BYTES(work->live_size); + else + memory_in_use += work->size; prev = work; } work = next; @@ -5732,6 +5742,48 @@ static void check_marks_cleared(NewGC *gc) static void check_marks_cleared(NewGC *gc) { } #endif +#if 0 +static int get_live_size_range(void **start, void **end) +{ + int live_size = 0; + + while(start < end) { + objhead *info = (objhead *)start; + + if (!info->dead) + live_size += info->size; + + start += info->size; + } + + return live_size; +} + +static void check_live_sizes(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); + GC_ASSERT(page->live_size == get_live_size_range(PAGE_START_VSS(page), PAGE_END_VSS(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) { + GC_ASSERT(page->live_size == get_live_size_range(PAGE_START_VSS(page), + PPTR(NUM(page->addr) + APAGE_SIZE - page->obj_size))); + } + } + } +} +#else +static void check_live_sizes(NewGC *gc) { } +#endif + static void park_for_inform_callback(NewGC *gc) { /* Avoid nested collections, which would need @@ -5902,6 +5954,8 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin incremental mode has been enabled: */ || ((gc->since_last_full > FORCE_MAJOR_AFTER_COUNT) && !gc->started_incremental) + /* Finalization triggers an extra full in case it releases + a lot of additional memory: */ || (gc->full_needed_for_finalization && !gc->incremental_requested && !gc->started_incremental) @@ -5952,8 +6006,10 @@ 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)); + do_incremental = (!gc->gc_full + && (gc->incremental_requested + || always_collect_incremental_on_minor) + && !gc->high_fragmentation); if (!postmaster_and_place_gc(gc)) do_incremental = 0; @@ -6112,12 +6168,18 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin } TIME_STEP("protect"); - if (gc->gc_full) + if (gc->gc_full) { mmu_flush_freed_pages(gc->mmu); + gc->high_fragmentation = (mmu_memory_allocated_and_used(gc->mmu) + > (HIGH_FRAGMENTATION_RATIO + * (gc->memory_in_use + gen_half_size_in_use(gc) + GEN0_MAX_SIZE))); + } reset_finalizer_tree(gc); if (gc->gc_full || !gc->started_incremental) check_marks_cleared(gc); + if (gc->gc_full) + check_live_sizes(gc); clear_stack_pages(gc); diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 5ae5ca5a5f..11f4e312cc 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -218,6 +218,7 @@ typedef struct NewGC { unsigned char fnl_gen1 :1; /* during incremental finalization of old generation */ unsigned char during_backpointer :1; unsigned char incremental_requested :1; + unsigned char high_fragmentation :1; /* blame the child */ unsigned int doing_memory_accounting :1; diff --git a/racket/src/racket/gc2/vm.c b/racket/src/racket/gc2/vm.c index 53795283ce..04e539c0d5 100644 --- a/racket/src/racket/gc2/vm.c +++ b/racket/src/racket/gc2/vm.c @@ -47,7 +47,8 @@ typedef struct MMU { struct AllocCacheBlock *alloc_caches[2]; Page_Range *page_range; #endif - intptr_t memory_allocated; + intptr_t memory_allocated; /* allocated from OS */ + intptr_t memory_used; /* subset of alloctaed from OS that's being used */ size_t os_pagesize; NewGC *gc; } MMU; @@ -139,6 +140,7 @@ static void mmu_free(MMU *mmu) { static void *mmu_alloc_page(MMU* mmu, size_t len, size_t alignment, int dirty, int type, int expect_mprotect, void **src_block) { mmu_assert_os_page_aligned(mmu, len); + mmu->memory_used += len; #ifdef USE_BLOCK_CACHE return block_cache_alloc_page(mmu->block_cache, len, alignment, dirty, type, expect_mprotect, src_block, &mmu->memory_allocated); #else @@ -164,6 +166,7 @@ static void mmu_free_page(MMU* mmu, void *p, size_t len, int type, int expect_mp int originated_here) { mmu_assert_os_page_aligned(mmu, (size_t)p); mmu_assert_os_page_aligned(mmu, len); + mmu->memory_used -= len; #ifdef USE_BLOCK_CACHE mmu->memory_allocated += block_cache_free_page(mmu->block_cache, p, len, type, expect_mprotect, src_block, originated_here); @@ -251,6 +254,10 @@ static size_t mmu_memory_allocated(MMU *mmu) { return mmu->memory_allocated; } +static size_t mmu_memory_allocated_and_used(MMU *mmu) { + return mmu->memory_used; +} + /* _WIN32 and OSKIT use these functions On OSX and Linux the block and alloc caches From e44926fceecb3927d9e8a704fa5eb0b2d2b5685d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 4 Dec 2015 16:15:07 -0500 Subject: [PATCH 139/369] increemntal GC: compact when a major GC is forced early This change further defends against fragmentation when incremental mode isn't working well. --- racket/src/racket/gc2/newgc.c | 8 +++++--- racket/src/racket/gc2/newgc.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 1dc1769e01..aaf86736b5 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -2015,7 +2015,7 @@ inline static void master_set_max_size(NewGC *gc) inline static void reset_nursery(NewGC *gc) { uintptr_t new_gen0_size; - + new_gen0_size = NUM((GEN0_SIZE_FACTOR * (float)gc->memory_in_use) + GEN0_SIZE_ADDITION); if ((new_gen0_size > GEN0_MAX_SIZE) || (gc->memory_in_use > GEN0_MAX_SIZE)) /* => overflow */ @@ -4833,7 +4833,7 @@ inline static void do_heap_compact(NewGC *gc) int tic_tock = gc->num_major_collects % 2; /* incremental mode disables old-generation compaction: */ - if (gc->started_incremental) + if (gc->started_incremental && !gc->compact_even_incremental) return; mmu_prep_for_compaction(gc->mmu); @@ -5975,8 +5975,10 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (gc->full_needed_for_finalization && gc->gc_full) gc->full_needed_for_finalization= 0; - if (gc->gc_full) + if (gc->gc_full) { + gc->compact_even_incremental = !gc->finishing_incremental; gc->finishing_incremental = 0; + } #ifdef GC_DEBUG_PAGES if (gc->gc_full == 1) { diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 11f4e312cc..6310a714fd 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -219,6 +219,7 @@ typedef struct NewGC { unsigned char during_backpointer :1; unsigned char incremental_requested :1; unsigned char high_fragmentation :1; + unsigned char compact_even_incremental :1; /* blame the child */ unsigned int doing_memory_accounting :1; From 715bdbb49e16c214b8b2066b668ca274803decdf Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 6 Dec 2015 08:43:36 -0500 Subject: [PATCH 140/369] incremental GC: avoid already-finished finalizaton work Avoid extra work svaing finalization information and re-chaining old-generation records for a major GC. --- racket/src/racket/gc2/newgc.c | 186 ++++++++++++++++++++++++++-------- racket/src/racket/gc2/newgc.h | 7 +- racket/src/racket/gc2/weak.c | 109 ++++++++------------ 3 files changed, 191 insertions(+), 111 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index aaf86736b5..b4e7e54c16 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -2065,6 +2065,7 @@ inline static int marked(NewGC *gc, const void *p) switch(page->size_class) { case SIZE_CLASS_SMALL_PAGE: if ((page->generation >= AGE_GEN_1) && !gc->inc_gen1) { + GC_ASSERT(!gc->finished_incremental); if ((NUM(page->addr) + page->scan_boundary) > NUM(p)) return 1; } @@ -2749,7 +2750,7 @@ static void push_ptr(NewGC *gc, void *ptr, int inc_gen1) #endif GC_ASSERT(inc_gen1 || !gc->inc_gen1); - GC_ASSERT(!inc_gen1 || !gc->finishing_incremental); + GC_ASSERT(!inc_gen1 || !gc->all_marked_incremental); push_ptr_at(ptr, inc_gen1 ? &gc->inc_mark_stack : &gc->mark_stack); } @@ -3084,9 +3085,13 @@ 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. */ + if (page && (page->generation >= AGE_GEN_1) && page->mprotected + /* Some marking functions, like the one for weak boxes, + update the record, so it's ok to make the page writable. */ + && (gc->inc_gen1 + /* Memory accounting can also modify otherwise unadjusted + pages after incrementa mode: */ + || (gc->doing_memory_accounting && gc->finished_incremental))) { check_incremental_unprotect(gc, page); return 1; } @@ -3692,8 +3697,7 @@ intptr_t GC_get_memory_use(void *o) 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); + GC_ASSERT(!gc->gc_full || gc->finished_incremental); if (page->mprotected) { page->mprotected = 0; @@ -3711,9 +3715,13 @@ static void page_newly_marked_on(NewGC *gc, mpage *page, int is_a_master_page, i /* If this page isn't already marked as old, it must be a medium page whose generation will be updated in the clean-up phase */ GC_ASSERT((page->generation >= AGE_GEN_1) || (page->size_class == SIZE_CLASS_MED_PAGE)); + GC_ASSERT(!gc->finished_incremental); + GC_ASSERT(!page->non_dead_as_mark); page->inc_marked_on = 1; page->inc_modified_next = gc->inc_modified_next; gc->inc_modified_next = page; + if (!gc->inc_repair_next) + gc->inc_repair_next = page; } else { GC_ASSERT(!page->marked_on); page->marked_on = 1; @@ -3849,6 +3857,10 @@ void GC_mark2(void *pp, struct NewGC *gc) /* in this case, it has not. So we want to mark it, first off. */ page->size_class = SIZE_CLASS_BIG_PAGE_MARKED; + GC_ASSERT((page->generation < AGE_GEN_1) + || is_a_master_page + || (!gc->all_marked_incremental && !gc->finished_incremental)); + /* 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) { GC_ASSERT(!gc->inc_gen1); @@ -3883,6 +3895,9 @@ void GC_mark2(void *pp, struct NewGC *gc) RELEASE_PAGE_LOCK(is_a_master_page, page); return; } + GC_ASSERT((page->generation < AGE_GEN_1) + || is_a_master_page + || (!gc->all_marked_incremental && !gc->finished_incremental)); if ((page->generation == AGE_GEN_0) || gc->gc_full) { GC_ASSERT(!gc->inc_gen1); inc_gen1 = 0; @@ -3890,6 +3905,7 @@ void GC_mark2(void *pp, struct NewGC *gc) if (is_a_master_page) inc_gen1 = 0; else { + GC_ASSERT(!gc->all_marked_incremental && !gc->finished_incremental); inc_gen1 = 1; check_incremental_unprotect(gc, page); } @@ -3915,6 +3931,10 @@ void GC_mark2(void *pp, struct NewGC *gc) return; } + GC_ASSERT((page->generation < AGE_GEN_1) + || is_a_master_page + || (!gc->all_marked_incremental && !gc->finished_incremental)); + /* what we do next depends on whether this is a gen0, gen_half, or gen1 object */ if (page->generation >= AGE_GEN_1) { @@ -3941,6 +3961,7 @@ void GC_mark2(void *pp, struct NewGC *gc) if (is_a_master_page) { inc_gen1 = 0; } else { + GC_ASSERT(!gc->all_marked_incremental && !gc->finished_incremental); check_incremental_unprotect(gc, page); inc_gen1 = 1; } @@ -4589,7 +4610,7 @@ void *GC_next_tagged_start(void *p) /* garbage collection */ /*****************************************************************************/ -static void reset_gen1_pages_scan_boundaries(NewGC *gc) +static void reset_gen1_pages_scan_boundaries_and_writable(NewGC *gc) { mpage *work; int i; @@ -4695,7 +4716,7 @@ static void mark_backpointers(NewGC *gc) /* 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) + else if (!gc->gc_full && !gc->all_marked_incremental) 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) { @@ -4712,7 +4733,7 @@ static void mark_backpointers(NewGC *gc) if (!info->dead) { if (info->mark || work->non_dead_as_mark) mark_traverse_object(gc, PPTR(OBJHEAD_TO_OBJPTR(start)), PPTR(info) + info->size, info->type); - else if (!gc->gc_full + else if ((!gc->gc_full && !gc->all_marked_incremental) /* Totally ad hoc; supports closure prefixes */ || ((info->type == PAGE_TAGGED) && gc->treat_as_incremental_mark_hook @@ -4735,7 +4756,7 @@ static void mark_backpointers(NewGC *gc) if (!info->dead) { if (info->mark || work->non_dead_as_mark) mark_traverse_object(gc, PPTR(OBJHEAD_TO_OBJPTR(start)), PPTR(info) + info->size, info->type); - else if (!gc->gc_full) + else if (!gc->gc_full && !gc->all_marked_incremental) mark_traverse_object_no_gen1(gc, PPTR(OBJHEAD_TO_OBJPTR(start)), PPTR(info) + info->size, info->type); } start += info->size; @@ -4832,10 +4853,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 && !gc->compact_even_incremental) + /* Cannot compact old generation if we've finished marking: */ + if (gc->all_marked_incremental) return; - + mmu_prep_for_compaction(gc->mmu); for(i = 0; i < PAGE_BIG; i++) { @@ -5097,7 +5118,7 @@ static void repair_heap(NewGC *gc) memory_in_use = gc->memory_in_use; need_fixup = gc->need_fixup; - minor_for_incremental = !gc->gc_full && gc->mark_gen1; + minor_for_incremental = !gc->gc_full && gc->started_incremental; for (; page; page = next) { GC_ASSERT(page->marked_on || page->marked_from); @@ -5109,7 +5130,7 @@ static void repair_heap(NewGC *gc) if (gc->gc_full) page->marked_on = 1; else { - if (gc->mark_gen1 && page->marked_on) + if (minor_for_incremental && page->marked_on) page_marked_on(gc, page, 0, 1); page->marked_on = 0; } @@ -5334,12 +5355,19 @@ static void repair_heap(NewGC *gc) 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->gc_full || gc->finished_incremental); GC_ASSERT(gc->mark_gen1); } else { - page->reprotect_next = gc->reprotect_next; - gc->reprotect_next = page; - page->reprotect = 1; + if (page->mprotected) { + /* This only happens for a full collection to wrap up a + finished incremental collection; the page wasn't + touched at al in the wrap-up */ + GC_ASSERT(gc->gc_full && gc->finished_incremental); + } else { + page->reprotect_next = gc->reprotect_next; + gc->reprotect_next = page; + page->reprotect = 1; + } } } } @@ -5411,6 +5439,7 @@ static void repair_heap(NewGC *gc) static void incremental_repair_pages(NewGC *gc, int fuel) { mpage *page; + int retry = 1; #if 0 /* Make sure `gc->inc_repair_next` is a tail of `gc->inc_modified_next` */ @@ -5433,8 +5462,12 @@ static void incremental_repair_pages(NewGC *gc, int fuel) /* skip */ } else { if (page->non_dead_as_mark) { - /* hit already-repaired tail; no more to repair */ - gc->inc_repair_next = NULL; + /* hit already-repaired tail; no more to repair here */ + if (retry) { + retry = 0; + gc->inc_repair_next = gc->inc_modified_next; + } else + gc->inc_repair_next = NULL; } else { int live_size; check_incremental_unprotect(gc, page); @@ -5457,6 +5490,33 @@ static void incremental_repair_pages(NewGC *gc, int fuel) } } +#if 0 +static void check_finished_incremental(NewGC *gc) +{ + mpage *work; + int i, ty; + + /* 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_BIG; i++) { + for(work = gc->gen1_pages[i]; work; work = work->next) { + GC_ASSERT(!work->inc_marked_on || work->non_dead_as_mark); + } + } + + 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) { + GC_ASSERT(!work->inc_marked_on || work->non_dead_as_mark); + } + } + } +} +#else +static void check_finished_incremental(NewGC *gc) { } +#endif + static inline void cleanup_vacated_pages(NewGC *gc) { mpage *pages = gc->release_pages; PageMap pagemap = gc->page_maps; @@ -5514,6 +5574,15 @@ inline static void gen0_free_big_pages(NewGC *gc) { gc->gen0.big_pages = NULL; } +static void check_mprotected_for_finished_incremental(NewGC *gc, mpage *work) +{ + if (work->mprotected) { + GC_ASSERT(gc->gc_full && gc->finished_incremental); + work->mprotected = 0; + mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work), page_mmu_type(work), &work->mmu_src_block); + } +} + static void clean_up_heap(NewGC *gc) { int i, ty; @@ -5533,6 +5602,7 @@ static void clean_up_heap(NewGC *gc) if(prev) prev->next = next; else gc->gen1_pages[i] = next; if(next) work->next->prev = prev; GCVERBOSEPAGE(gc, "Cleaning up BIGPAGE", work); + check_mprotected_for_finished_incremental(gc, work); gen1_free_mpage(pagemap, work); --gc->num_gen1_pages; } else { @@ -5570,6 +5640,7 @@ static void clean_up_heap(NewGC *gc) 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); + check_mprotected_for_finished_incremental(gc, work); gen1_free_mpage(pagemap, work); --gc->num_gen1_pages; } else { @@ -5577,7 +5648,7 @@ static void clean_up_heap(NewGC *gc) next = NULL; } } - if (gc->finishing_incremental) { + if (gc->all_marked_incremental && !gc->gc_full) { /* no more allocation on old pages */ gc->med_freelist_pages[ty][i] = NULL; } else @@ -5853,16 +5924,24 @@ static int mark_and_finalize_all(NewGC *gc, int old_gen TIME_FORMAL_ARGS) gc->fnl_gen1 = 1; } + if (gc->gc_full) + (void)zero_weak_boxes(gc, 0, 0, 1, -1); fuel = zero_weak_boxes(gc, 0, 0, old_gen, (old_gen ? fuel : -1)); if (old_gen && !fuel) { gc->fnl_gen1 = 0; return 1; } + + if (gc->gc_full) + (void)zero_weak_arrays(gc, 0, 1, -1); fuel = zero_weak_arrays(gc, 0, old_gen, (old_gen ? fuel : -1)); if (old_gen && !fuel) { gc->fnl_gen1 = 0; return 1; } + + if (gc->gc_full) + zero_remaining_ephemerons(gc, 1); zero_remaining_ephemerons(gc, old_gen); TIME_STEP("zeroed"); @@ -5872,6 +5951,8 @@ static int mark_and_finalize_all(NewGC *gc, int old_gen TIME_FORMAL_ARGS) propagate_marks(gc); else (void)propagate_incremental_marks(gc, 0, -1); + if (gc->gc_full) + (void)zero_weak_boxes(gc, 1, 0, 1, -1); (void)zero_weak_boxes(gc, 1, 0, old_gen, -1); check_finalizers(gc, 3, old_gen); @@ -5889,6 +5970,21 @@ static int mark_and_finalize_all(NewGC *gc, int old_gen TIME_FORMAL_ARGS) (void)zero_weak_arrays(gc, 1, old_gen, -1); zero_remaining_ephemerons(gc, old_gen); + GC_ASSERT(!gc->weak_arrays); + GC_ASSERT(!gc->bp_weak_arrays); + GC_ASSERT(!gc->weak_boxes[0]); + GC_ASSERT(!gc->weak_boxes[1]); + GC_ASSERT(!gc->bp_weak_boxes[0]); + GC_ASSERT(!gc->bp_weak_boxes[1]); + GC_ASSERT(!gc->ephemerons); + GC_ASSERT(!gc->bp_ephemerons); + if (gc->gc_full) { + GC_ASSERT(!gc->inc_weak_arrays); + GC_ASSERT(!gc->inc_weak_boxes[0]); + GC_ASSERT(!gc->inc_weak_boxes[1]); + GC_ASSERT(!gc->inc_ephemerons); + } + if (old_gen) gc->fnl_gen1 = 0; @@ -5938,6 +6034,10 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin dump_page_map(gc, "pre"); + GC_ASSERT(!gc->all_marked_incremental || gc->started_incremental); + GC_ASSERT(!gc->all_marked_incremental || mark_stack_is_empty(gc->inc_mark_stack)); + GC_ASSERT(!gc->finished_incremental || (gc->all_marked_incremental && !gc->inc_repair_next)); + /* determine if this should be a full collection or not */ gc->gc_full = (force_full || !gc->generations_available @@ -5947,7 +6047,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin fraction of the actual use by live data: */ || (gc->memory_in_use > (FULL_COLLECTION_SIZE_RATIO * gc->last_full_mem_use - * ((gc->started_incremental && !no_full) + * (gc->started_incremental ? INCREMENTAL_EXTRA_SIZE_RATIO : 1))) /* Just in case, for a full GC every so often, unless @@ -5961,10 +6061,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin && !gc->started_incremental) /* In incremental mode, GC earlier if we've done everything that we can do incrementally. */ - || (gc->started_incremental - && mark_stack_is_empty(gc->inc_mark_stack) - && gc->finishing_incremental - && !gc->inc_repair_next)); + || gc->finished_incremental); if (gc->gc_full && no_full) return; @@ -5975,10 +6072,6 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (gc->full_needed_for_finalization && gc->gc_full) gc->full_needed_for_finalization= 0; - if (gc->gc_full) { - gc->compact_even_incremental = !gc->finishing_incremental; - gc->finishing_incremental = 0; - } #ifdef GC_DEBUG_PAGES if (gc->gc_full == 1) { @@ -6020,8 +6113,8 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin gc->incremental_requested = 0; - gc->mark_gen1 = gc->gc_full || gc->started_incremental; - gc->check_gen1 = gc->gc_full; + gc->mark_gen1 = (gc->gc_full || gc->started_incremental) && !gc->all_marked_incremental; + gc->check_gen1 = gc->gc_full && !gc->all_marked_incremental; TIME_INIT(); @@ -6037,18 +6130,21 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin 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) + if (gc->finished_incremental) + check_finished_incremental(gc); + + if (gc->gc_full && !gc->finished_incremental) + reset_gen1_pages_scan_boundaries_and_writable(gc); + + if (gc->gc_full && !gc->finished_incremental) merge_finalizer_trees(gc); move_gen_half_pages_to_old(gc); - init_weak_boxes(gc, gc->gc_full); - init_weak_arrays(gc, gc->gc_full); - init_ephemerons(gc, gc->gc_full); + init_weak_boxes(gc); + init_weak_arrays(gc); + init_ephemerons(gc); /* at this point, the page map should only include pages that contain collectable objects */ @@ -6076,7 +6172,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin (void)mark_and_finalize_all(gc, 0 TIME_ARGS); if (do_incremental) { - if (!gc->finishing_incremental) { + if (!gc->all_marked_incremental) { mark_finalizer_structs(gc, 1); if (!mark_stack_is_empty(gc->inc_mark_stack)) { int fuel = (no_full @@ -6094,8 +6190,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin BTC_clean_up_gen1(gc); reset_gen1_finalizer_tree(gc); /* Switch to incrementally reparing pages */ - gc->finishing_incremental = 1; - gc->inc_repair_next = gc->inc_modified_next; + gc->all_marked_incremental = 1; } } check_inc_repair = 0; @@ -6135,11 +6230,14 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin repair_heap(gc); TIME_STEP("repaired"); if (check_inc_repair) { + GC_ASSERT(gc->all_marked_incremental); int fuel = (no_full ? INCREMENTAL_REPAIR_FUEL_PER_100M / INCREMENTAL_MINOR_REQUEST_DIVISOR : INCREMENTAL_REPAIR_FUEL_PER_100M * AS_100M(gc->memory_in_use)); incremental_repair_pages(gc, fuel); TIME_STEP("inc-repaired"); + if (!gc->inc_repair_next) + gc->finished_incremental = 1; } clean_up_heap(gc); @@ -6224,6 +6322,8 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (gc->gc_full) { gc->last_full_mem_use = gc->memory_in_use; gc->started_incremental = 0; + gc->all_marked_incremental = 0; + gc->finished_incremental = 0; gc->inc_prop_count = 0; } diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 6310a714fd..deb14977b8 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -203,23 +203,24 @@ typedef struct NewGC { unsigned char generations_available :1; unsigned char started_incremental :1; /* must stick with incremental until major GC */ - unsigned char finishing_incremental :1; /* finalized already */ + unsigned char all_marked_incremental :1; /* finished all marking for an incremental GC */ + unsigned char finished_incremental :1; /* finished marking and reparing an incremental GC */ unsigned char in_unsafe_allocation_mode :1; 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 had_finished_incremental :1; /* when gc_full, indicates full GC after incremental finished */ unsigned char use_gen_half :1; unsigned char running_finalizers :1; unsigned char back_pointers :1; unsigned char need_fixup :1; - unsigned char check_gen1 :1; /* check marks bit for old generation (insteda of claiming always marked) */ + unsigned char check_gen1 :1; /* check marks bit for old generation (instead of claiming always marked) */ unsigned char mark_gen1 :1; /* set mark bits for old generation */ unsigned char inc_gen1 :1; /* during incremental marking of old generation */ unsigned char fnl_gen1 :1; /* during incremental finalization of old generation */ unsigned char during_backpointer :1; unsigned char incremental_requested :1; unsigned char high_fragmentation :1; - unsigned char compact_even_incremental :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 74aa1bcc00..d9fcd99a08 100644 --- a/racket/src/racket/gc2/weak.c +++ b/racket/src/racket/gc2/weak.c @@ -132,22 +132,10 @@ 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, int old_gen) +static void init_weak_arrays(GCTYPE *gc) { GC_ASSERT(!gc->bp_weak_arrays); - if (old_gen) { - 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->weak_arrays = NULL; } static GC_Weak_Array *append_weak_arrays(GC_Weak_Array *wa, GC_Weak_Array *bp_wa, int *_num_gen0) @@ -197,10 +185,15 @@ static int zero_weak_arrays(GCTYPE *gc, int force_zero, int from_inc, int fuel) 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; + if (!gc->all_marked_incremental) { + /* For incremental mode, preserve this weak array + in the incremental list for re-checking later. */ + wa->data[wa->count] = gc->inc_weak_arrays; + gc->inc_weak_arrays = wa; + } else { + /* Count as incremental-done: */ + wa->data[wa->count] = gc->weak_incremental_done; + } } } @@ -330,28 +323,12 @@ 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, int old_gen) +static void init_weak_boxes(GCTYPE *gc) { GC_ASSERT(!gc->bp_weak_boxes[0]); GC_ASSERT(!gc->bp_weak_boxes[1]); - if (old_gen) { - 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->weak_boxes[0] = NULL; + gc->weak_boxes[1] = NULL; } static GC_Weak_Box *append_weak_boxes(GC_Weak_Box *wb, GC_Weak_Box *bp_wb, int *_num_gen0) @@ -416,11 +393,16 @@ static int zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero, int from_inc } 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. */ - check_weak_box_not_already_in_inc_chain(wb, gc->inc_weak_boxes[wb->is_late]); - wb->inc_next = gc->inc_weak_boxes[is_late]; - gc->inc_weak_boxes[is_late] = wb; + if (!gc->all_marked_incremental) { + /* For incremental mode, preserve this weak box + in the incremental list for re-checking later. */ + check_weak_box_not_already_in_inc_chain(wb, gc->inc_weak_boxes[wb->is_late]); + wb->inc_next = gc->inc_weak_boxes[is_late]; + gc->inc_weak_boxes[is_late] = wb; + } else { + /* Count as incremental-done: */ + wb->inc_next = gc->weak_incremental_done; + } } } if (from_inc) { @@ -481,7 +463,7 @@ static int mark_ephemeron(void *p, struct NewGC *gc) other old-generation objects), so ignore in that case */ && (gc->mark_gen1 || !gc->started_incremental - || !gc->finishing_incremental)) { + || !gc->all_marked_incremental)) { eph->next = gc->bp_ephemerons; gc->bp_ephemerons = eph; } @@ -545,20 +527,9 @@ 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, int old_gen) { - if (old_gen) { - rechain_inc_ephemerons(gc->inc_ephemerons); - gc->ephemerons = gc->inc_ephemerons; - gc->inc_ephemerons = NULL; - } else - gc->ephemerons = NULL; +void init_ephemerons(GCTYPE *gc) { + GC_ASSERT(!gc->bp_ephemerons); + gc->ephemerons = NULL; gc->bp_ephemerons = NULL; gc->num_last_seen_ephemerons = 0; } @@ -570,18 +541,23 @@ static int mark_ready_ephemerons(GCTYPE *gc, int inc_gen1) GC_mark_no_recur(gc, 1); - for (j = 0; j < (inc_gen1 ? 1 : 2); j++) { + for (j = 0; j < (inc_gen1 ? 1 : (gc->gc_full ? 3 : 2)); j++) { + waiting = NULL; + if (inc_gen1) eph = gc->inc_ephemerons; else if (j == 0) eph = gc->ephemerons; - else + else if (j == 1) eph = gc->bp_ephemerons; - - waiting = NULL; + else { + eph = gc->inc_ephemerons; + gc->inc_ephemerons = NULL; + waiting = gc->ephemerons; + } for (; eph; eph = next) { - if (inc_gen1) + if (inc_gen1 || (j == 2)) next = eph->inc_next; else next = eph->next; @@ -591,9 +567,10 @@ static int mark_ready_ephemerons(GCTYPE *gc, int inc_gen1) gcMARK2(eph->val, gc); gc->num_last_seen_ephemerons++; did_one = 1; - if (!inc_gen1 && (j == 0) && !gc->gc_full && gc->started_incremental) { + if (!inc_gen1 && (j == 0) && !gc->gc_full + && gc->started_incremental && !gc->all_marked_incremental) { /* Need to preserve the ephemeron in the incremental list, - unless it's kept in generation 1/2 nistead of promoted to + unless it's kept in generation 1/2 instead of promoted to generation 1. */ if (!is_in_generation_half(gc, eph)) { eph->inc_next = gc->inc_ephemerons; @@ -613,7 +590,7 @@ static int mark_ready_ephemerons(GCTYPE *gc, int inc_gen1) if (inc_gen1) gc->inc_ephemerons = waiting; - else if (j == 0) + else if ((j == 0)|| (j == 2)) gc->ephemerons = waiting; else gc->bp_ephemerons = waiting; @@ -628,6 +605,8 @@ static void zero_remaining_ephemerons(GCTYPE *gc, int from_inc) { GC_Ephemeron *eph; + GC_ASSERT(from_inc || !gc->gc_full || !gc->inc_ephemerons); + /* After level-1 finalization, any remaining ephemerons should be zeroed. */ if (from_inc) { From 22caaad944eddaea6dadd48a181af7fdae624b86 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Thu, 3 Dec 2015 15:20:16 -0600 Subject: [PATCH 141/369] free-vars: nicer error on submodules --- racket/collects/syntax/free-vars.rkt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/racket/collects/syntax/free-vars.rkt b/racket/collects/syntax/free-vars.rkt index 9ced2c1e71..1daa430e3d 100644 --- a/racket/collects/syntax/free-vars.rkt +++ b/racket/collects/syntax/free-vars.rkt @@ -49,7 +49,9 @@ (define (free-vars e [code-insp (variable-reference->module-declaration-inspector (#%variable-reference))]) - ;; It would be nicers to have a functional mapping: + (define (submodule-error e) + (error 'free-vars "submodules not supported: ~a" e)) + ;; It would be nicer to have a functional mapping: (define bindings (make-bound-identifier-mapping)) (merge (let free-vars ([e e]) @@ -89,5 +91,9 @@ (list #'if #'begin #'begin0 #'set! #'#%plain-app #'#%expression #'#%variable-reference #'with-continuation-mark)) (map free-vars (syntax->list #'(expr ...)))] + [(module . _) + (submodule-error e)] + [(module* . _) + (submodule-error e)] [(kw . _) (error 'free-vars "unknown core form: ~a" (syntax->datum #'kw))])))) From 5353dd1076477f5bf6ec0eaa879b5becb0b159f1 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Thu, 3 Dec 2015 15:39:34 -0600 Subject: [PATCH 142/369] free-vars: add mode that also reports module-bound variables As a separate mode, for backwards compatibility. --- .../syntax/scribblings/free-vars.scrbl | 7 ++++- pkgs/racket-test/tests/syntax/free-vars.rkt | 9 +++++- racket/collects/syntax/free-vars.rkt | 30 ++++++++++++------- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/pkgs/racket-doc/syntax/scribblings/free-vars.scrbl b/pkgs/racket-doc/syntax/scribblings/free-vars.scrbl index 0077a7b4e3..f5ba88658f 100644 --- a/pkgs/racket-doc/syntax/scribblings/free-vars.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/free-vars.scrbl @@ -5,7 +5,9 @@ @defmodule[syntax/free-vars] -@defproc[(free-vars [expr-stx syntax?] [insp inspector? _mod-decl-insp]) +@defproc[(free-vars [expr-stx syntax?] + [insp inspector? _mod-decl-insp] + [#:module-bound? module-bound? any/c #f]) (listof identifier?)]{ Returns a list of free @racket[lambda]- and @racket[let]-bound @@ -18,3 +20,6 @@ The inspector @racket[insp] is used to disarm @racket[expr-stx] and sub-expressions before extracting identifiers. The default @racket[insp] is the declaration-time inspector of the @racketmodname[syntax/free-vars] module.} + +If @racket[module-bound?] is non-false, the list of free variables also +includes free module-bound identifiers. diff --git a/pkgs/racket-test/tests/syntax/free-vars.rkt b/pkgs/racket-test/tests/syntax/free-vars.rkt index 233f4a5643..50850c10ca 100644 --- a/pkgs/racket-test/tests/syntax/free-vars.rkt +++ b/pkgs/racket-test/tests/syntax/free-vars.rkt @@ -1,5 +1,6 @@ #lang racket -(require syntax/free-vars) +(require syntax/free-vars + rackunit) (parameterize ([current-namespace (make-base-namespace)]) (define (check stx) @@ -40,3 +41,9 @@ '(x) (let ([y 3]) (list x y))))) + +(check-equal? (free-vars (expand #'(+ 1 2))) + '()) +(check-pred (lambda (x) (free-identifier=? x #'+)) + (first (free-vars (expand #'(+ 1 2)) + #:module-bound? #t))) diff --git a/racket/collects/syntax/free-vars.rkt b/racket/collects/syntax/free-vars.rkt index 1daa430e3d..4a29674ac2 100644 --- a/racket/collects/syntax/free-vars.rkt +++ b/racket/collects/syntax/free-vars.rkt @@ -43,12 +43,15 @@ [(null? f) null] [(syntax? f) (loop (syntax-e f))]))) -;; free-vars : expr-stx -> (listof id) +;; free-vars : expr-stx [inspector?] [#:module-bound? any/c] -> (listof id) ;; Returns a list of free lambda- and let-bound identifiers in a ;; given epression. The expression must be fully expanded. -(define (free-vars e [code-insp - (variable-reference->module-declaration-inspector - (#%variable-reference))]) +;; If `module-bound?` is true, also return module-bound variables. +(define (free-vars e + [code-insp + (variable-reference->module-declaration-inspector + (#%variable-reference))] + #:module-bound? [module-bound? #f]) (define (submodule-error e) (error 'free-vars "submodules not supported: ~a" e)) ;; It would be nicer to have a functional mapping: @@ -56,12 +59,19 @@ (merge (let free-vars ([e e]) (kernel-syntax-case (syntax-disarm e code-insp) #f - [id - (identifier? #'id) - (if (and (eq? 'lexical (identifier-binding #'id)) - (not (bound-identifier-mapping-get bindings #'id (lambda () #f)))) - (list #'id) - null)] + [id + (identifier? #'id) + (let ([b (identifier-binding #'id)]) + (cond [(and (eq? 'lexical b) + (not (bound-identifier-mapping-get bindings #'id (lambda () #f)))) + (list #'id)] + [(and module-bound? ; do we count module-bound vars too? + ;; we're in an expression context, so any module-bound + ;; variable is free + (list? b)) + (list #'id)] + [else + null]))] [(#%top . id) null] [(quote q) null] [(quote-syntax . _) null] From 4d7e90286e15d9b27372739c8115d969315cf81d Mon Sep 17 00:00:00 2001 From: Michael Campagnaro Date: Sun, 6 Dec 2015 16:05:41 -0500 Subject: [PATCH 143/369] Fix typo in 'more: systems' doc --- pkgs/racket-doc/scribblings/more/more.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/more/more.scrbl b/pkgs/racket-doc/scribblings/more/more.scrbl index 0266f46a55..35d1bfc7bc 100644 --- a/pkgs/racket-doc/scribblings/more/more.scrbl +++ b/pkgs/racket-doc/scribblings/more/more.scrbl @@ -747,7 +747,7 @@ import a library of control operators: Specifically, we need @racket[prompt] and @racket[abort] from @racketmodname[racket/control]. We use @racket[prompt] to mark the place where a servlet is started, so that we can abort a computation -to that point. Change @racket[handle] by wrapping an @racket[prompt] +to that point. Change @racket[handle] by wrapping a @racket[prompt] around the call to @racket[dispatch]: @racketblock[ From 5cd222036647e81e6d1456c0bd8e5addfe30dc3f Mon Sep 17 00:00:00 2001 From: Leif Andersen Date: Mon, 7 Dec 2015 17:54:28 -0500 Subject: [PATCH 144/369] Add coverall support and use new TravisCI Infrastructure --- racket/collects/pkg/private/new.rkt | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/racket/collects/pkg/private/new.rkt b/racket/collects/pkg/private/new.rkt index 5e7ae44c69..14edbefda6 100644 --- a/racket/collects/pkg/private/new.rkt +++ b/racket/collects/pkg/private/new.rkt @@ -99,11 +99,8 @@ language: c # Based from: https://github.com/greghendershott/travis-racket -# Optional: To use Travis CI's newer container infrastucture, -# un-comment the following line. (Also be sure RACKET_DIR is set to -# somewhere like ~/racket that doesn't require sudo.) -# -# sudo: false +# Optional: Remove to use Travis CI's older infrastructure. +sudo: false env: global: @@ -120,9 +117,6 @@ env: # Supply more than one RACKET_VERSION (as in the example below) to # create a Travis-CI build matrix to test against multiple Racket # versions. - # - RACKET_VERSION=5.3.4 - # - RACKET_VERSION=5.3.5 - # - RACKET_VERSION=5.92 - RACKET_VERSION=6.0 - RACKET_VERSION=6.1 - RACKET_VERSION=6.1.1 @@ -149,10 +143,14 @@ before_script: # `raco pkg install --deps search-auto <>` to install any required # packages without it getting stuck on a confirmation prompt. script: - - raco pkg install --deps search-auto + - raco pkg install --deps search-auto cover - raco test -x -p <> -after_script: +after_success: + - raco setup --check-deps <> + - raco pkg install --deps search-auto cover-coveralls + - raco pkg install --deps search-auto + - raco cover -b -f coveralls -d $TRAVIS_BUILD_DIR/coverage . EOS ))) From 6f106d9adc7591a9dea432aa4473035635e559a4 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 7 Dec 2015 16:39:33 -0500 Subject: [PATCH 145/369] incremental GC: more precising counting of work done --- racket/src/racket/gc2/newgc.c | 16 +++++++++++++++- racket/src/racket/gc2/newgc.h | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index b4e7e54c16..69d71c3280 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -4062,6 +4062,8 @@ void GC_mark2(void *pp, struct NewGC *gc) new_type = 0; /* i.e., not in gen 1/2 */ } + gc->copy_count += size; + /* transfer the object */ ohead->mark = 1; /* mark is copied to newplace, too */ if (size == PAIR_SIZE_IN_BYTES) @@ -4167,6 +4169,8 @@ static inline void propagate_marks_worker(NewGC *gc, void *pp, int inc_gen1) end = PPTR(info) + info->size; } + gc->traverse_count += (end - start); + mark_traverse_object(gc, start, end, alloc_type); } @@ -4207,8 +4211,18 @@ static int propagate_incremental_marks(NewGC *gc, int do_emph, int fuel) void *p; while (fuel && pop_ptr(gc, &p, 1)) { GCDEBUG((DEBUGOUTF, "Popped incremental pointer %p\n", p)); + gc->copy_count = 0; + gc->traverse_count = 0; + propagate_marks_worker(gc, p, 1); - fuel--; + + if (fuel > 0) { + fuel--; + fuel -= (gc->copy_count >> 2); + fuel -= (gc->traverse_count >> 2); + if (fuel < 0) + fuel = 0; + } } } while (do_emph && fuel && mark_ready_ephemerons(gc, 1)); diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index deb14977b8..03323fd128 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -243,6 +243,8 @@ typedef struct NewGC { uintptr_t prop_count; uintptr_t inc_prop_count; + uintptr_t copy_count; /* bytes */ + uintptr_t traverse_count; /* words */ /* These collect information about memory usage, for use in GC_dump. */ uintptr_t peak_memory_use; From c0f4eb8287d38c43cb5e3a8e5c6ed8b77c0aa5f4 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 7 Dec 2015 16:56:52 -0700 Subject: [PATCH 146/369] inctemental GC: make finalization more incremental Allow the process of discovering finalizers to be incremental, including allow interruptions in later levels of ordered finalization. --- racket/src/racket/gc2/fnls.c | 114 ++++++------- racket/src/racket/gc2/newgc.c | 233 +++++++++++++++----------- racket/src/racket/gc2/newgc.h | 16 +- racket/src/racket/gc2/weak.c | 32 ++-- racket/src/racket/src/mzclpf_post.inc | 3 +- 5 files changed, 228 insertions(+), 170 deletions(-) diff --git a/racket/src/racket/gc2/fnls.c b/racket/src/racket/gc2/fnls.c index 755d0047ee..c7ce9b0b9b 100644 --- a/racket/src/racket/gc2/fnls.c +++ b/racket/src/racket/gc2/fnls.c @@ -23,39 +23,28 @@ #undef splay_insert #undef splay_delete -static void remove_finalizer(Fnl *fnl, int gen0, GCTYPE *gc) +static void remove_finalizer(Fnl *fnl, int lvl, GCTYPE *gc) { if (fnl->prev) fnl->prev->next = fnl->next; - else { - if (gen0) - gc->gen0_finalizers = fnl->next; - else - gc->finalizers = fnl->next; - } + else + gc->finalizers[lvl] = 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); + gc->splayed_finalizers[lvl] = fnl_splay_delete((intptr_t)fnl->p, gc->splayed_finalizers[lvl]); } -static void add_finalizer(Fnl *fnl, int gen0, GCTYPE *gc) +static void add_finalizer(Fnl *fnl, int lvl, GCTYPE *gc) { - fnl->next = (gen0 ? gc->gen0_finalizers : gc->finalizers); + fnl->next = gc->finalizers[lvl]; + 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); - } + gc->finalizers[lvl] = fnl; + gc->splayed_finalizers[lvl] = fnl_splay_insert((intptr_t)fnl->p, fnl, gc->splayed_finalizers[lvl]); } void GC_set_finalizer(void *p, int tagged, int level, void (*f)(void *p, void *data), @@ -64,6 +53,7 @@ void GC_set_finalizer(void *p, int tagged, int level, void (*f)(void *p, void *d { GCTYPE *gc = GC_get_GC(); Fnl *fnl; + int lvl; if (!is_finalizable_page(gc, p)) { /* Never collected. Don't finalize it. */ @@ -72,17 +62,18 @@ void GC_set_finalizer(void *p, int tagged, int level, void (*f)(void *p, void *d return; } - 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)) + for (lvl = 0; lvl < NUM_FNL_LEVELS; lvl++) { + gc->splayed_finalizers[lvl] = fnl_splay((intptr_t)p, gc->splayed_finalizers[lvl]); + fnl = gc->splayed_finalizers[lvl]; + 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); + } else { + if (lvl > FNL_LEVEL_GEN_0) { + /* since we're mutating this finalizer, move it to the gen0 set */ + remove_finalizer(fnl, lvl, gc); + add_finalizer(fnl, FNL_LEVEL_GEN_0, gc); + } + break; } } @@ -95,7 +86,7 @@ void GC_set_finalizer(void *p, int tagged, int level, void (*f)(void *p, void *d fnl->eager_level = level; } else { /* remove finalizer */ - remove_finalizer(fnl, 1, gc); + remove_finalizer(fnl, FNL_LEVEL_GEN_0, gc); --gc->num_fnls; } return; @@ -143,7 +134,7 @@ void GC_set_finalizer(void *p, int tagged, int level, void (*f)(void *p, void *d } #endif - add_finalizer(fnl, 1, gc); + add_finalizer(fnl, FNL_LEVEL_GEN_0, gc); gc->num_fnls++; } @@ -151,14 +142,16 @@ static void merge_finalizer_trees(GCTYPE *gc) /* For a full GC, move all finalizers to the gen0 list */ { Fnl *fnl, *next; + int lvl; - for (fnl = gc->finalizers; fnl; fnl = next) { - next = fnl->next; - add_finalizer(fnl, 1, gc); + for (lvl = FNL_LEVEL_GEN_1; lvl < NUM_FNL_LEVELS; lvl++) { + for (fnl = gc->finalizers[lvl]; fnl; fnl = next) { + next = fnl->next; + add_finalizer(fnl, FNL_LEVEL_GEN_0, gc); + } + gc->finalizers[lvl] = NULL; + gc->splayed_finalizers[lvl] = NULL; } - - gc->finalizers = NULL; - gc->splayed_finalizers = NULL; } static void reset_finalizer_tree(GCTYPE *gc) @@ -168,9 +161,30 @@ static void reset_finalizer_tree(GCTYPE *gc) { Fnl *fnl, *next; - fnl = gc->gen0_finalizers; - gc->gen0_finalizers = NULL; - gc->splayed_gen0_finalizers = NULL; + if (gc->gc_full) { + GC_ASSERT(!gc->finalizers[FNL_LEVEL_INC_1]); + GC_ASSERT(!gc->splayed_finalizers[FNL_LEVEL_INC_1]); + GC_ASSERT(!gc->finalizers[FNL_LEVEL_INC_2]); + GC_ASSERT(!gc->splayed_finalizers[FNL_LEVEL_INC_2]); + if (gc->finished_incremental) { + fnl = gc->finalizers[FNL_LEVEL_GEN_1]; + for (; fnl; fnl = next) { + next = fnl->next; + add_finalizer(fnl, FNL_LEVEL_INC_3, gc); + } + gc->finalizers[FNL_LEVEL_GEN_1] = gc->finalizers[FNL_LEVEL_INC_3]; + gc->splayed_finalizers[FNL_LEVEL_GEN_1] = gc->splayed_finalizers[FNL_LEVEL_INC_3]; + gc->finalizers[FNL_LEVEL_INC_3] = NULL; + gc->splayed_finalizers[FNL_LEVEL_INC_3] = NULL; + } else { + GC_ASSERT(!gc->finalizers[FNL_LEVEL_INC_3]); + GC_ASSERT(!gc->splayed_finalizers[FNL_LEVEL_INC_3]); + } + } + + fnl = gc->finalizers[FNL_LEVEL_GEN_0]; + gc->finalizers[FNL_LEVEL_GEN_0] = NULL; + gc->splayed_finalizers[FNL_LEVEL_GEN_0] = NULL; for (; fnl; fnl = next) { next = fnl->next; @@ -182,22 +196,8 @@ static void reset_finalizer_tree(GCTYPE *gc) || 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); + add_finalizer(fnl, FNL_LEVEL_GEN_0, gc); else - add_finalizer(fnl, 0, gc); - } -} - -static void reset_gen1_finalizer_tree(GCTYPE *gc) -{ - Fnl *fnl, *next; - - fnl = gc->finalizers; - gc->finalizers = NULL; - gc->splayed_finalizers = NULL; - - for (; fnl; fnl = next) { - next = fnl->next; - add_finalizer(fnl, 0, gc); + add_finalizer(fnl, FNL_LEVEL_GEN_1, gc); } } diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 69d71c3280..7b4aad3149 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -102,7 +102,8 @@ enum { AGE_GEN_0 = 0, AGE_GEN_HALF = 1, AGE_GEN_1 = 2, - AGE_VACATED = 3 + AGE_VACATED = 3, /* used for pages to be removed */ + AGE_GEN_INC = 4 /* used for naming a finalizer set */ }; static const char *type_name[PAGE_TYPES] = { @@ -2472,23 +2473,20 @@ static int is_finalizable_page(NewGC *gc, void *p) #include "fnls.c" -inline static void mark_finalizer_structs(NewGC *gc, int old_gen) +inline static void mark_finalizer_structs(NewGC *gc, int lvl) { Fnl *fnl; - set_backtrace_source(gc, &gc->gen0_finalizers, BT_ROOT); - if (old_gen) - gcMARK2(gc->finalizers, gc); - else - gcMARK2(gc->gen0_finalizers, gc); - for(fnl = (old_gen ? gc->finalizers : gc->gen0_finalizers); fnl; fnl = fnl->next) { + set_backtrace_source(gc, &gc->finalizers[lvl], BT_ROOT); + gcMARK2(gc->finalizers[lvl], gc); + for(fnl = gc->finalizers[lvl]; fnl; fnl = fnl->next) { set_backtrace_source(gc, fnl, BT_FINALIZER); gcMARK2(fnl->data, gc); - set_backtrace_source(gc, &gc->gen0_finalizers, BT_ROOT); + set_backtrace_source(gc, &gc->finalizers[lvl], BT_ROOT); gcMARK2(fnl->next, gc); } - if (!old_gen) { + if (lvl == FNL_LEVEL_GEN_0) { set_backtrace_source(gc, &gc->run_queue, BT_ROOT); gcMARK2(gc->run_queue, gc); for(fnl = gc->run_queue; fnl; fnl = fnl->next) { @@ -2509,20 +2507,20 @@ inline static void mark_finalizer_structs(NewGC *gc, int old_gen) gcMARK2(fnl->next, gc); } } -} +} inline static void repair_finalizer_structs(NewGC *gc) { Fnl *fnl; /* repair the base parts of the list */ - gcFIXUP2(gc->gen0_finalizers, gc); + gcFIXUP2(gc->finalizers[FNL_LEVEL_GEN_0], gc); gcFIXUP2(gc->run_queue, gc); gcFIXUP2(gc->last_in_queue, gc); gcFIXUP2(gc->inc_run_queue, gc); gcFIXUP2(gc->inc_last_in_queue, gc); /* then repair the stuff inside them */ - for(fnl = gc->gen0_finalizers; fnl; fnl = fnl->next) { + for(fnl = gc->finalizers[FNL_LEVEL_GEN_0]; fnl; fnl = fnl->next) { gcFIXUP2(fnl->data, gc); gcFIXUP2(fnl->p, gc); gcFIXUP2(fnl->next, gc); @@ -2552,45 +2550,61 @@ static void merge_run_queues(NewGC *gc) } } -inline static void check_finalizers(NewGC *gc, int level, int old_gen) +inline static int check_finalizers(NewGC *gc, int level, int old_gen, int fuel) { - Fnl *work = (old_gen - ? GC_resolve2(gc->finalizers, gc) - : GC_resolve2(gc->gen0_finalizers, gc)); + int lvl = (old_gen + ? (FNL_LEVEL_GEN_1 + level - 1) + : FNL_LEVEL_GEN_0); + Fnl *work = GC_resolve2(gc->finalizers[lvl], gc); Fnl *prev = NULL; + if (!fuel) return 0; + GCDEBUG((DEBUGOUTF, "CFNL: Checking level %i finalizers\n", level)); while(work) { + if (!fuel) { + GC_ASSERT(old_gen); + return 0; + } + if (fuel > 0) { + fuel -= 4; + if (fuel < 0) fuel = 0; + } + if((work->eager_level == level) && !marked(gc, work->p)) { - struct finalizer *next = GC_resolve2(work->next, gc); + struct finalizer *next; GCDEBUG((DEBUGOUTF, "CFNL: Level %i finalizer %p on %p queued for finalization.\n", work->eager_level, work, work->p)); set_backtrace_source(gc, work, BT_FINALIZER); gcMARK2(work->p, gc); - if (prev) - prev->next = next; - else if (old_gen) - gc->finalizers = next; - else - gc->gen0_finalizers = next; - if (next) - next->prev = work->prev; - work->prev = NULL; /* queue is singly-linked */ - work->left = NULL; - work->right = NULL; if (old_gen) { + remove_finalizer(work, lvl, gc); + next = gc->finalizers[lvl]; + if (gc->inc_last_in_queue) gc->inc_last_in_queue = gc->inc_last_in_queue->next = work; else gc->inc_run_queue = gc->inc_last_in_queue = work; } else { + next = GC_resolve2(work->next, gc); + if (prev) + prev->next = next; + else + gc->finalizers[lvl] = next; + if (next) + next->prev = work->prev; + work->prev = NULL; /* queue is singly-linked */ + work->left = NULL; + work->right = NULL; + if (gc->last_in_queue) gc->last_in_queue = gc->last_in_queue->next = work; else gc->run_queue = gc->last_in_queue = work; } + work->next = NULL; --gc->num_fnls; @@ -2600,13 +2614,23 @@ inline static void check_finalizers(NewGC *gc, int level, int old_gen) 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); + if (old_gen) { + /* Move to next set of finalizers */ + GC_ASSERT(lvl < FNL_LEVEL_INC_3); + remove_finalizer(work, lvl, gc); + add_finalizer(work, lvl+1, gc); + work = gc->finalizers[lvl]; + } else { + p = GC_resolve2(work->p, gc); + if (p != work->p) + work->p = p; + prev = work; + work = GC_resolve2(work->next, gc); + } } } + + return fuel; } /*****************************************************************************/ @@ -3089,10 +3113,14 @@ static int designate_modified_gc(NewGC *gc, void *p) /* Some marking functions, like the one for weak boxes, update the record, so it's ok to make the page writable. */ && (gc->inc_gen1 + /* Finalization in incremental mode can touch otherwise + pages that are otherwise unmodified in the current pass: */ + || gc->fnl_gen1 /* Memory accounting can also modify otherwise unadjusted pages after incrementa mode: */ || (gc->doing_memory_accounting && gc->finished_incremental))) { check_incremental_unprotect(gc, page); + gc->unprotected_page = 1; /* for using fuel */ return 1; } GCPRINT(GCOUTF, "Seg fault (internal error during gc) at %p\n", p); @@ -4199,6 +4227,8 @@ static int propagate_incremental_marks(NewGC *gc, int do_emph, int fuel) { int save_inc, save_check, init_fuel = fuel; + if (!fuel) return 0; + GC_ASSERT(gc->mark_gen1); save_inc = gc->inc_gen1; @@ -4220,6 +4250,10 @@ static int propagate_incremental_marks(NewGC *gc, int do_emph, int fuel) fuel--; fuel -= (gc->copy_count >> 2); fuel -= (gc->traverse_count >> 2); + if (gc->unprotected_page) { + gc->unprotected_page = 0; + fuel -= 100; + } if (fuel < 0) fuel = 0; } @@ -5913,101 +5947,106 @@ extern double scheme_get_inexact_milliseconds(void); #define AS_100M(c) ((c / (1024 * 1024 * 100)) + 1) -static int mark_and_finalize_all(NewGC *gc, int old_gen TIME_FORMAL_ARGS) +static int mark_and_finalize_all(NewGC *gc, int old_gen, int no_full TIME_FORMAL_ARGS) { - int fuel = (INCREMENTAL_COLLECT_FUEL_PER_100M * AS_100M(gc->memory_in_use)) / 2; + int fuel = (old_gen + ? (no_full + ? INCREMENTAL_COLLECT_FUEL_PER_100M / INCREMENTAL_MINOR_REQUEST_DIVISOR + : (INCREMENTAL_COLLECT_FUEL_PER_100M * AS_100M(gc->memory_in_use)) / 2) + : -1); + int reset_gen1; + + /* Propagate marks */ + if (!old_gen) + propagate_marks_plus_ephemerons(gc); + else + fuel = propagate_incremental_marks(gc, 1, fuel); + + /* check finalizers at level 1 */ + fuel = check_finalizers(gc, 1, old_gen, fuel); if (!old_gen) propagate_marks_plus_ephemerons(gc); else - (void)propagate_incremental_marks(gc, 1, -1); - - check_finalizers(gc, 1, old_gen); - if (!old_gen) - propagate_marks_plus_ephemerons(gc); - else { fuel = propagate_incremental_marks(gc, 1, fuel); - if (!fuel) - return 1; - } TIME_STEP("marked"); - if (old_gen) { + if (old_gen || (gc->gc_full && gc->finished_incremental)) { GC_ASSERT(!gc->fnl_gen1); gc->fnl_gen1 = 1; - } + reset_gen1 = 1; + } else + reset_gen1 = 0; if (gc->gc_full) - (void)zero_weak_boxes(gc, 0, 0, 1, -1); - fuel = zero_weak_boxes(gc, 0, 0, old_gen, (old_gen ? fuel : -1)); - if (old_gen && !fuel) { - gc->fnl_gen1 = 0; - return 1; - } + (void)zero_weak_boxes(gc, 0, 0, 1, 1, -1); + fuel = zero_weak_boxes(gc, 0, 0, old_gen, !old_gen, fuel); if (gc->gc_full) - (void)zero_weak_arrays(gc, 0, 1, -1); - fuel = zero_weak_arrays(gc, 0, old_gen, (old_gen ? fuel : -1)); - if (old_gen && !fuel) { - gc->fnl_gen1 = 0; - return 1; - } + (void)zero_weak_arrays(gc, 0, 1, 1, -1); + fuel = zero_weak_arrays(gc, 0, old_gen, !old_gen, fuel); if (gc->gc_full) zero_remaining_ephemerons(gc, 1); - zero_remaining_ephemerons(gc, old_gen); + if (fuel) + zero_remaining_ephemerons(gc, old_gen); TIME_STEP("zeroed"); - - check_finalizers(gc, 2, old_gen); + + fuel = check_finalizers(gc, 2, old_gen, fuel); + if (!old_gen) propagate_marks(gc); else - (void)propagate_incremental_marks(gc, 0, -1); + fuel = propagate_incremental_marks(gc, 0, fuel); + if (gc->gc_full) - (void)zero_weak_boxes(gc, 1, 0, 1, -1); - (void)zero_weak_boxes(gc, 1, 0, old_gen, -1); + (void)zero_weak_boxes(gc, 1, 0, 1, 1, -1); + fuel = zero_weak_boxes(gc, 1, 0, old_gen, !old_gen, fuel); + + fuel = check_finalizers(gc, 3, old_gen, fuel); - check_finalizers(gc, 3, old_gen); if (!old_gen) propagate_marks(gc); else - (void)propagate_incremental_marks(gc, 0, -1); + fuel = propagate_incremental_marks(gc, 0, fuel); - if (gc->GC_post_propagate_hook) + if (fuel && gc->GC_post_propagate_hook) gc->GC_post_propagate_hook(gc); + + if (fuel) { + /* for any new ones that appeared: */ + (void)zero_weak_boxes(gc, 0, 1, old_gen, 0, -1); + (void)zero_weak_boxes(gc, 1, 1, old_gen, 0, -1); + (void)zero_weak_arrays(gc, 1, old_gen, 0, -1); + zero_remaining_ephemerons(gc, old_gen); - /* for any new ones that appeared: */ - (void)zero_weak_boxes(gc, 0, 1, old_gen, -1); - (void)zero_weak_boxes(gc, 1, 1, old_gen, -1); - (void)zero_weak_arrays(gc, 1, old_gen, -1); - zero_remaining_ephemerons(gc, old_gen); - - GC_ASSERT(!gc->weak_arrays); - GC_ASSERT(!gc->bp_weak_arrays); - GC_ASSERT(!gc->weak_boxes[0]); - GC_ASSERT(!gc->weak_boxes[1]); - GC_ASSERT(!gc->bp_weak_boxes[0]); - GC_ASSERT(!gc->bp_weak_boxes[1]); - GC_ASSERT(!gc->ephemerons); - GC_ASSERT(!gc->bp_ephemerons); - if (gc->gc_full) { - GC_ASSERT(!gc->inc_weak_arrays); - GC_ASSERT(!gc->inc_weak_boxes[0]); - GC_ASSERT(!gc->inc_weak_boxes[1]); - GC_ASSERT(!gc->inc_ephemerons); + GC_ASSERT(!gc->weak_arrays); + GC_ASSERT(!gc->bp_weak_arrays); + GC_ASSERT(!gc->weak_boxes[0]); + GC_ASSERT(!gc->weak_boxes[1]); + GC_ASSERT(!gc->bp_weak_boxes[0]); + GC_ASSERT(!gc->bp_weak_boxes[1]); + GC_ASSERT(!gc->ephemerons); + GC_ASSERT(!gc->bp_ephemerons); + if (gc->gc_full) { + GC_ASSERT(!gc->inc_weak_arrays); + GC_ASSERT(!gc->inc_weak_boxes[0]); + GC_ASSERT(!gc->inc_weak_boxes[1]); + GC_ASSERT(!gc->inc_ephemerons); + } } - if (old_gen) + if (reset_gen1) gc->fnl_gen1 = 0; TIME_STEP("finalized"); - return 0; + return !fuel; } -static int mark_and_finalize_all_incremental(NewGC *gc TIME_FORMAL_ARGS) +static int mark_and_finalize_all_incremental(NewGC *gc, int no_full TIME_FORMAL_ARGS) { int save_inc, save_check, more_to_do; @@ -6019,7 +6058,7 @@ static int mark_and_finalize_all_incremental(NewGC *gc TIME_FORMAL_ARGS) gc->inc_gen1 = 1; gc->check_gen1 = 1; - more_to_do = mark_and_finalize_all(gc, 1 TIME_ARGS); + more_to_do = mark_and_finalize_all(gc, 1, no_full TIME_ARGS); gc->inc_gen1 = save_inc; gc->check_gen1 = save_check; @@ -6168,7 +6207,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin /* mark and repair the roots for collection */ mark_backpointers(gc); TIME_STEP("backpointered"); - mark_finalizer_structs(gc, 0); + mark_finalizer_structs(gc, FNL_LEVEL_GEN_0); TIME_STEP("pre-rooted"); mark_roots(gc); mark_immobiles(gc); @@ -6183,11 +6222,11 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin /* now propagate/repair the marks we got from these roots, and do the finalizer passes */ - (void)mark_and_finalize_all(gc, 0 TIME_ARGS); + (void)mark_and_finalize_all(gc, 0, no_full TIME_ARGS); if (do_incremental) { if (!gc->all_marked_incremental) { - mark_finalizer_structs(gc, 1); + mark_finalizer_structs(gc, FNL_LEVEL_GEN_1); if (!mark_stack_is_empty(gc->inc_mark_stack)) { int fuel = (no_full ? INCREMENTAL_COLLECT_FUEL_PER_100M / INCREMENTAL_MINOR_REQUEST_DIVISOR @@ -6197,12 +6236,10 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin } else { /* We ran out of incremental marking work, so perform major-GC finalization */ - if (mark_and_finalize_all_incremental(gc TIME_ARGS)) { + if (mark_and_finalize_all_incremental(gc, no_full TIME_ARGS)) { /* More finalizaton work to do */ - reset_gen1_finalizer_tree(gc); } else { BTC_clean_up_gen1(gc); - reset_gen1_finalizer_tree(gc); /* Switch to incrementally reparing pages */ gc->all_marked_incremental = 1; } @@ -6244,10 +6281,10 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin repair_heap(gc); TIME_STEP("repaired"); if (check_inc_repair) { - GC_ASSERT(gc->all_marked_incremental); int fuel = (no_full ? INCREMENTAL_REPAIR_FUEL_PER_100M / INCREMENTAL_MINOR_REQUEST_DIVISOR : INCREMENTAL_REPAIR_FUEL_PER_100M * AS_100M(gc->memory_in_use)); + GC_ASSERT(gc->all_marked_incremental); incremental_repair_pages(gc, fuel); TIME_STEP("inc-repaired"); if (!gc->inc_repair_next) diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 03323fd128..973eeb3dec 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -149,6 +149,15 @@ typedef mpage **PageMap; #define NUM_MED_PAGE_SIZES (((LOG_APAGE_SIZE - 1) - 3) + 1) +enum { + FNL_LEVEL_GEN_0, + FNL_LEVEL_GEN_1, + FNL_LEVEL_INC_1, + FNL_LEVEL_INC_2, + FNL_LEVEL_INC_3, + NUM_FNL_LEVELS +}; + typedef struct NewGC { Gen0 gen0; Gen_Half gen_half; @@ -221,6 +230,7 @@ typedef struct NewGC { unsigned char during_backpointer :1; unsigned char incremental_requested :1; unsigned char high_fragmentation :1; + unsigned char unprotected_page :1; /* blame the child */ unsigned int doing_memory_accounting :1; @@ -282,10 +292,8 @@ typedef struct NewGC { GC_Immobile_Box *immobile_boxes; - Fnl *finalizers; - Fnl *splayed_finalizers; - Fnl *gen0_finalizers; - Fnl *splayed_gen0_finalizers; + Fnl *finalizers[NUM_FNL_LEVELS]; + Fnl *splayed_finalizers[NUM_FNL_LEVELS]; int num_fnls; void *park[2]; diff --git a/racket/src/racket/gc2/weak.c b/racket/src/racket/gc2/weak.c index d9fcd99a08..e1b0aa5255 100644 --- a/racket/src/racket/gc2/weak.c +++ b/racket/src/racket/gc2/weak.c @@ -155,11 +155,13 @@ static GC_Weak_Array *append_weak_arrays(GC_Weak_Array *wa, GC_Weak_Array *bp_wa return bp_wa; } -static int zero_weak_arrays(GCTYPE *gc, int force_zero, int from_inc, int fuel) +static int zero_weak_arrays(GCTYPE *gc, int force_zero, int from_inc, int need_resolve, int fuel) { GC_Weak_Array *wa; int i, num_gen0; + if (!fuel) return 0; + if (from_inc) { wa = gc->inc_weak_arrays; num_gen0 = 0; @@ -177,11 +179,13 @@ static int zero_weak_arrays(GCTYPE *gc, int force_zero, int from_inc, int fuel) void *p = data[i]; if (p && (force_zero || !is_marked(gc, p))) data[i] = wa->replace_val; - else + else if (need_resolve) data[i] = GC_resolve2(p, gc); } - if (fuel > 0) - fuel = ((fuel > wa->count) ? (fuel - wa->count) : 0); + if (fuel > 0) { + fuel -= (4 * wa->count); + if (fuel < 0) fuel = 0; + } if (num_gen0 > 0) { if (!is_in_generation_half(gc, wa)) { @@ -348,11 +352,13 @@ static GC_Weak_Box *append_weak_boxes(GC_Weak_Box *wb, GC_Weak_Box *bp_wb, int * return bp_wb; } -static int zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero, int from_inc, int fuel) +static int zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero, int from_inc, int need_resolve, int fuel) { GC_Weak_Box *wb; int num_gen0; + if (!fuel) return 0; + if (from_inc) { wb = gc->inc_weak_boxes[is_late]; num_gen0 = 0; @@ -388,9 +394,9 @@ static int zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero, int from_inc *(p + wb->soffset) = NULL; wb->secondary_erase = NULL; } - } else { + } else if (need_resolve) wb->val = GC_resolve2(wb->val, gc); - } + if (num_gen0 > 0) { if (!is_in_generation_half(gc, wb)) { if (!gc->all_marked_incremental) { @@ -405,6 +411,7 @@ static int zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero, int from_inc } } } + if (from_inc) { GC_Weak_Box *next; next = wb->inc_next; @@ -416,9 +423,14 @@ static int zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero, int from_inc num_gen0--; if (fuel >= 0) { - if (fuel > 0) - fuel--; - else { + if (fuel > 0) { + if (gc->unprotected_page) { + fuel -= 100; + gc->unprotected_page = 0; + } else + fuel -= 4; + if (fuel < 0) fuel = 0; + } else { GC_ASSERT(from_inc); gc->inc_weak_boxes[is_late] = wb; return 0; diff --git a/racket/src/racket/src/mzclpf_post.inc b/racket/src/racket/src/mzclpf_post.inc index 1a0303a9f0..9b47dc1f48 100644 --- a/racket/src/racket/src/mzclpf_post.inc +++ b/racket/src/racket/src/mzclpf_post.inc @@ -27,7 +27,8 @@ /* We're the first to look at this prefix... */ /* Add it to the chain of prefixes to finish after all other marking: */ - if (gc_mode == GC_CURRENT_MODE_INCREMENTAL) { + if ((gc_mode == GC_CURRENT_MODE_INCREMENTAL) + || (gc_mode == GC_CURRENT_MODE_INCREMENTAL_FINAL)) { pf->next_final = scheme_inc_prefix_finalize; scheme_inc_prefix_finalize = pf; } else { From 5a01b9740078b6784b75e243074376770f80774a Mon Sep 17 00:00:00 2001 From: Leif Andersen Date: Wed, 9 Dec 2015 11:58:18 -0500 Subject: [PATCH 147/369] Remove typo in docs for expand-syntax-top-level-with-compile-time-evals Duplicate 'of' words. --- pkgs/racket-doc/syntax/scribblings/toplevel.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/syntax/scribblings/toplevel.scrbl b/pkgs/racket-doc/syntax/scribblings/toplevel.scrbl index 30f79feb9d..3874194286 100644 --- a/pkgs/racket-doc/syntax/scribblings/toplevel.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/toplevel.scrbl @@ -12,7 +12,7 @@ Expands @racket[stx] as a top-level expression, and evaluates its compile-time portion for the benefit of later expansions. The expander recognizes top-level @racket[begin] expressions, and -interleaves the evaluation and expansion of of the @racket[begin] +interleaves the evaluation and expansion of the @racket[begin] body, so that compile-time expressions within the @racket[begin] body affect later expansions within the body. (In other words, it ensures that expanding a @racket[begin] is the same as expanding separate From 3d7d906cc1b83e942191fb86ea8d16df11905325 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 9 Dec 2015 16:41:38 -0600 Subject: [PATCH 148/369] tweak and clean up the contract combinators api - uniformly remove the extra layers of calls to unknown functions for chapereone-of? checks that make sure that chaperone contracts are well-behaved (put those checks only in contracts that are created outside racket/contract) - clean up and simplify how missing projection functions are created (val-first vs late-neg vs the regular ones) - add some logging to more accurately tell when late-neg projections aren't being used - port the contract combinator that ->m uses to use late-neg - port the contract? blame? (-> any/c any/c any/c))]{ + Returns the @racket[_late-neg] projection for @racket[c]. + + If @racket[c] does not have a @racket[_late-neg] contract, + then this function uses the original projection for it + and logs a warning to the @racket['racket/contract] logger. + + See @racket[make-contract] for more details. + + @history[#:added "6.2.900.11"] +} + +@defparam[skip-projection-wrapper? wrap? boolean? #:value #f]{ + The functions @racket[make-chaperone-contract] and + @racket[build-chaperone-contract-property] wrap their + arguments to ensure that the result of the projections + are chaperones of the input. This layer of wrapping can, + in some cases, introduce unwanted overhead into contract + checking. If this parameter's value is @racket[#t] + during the dynamic extent of the call to either of those + functions, the wrapping (and thus the checks) are skipped. +} + @subsection{Blame Objects} @defproc[(blame? [x any/c]) boolean?]{ @@ -2526,6 +2553,9 @@ whose values will be generated by this process; and @racket[is-flat-contract?], which is used by @racket[flat-contract?] to determine if this contract accepts only @racket[list?]s. +At least one of the @racket[late-neg-proj], @racket[proj], +@racket[val-first-proj], or @racket[first-order] must be non-@racket[#f]. + These accessors are passed as (optional) keyword arguments to @racket[build-contract-property], and are applied to instances of the appropriate structure type by the contract system. Their results are used diff --git a/pkgs/racket-test/tests/racket/contract/make-contract.rkt b/pkgs/racket-test/tests/racket/contract/make-contract.rkt index 8f7ff01bf2..04bb43c3d1 100644 --- a/pkgs/racket-test/tests/racket/contract/make-contract.rkt +++ b/pkgs/racket-test/tests/racket/contract/make-contract.rkt @@ -134,6 +134,52 @@ '(contract proj:bad-prime-box-list/c (list (box 2) (box 3)) 'pos 'neg) exn:fail?) + (contract-eval + '(define val-first-proj:bad-prime-box-list/c + (let* ([prime? (λ (n) + (for/and ([m (in-range 2 (add1 (floor (sqrt n))))]) + (not (= (remainder n m) 0))))] + [wrap-box (λ (blame b) (box (unbox b)))]) + (make-chaperone-contract + #:name 'bad-prime-box-list/c + #:first-order (λ (v) (and (list? v) (andmap box? v))) + #:val-first-projection + (λ (blame) + (λ (v) + (λ (neg-party) + (unless (and (list? v) (andmap box? v)) + (raise-blame-error blame v + #:missing-party neg-party + "expected list of boxes, got ~v" v)) + (map (λ (b) (wrap-box blame b)) v)))))))) + + (contract-error-test + 'contract-error-test6 + '(contract val-first-proj:bad-prime-box-list/c (list (box 2) (box 3)) 'pos 'neg) + exn:fail?) + + (contract-eval + '(define late-neg-proj:bad-prime-box-list/c + (let* ([prime? (λ (n) + (for/and ([m (in-range 2 (add1 (floor (sqrt n))))]) + (not (= (remainder n m) 0))))] + [wrap-box (λ (blame b) (box (unbox b)))]) + (make-chaperone-contract + #:name 'bad-prime-box-list/c + #:first-order (λ (v) (and (list? v) (andmap box? v))) + #:late-neg-projection + (λ (blame) + (λ (v neg-party) + (unless (and (list? v) (andmap box? v)) + (raise-blame-error blame v + "expected list of boxes, got ~v" v)) + (map (λ (b) (wrap-box blame b)) v))))))) + + (contract-error-test + 'contract-error-test7 + '(contract late-neg-proj:bad-prime-box-list/c (list (box 2) (box 3)) 'pos 'neg) + exn:fail?) + (test/pos-blame 'build-chaperone-contract-property1 '(let () @@ -156,6 +202,88 @@ (((contract-projection (val-first-none)) (make-blame (srcloc #f #f #f #f #f) 5 (λ () 'the-name) 'pos 'neg #t)) 5))) + + (contract-eval + '(define prop:late-neg-proj:bad-prime-box-list/c + (let* ([prime? (λ (n) + (for/and ([m (in-range 2 (add1 (floor (sqrt n))))]) + (not (= (remainder n m) 0))))] + [wrap-box (λ (blame b) (box (unbox b)))]) + (struct ctc () + #:property + prop:chaperone-contract + (build-chaperone-contract-property + #:name (λ (c) 'bad-prime-box-list/c) + #:first-order (λ (c) (λ (v) (and (list? v) (andmap box? v)))) + #:late-neg-projection + (λ (c) + (λ (blame) + (λ (v neg-party) + (unless (and (list? v) (andmap box? v)) + (raise-blame-error blame v #:missing-party neg-party + "expected list of boxes, got ~v" v)) + (map (λ (b) (wrap-box blame b)) v)))))) + (ctc)))) + + (contract-error-test + 'contract-error-test8 + '(contract prop:late-neg-proj:bad-prime-box-list/c (list (box 2) (box 3)) 'pos 'neg) + exn:fail?) + + (contract-eval + '(define prop:val-first-proj:bad-prime-box-list/c + (let* ([prime? (λ (n) + (for/and ([m (in-range 2 (add1 (floor (sqrt n))))]) + (not (= (remainder n m) 0))))] + [wrap-box (λ (blame b) (box (unbox b)))]) + (struct ctc () + #:property + prop:chaperone-contract + (build-chaperone-contract-property + #:name (λ (c) 'bad-prime-box-list/c) + #:first-order (λ (c) (λ (v) (and (list? v) (andmap box? v)))) + #:val-first-projection + (λ (c) + (λ (blame) + (λ (v) + (λ (neg-party) + (unless (and (list? v) (andmap box? v)) + (raise-blame-error blame v #:missing-party neg-party + "expected list of boxes, got ~v" v)) + (map (λ (b) (wrap-box blame b)) v))))))) + (ctc)))) + + (contract-error-test + 'contract-error-test9 + '(contract prop:val-first-proj:bad-prime-box-list/c (list (box 2) (box 3)) 'pos 'neg) + exn:fail?) + + (contract-eval + '(define prop:proj:bad-prime-box-list/c + (let* ([prime? (λ (n) + (for/and ([m (in-range 2 (add1 (floor (sqrt n))))]) + (not (= (remainder n m) 0))))] + [wrap-box (λ (blame b) (box (unbox b)))]) + (struct ctc () + #:property + prop:chaperone-contract + (build-chaperone-contract-property + #:name (λ (c) 'bad-prime-box-list/c) + #:first-order (λ (c) (λ (v) (and (list? v) (andmap box? v)))) + #:projection + (λ (c) + (λ (blame) + (λ (v) + (unless (and (list? v) (andmap box? v)) + (raise-blame-error blame v + "expected list of boxes, got ~v" v)) + (map (λ (b) (wrap-box blame b)) v)))))) + (ctc)))) + + (contract-error-test + 'contract-error-test10 + '(contract prop:proj:bad-prime-box-list/c (list (box 2) (box 3)) 'pos 'neg) + exn:fail?) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -226,4 +354,228 @@ (test/spec-passed/result 'make-flat-contract-bad-6 '(chaperone-contract? proj:prime-list/c) - #t)) \ No newline at end of file + #t) + + (contract-eval + '(define val-first-proj:prime-list/c + (let ([prime? (λ (n) + (for/and ([m (in-range 2 (add1 (floor (sqrt n))))]) + (not (= (remainder n m) 0))))]) + (make-flat-contract + #:name 'prime-list/c + #:first-order (λ (v) (and (list? v) (andmap prime? v))) + #:val-first-projection + (λ (b) + (λ (v) + (λ (neg-party) + (unless (and (list? v) (andmap prime? v)) + (raise-blame-error b v #:missing-party neg-party + "expected prime list, got ~v" v)) + (map values v)))))))) + + + + +(test/spec-passed/result + 'make-flat-contract-bad-7 + '(contract val-first-proj:prime-list/c (list 2 3 5 7) 'pos 'neg) + (list 2 3 5 7)) + +(test/pos-blame + 'make-flat-contract-bad-8 + '(contract val-first-proj:prime-list/c (list 2 3 4 5) 'pos 'neg)) + +(test/spec-passed/result + 'make-flat-contract-bad-9 + '(let ([l (list 2 3 5 7)]) + (eq? l (contract val-first-proj:prime-list/c l 'pos 'neg))) + #t) + +(ctest #t contract? val-first-proj:prime-list/c) +(ctest #t flat-contract? val-first-proj:prime-list/c) + +(test/spec-passed/result + 'make-flat-contract-bad-10 + '(chaperone-contract? val-first-proj:prime-list/c) + #t) + + + (contract-eval + '(define late-neg-proj:prime-list/c + (let ([prime? (λ (n) + (for/and ([m (in-range 2 (add1 (floor (sqrt n))))]) + (not (= (remainder n m) 0))))]) + (make-flat-contract + #:name 'prime-list/c + #:first-order (λ (v) (and (list? v) (andmap prime? v))) + #:late-neg-projection + (λ (b) + (λ (v neg-party) + (unless (and (list? v) (andmap prime? v)) + (raise-blame-error b v #:missing-party neg-party "expected prime list, got ~v" v)) + (map values v))))))) + + + + +(test/spec-passed/result + 'make-flat-contract-bad-11 + '(contract late-neg-proj:prime-list/c (list 2 3 5 7) 'pos 'neg) + (list 2 3 5 7)) + +(test/pos-blame + 'make-flat-contract-bad-12 + '(contract late-neg-proj:prime-list/c (list 2 3 4 5) 'pos 'neg)) + +(test/spec-passed/result + 'make-flat-contract-bad-13 + '(let ([l (list 2 3 5 7)]) + (eq? l (contract late-neg-proj:prime-list/c l 'pos 'neg))) + #t) + +(ctest #t contract? late-neg-proj:prime-list/c) +(ctest #t flat-contract? late-neg-proj:prime-list/c) + +(test/spec-passed/result + 'make-flat-contract-bad-14 + '(chaperone-contract? late-neg-proj:prime-list/c) + #t) + + +(contract-eval + '(define prop:proj:prime-list/c + (let ([prime? (λ (n) + (for/and ([m (in-range 2 (add1 (floor (sqrt n))))]) + (not (= (remainder n m) 0))))]) + (struct ctc () + #:property + prop:flat-contract + (build-flat-contract-property + #:name (λ (c) 'prime-list/c) + #:first-order (λ (c) (λ (v) (and (list? v) (andmap prime? v)))) + #:projection + (λ (c) + (λ (b) + (λ (v) + (unless (and (list? v) (andmap prime? v)) + (raise-blame-error b v "expected prime list, got ~v" v)) + (map values v)))))) + + (ctc)))) + +(test/spec-passed/result + 'make-flat-contract-bad-15 + '(contract prop:proj:prime-list/c (list 2 3 5 7) 'pos 'neg) + (list 2 3 5 7)) + +(test/pos-blame + 'make-flat-contract-bad-16 + '(contract prop:proj:prime-list/c (list 2 3 4 5) 'pos 'neg)) + +(test/spec-passed/result + 'make-flat-contract-bad-17 + '(let ([l (list 2 3 5 7)]) + (eq? l (contract prop:proj:prime-list/c l 'pos 'neg))) + #t) + +(ctest #t contract? prop:proj:prime-list/c) +(ctest #t flat-contract? prop:proj:prime-list/c) + +(test/spec-passed/result + 'make-flat-contract-bad-18 + '(chaperone-contract? prop:proj:prime-list/c) + #t) + + +(contract-eval + '(define prop:val-first-proj:prime-list/c + (let ([prime? (λ (n) + (for/and ([m (in-range 2 (add1 (floor (sqrt n))))]) + (not (= (remainder n m) 0))))]) + (struct ctc () + #:property + prop:flat-contract + (build-flat-contract-property + #:name (λ (c) 'prime-list/c) + #:first-order (λ (c) (λ (v) (and (list? v) (andmap prime? v)))) + #:val-first-projection + (λ (c) + (λ (b) + (λ (v) + (λ (neg-party) + (unless (and (list? v) (andmap prime? v)) + (raise-blame-error b v + #:missing-party neg-party + "expected prime list, got ~v" v)) + (map values v))))))) + + (ctc)))) + +(test/spec-passed/result + 'make-flat-contract-bad-19 + '(contract prop:val-first-proj:prime-list/c (list 2 3 5 7) 'pos 'neg) + (list 2 3 5 7)) + +(test/pos-blame + 'make-flat-contract-bad-20 + '(contract prop:val-first-proj:prime-list/c (list 2 3 4 5) 'pos 'neg)) + +(test/spec-passed/result + 'make-flat-contract-bad-21 + '(let ([l (list 2 3 5 7)]) + (eq? l (contract prop:val-first-proj:prime-list/c l 'pos 'neg))) + #t) + +(ctest #t contract? prop:val-first-proj:prime-list/c) +(ctest #t flat-contract? prop:val-first-proj:prime-list/c) + +(test/spec-passed/result + 'make-flat-contract-bad-22 + '(chaperone-contract? prop:val-first-proj:prime-list/c) + #t) + + (contract-eval + '(define prop:late-neg-proj:prime-list/c + (let ([prime? (λ (n) + (for/and ([m (in-range 2 (add1 (floor (sqrt n))))]) + (not (= (remainder n m) 0))))]) + (struct ctc () + #:property + prop:flat-contract + (build-flat-contract-property + #:name (λ (c) 'prime-list/c) + #:first-order (λ (c) (λ (v) (and (list? v) (andmap prime? v)))) + #:late-neg-projection + (λ (c) + (λ (b) + (λ (v neg-party) + (unless (and (list? v) (andmap prime? v)) + (raise-blame-error b v + #:missing-party neg-party + "expected prime list, got ~v" v)) + (map values v)))))) + + (ctc)))) + +(test/spec-passed/result + 'make-flat-contract-bad-23 + '(contract prop:late-neg-proj:prime-list/c (list 2 3 5 7) 'pos 'neg) + (list 2 3 5 7)) + +(test/pos-blame + 'make-flat-contract-bad-24 + '(contract prop:late-neg-proj:prime-list/c (list 2 3 4 5) 'pos 'neg)) + +(test/spec-passed/result + 'make-flat-contract-bad-25 + '(let ([l (list 2 3 5 7)]) + (eq? l (contract prop:late-neg-proj:prime-list/c l 'pos 'neg))) + #t) + +(ctest #t contract? prop:late-neg-proj:prime-list/c) +(ctest #t flat-contract? prop:late-neg-proj:prime-list/c) + +(test/spec-passed/result + 'make-flat-contract-bad-26 + '(chaperone-contract? prop:late-neg-proj:prime-list/c) + #t)) diff --git a/racket/collects/racket/contract/combinator.rkt b/racket/collects/racket/contract/combinator.rkt index b2075fe620..5072060024 100644 --- a/racket/collects/racket/contract/combinator.rkt +++ b/racket/collects/racket/contract/combinator.rkt @@ -1,5 +1,6 @@ #lang racket/base (require "private/prop.rkt" + (prefix-in : "private/prop.rkt") "private/guts.rkt" "private/blame.rkt") @@ -12,7 +13,11 @@ contract-struct-stronger? contract-struct? chaperone-contract-struct? - flat-contract-struct?) + flat-contract-struct? + make-chaperone-contract + make-flat-contract + build-chaperone-contract-property + build-flat-contract-property) (except-out (all-from-out "private/guts.rkt") check-flat-contract @@ -21,4 +26,177 @@ has-contract? value-contract) - (except-out (all-from-out "private/blame.rkt") make-blame)) + (except-out (all-from-out "private/blame.rkt") make-blame) + (rename-out [-make-chaperone-contract make-chaperone-contract] + [-make-flat-contract make-flat-contract] + [-build-chaperone-contract-property build-chaperone-contract-property] + [-build-flat-contract-property build-flat-contract-property]) + skip-projection-wrapper?) + +(define skip-projection-wrapper? (make-parameter #f)) + +(define (maybe-add-wrapper f x) + (cond + [(and x (not (skip-projection-wrapper?))) + (f x)] + [else x])) + +(define -make-chaperone-contract + (let ([make-chaperone-contract + (λ (#:name [name 'anonymous-chaperone-contract] + #:first-order [first-order (λ (x) #t)] + #:late-neg-projection [late-neg-projection #f] + #:val-first-projection [val-first-projection #f] + #:projection [projection #f] + #:stronger [stronger #f] + #:list-contract? [is-list-contract #f]) + (:make-chaperone-contract + #:name name + #:first-order first-order + #:late-neg-projection + (maybe-add-wrapper add-late-neg-chaperone-check late-neg-projection) + #:val-first-projection + (maybe-add-wrapper add-val-first-chaperone-check val-first-projection) + #:projection + (maybe-add-wrapper add-projection-chaperone-check projection) + #:stronger stronger + #:list-contract? is-list-contract))]) + make-chaperone-contract)) + +(define -build-chaperone-contract-property + (let () + (define (build-chaperone-contract-property + #:name [get-name (λ (c) 'anonymous-chaperone-contract)] + #:first-order [get-first-order (λ (c) (λ (x) #t))] + #:val-first-projection [val-first-proj #f] + #:late-neg-projection [late-neg-proj #f] + #:projection [get-projection #f] + #:stronger [stronger #f] + #:generate [generate #f] + #:exercise [exercise #f]) + (:build-chaperone-contract-property + #:name get-name + #:first-order get-first-order + #:val-first-projection + (maybe-add-wrapper add-prop-val-first-chaperone-check val-first-proj) + #:late-neg-projection + (maybe-add-wrapper add-prop-late-neg-chaperone-check late-neg-proj) + #:projection + (maybe-add-wrapper add-prop-chaperone-check get-projection) + #:stronger stronger + #:generate generate + #:exercise exercise)) + build-chaperone-contract-property)) + +(define (add-prop-late-neg-chaperone-check get-late-neg) + (λ (c) + (add-late-neg-chaperone-check (get-late-neg c)))) + +(define (add-late-neg-chaperone-check accepts-blame) + (λ (b) + (define accepts-val-and-np (accepts-blame b)) + (λ (x neg-party) + (check-and-signal x + (accepts-val-and-np x neg-party) + 'make-chaperone-contract::late-neg-projection)))) + +(define (add-prop-val-first-chaperone-check get) + (λ (c) + (add-val-first-chaperone-check (get c)))) + +(define (add-val-first-chaperone-check vfp) + (λ (b) + (define x-acceptor (vfp b)) + (λ (x) + (define neg-acceptor (x-acceptor x)) + (λ (neg-party) + (check-and-signal x + (neg-acceptor neg-party) + 'make-chaperone-contract::late-neg-projection))))) + +(define (add-prop-chaperone-check get) + (λ (c) + (add-projection-chaperone-check (get c)))) + +(define (add-projection-chaperone-check proj) + (λ (b) + (define x-acceptor (proj b)) + (λ (x) + (check-and-signal x (x-acceptor x) + 'make-chaperone-contract::projection)))) + + +(define (check-and-signal val chapd-val who) + (unless (chaperone-of? chapd-val val) + (raise-result-error who + (format "chaperone-of ~e" val) + chapd-val)) + chapd-val) + +(define -make-flat-contract + (let ([make-flat-contract + (λ (#:name [name 'anonymous-chaperone-contract] + #:first-order [first-order (λ (x) #t)] + #:late-neg-projection [late-neg-projection #f] + #:val-first-projection [val-first-projection #f] + #:projection [projection #f] + #:stronger [stronger #f] + #:list-contract? [is-list-contract #f]) + (:make-flat-contract + #:name name + #:first-order first-order + #:late-neg-projection (force-late-neg-eq late-neg-projection) + #:val-first-projection (force-val-first-eq val-first-projection) + #:projection (force-projection-eq projection) + #:stronger stronger + #:list-contract? is-list-contract))]) + make-flat-contract)) + +(define -build-flat-contract-property + (let ([build-flat-contract-property + (λ (#:name [name (λ (c) 'anonymous-chaperone-contract)] + #:first-order [first-order (λ (c) (λ (x) #t))] + #:late-neg-projection [late-neg-projection #f] + #:val-first-projection [val-first-projection #f] + #:projection [projection #f] + #:stronger [stronger #f] + #:list-contract? [is-list-contract #f]) + (:build-flat-contract-property + #:name name + #:first-order first-order + #:late-neg-projection + (and late-neg-projection (λ (c) (force-late-neg-eq (late-neg-projection c)))) + #:val-first-projection + (and val-first-projection (λ (c) (force-val-first-eq (val-first-projection c)))) + #:projection + (and projection (λ (c) (force-projection-eq (projection c)))) + #:stronger stronger + #:list-contract? is-list-contract))]) + build-flat-contract-property)) + +(define (force-late-neg-eq accepts-blame) + (and accepts-blame + (λ (b) + (define accepts-val-and-np (accepts-blame b)) + (λ (x neg-party) + (accepts-val-and-np x neg-party) + x)))) + +(define (force-val-first-eq vfp) + (and vfp + (λ (b) + (define x-acceptor (vfp b)) + (λ (x) + (define neg-acceptor (x-acceptor x)) + (λ (neg-party) + (neg-acceptor neg-party) + x))))) + +(define (force-projection-eq proj) + (and proj + (λ (b) + (define x-acceptor (proj b)) + (λ (x) + (x-acceptor x) + x)))) + diff --git a/racket/collects/racket/contract/private/arr-i.rkt b/racket/collects/racket/contract/private/arr-i.rkt index e3f6ff3159..d2bf3b4715 100644 --- a/racket/collects/racket/contract/private/arr-i.rkt +++ b/racket/collects/racket/contract/private/arr-i.rkt @@ -87,11 +87,11 @@ (->i-mandatory-args ctc) (->i-mandatory-kwds ctc) (->i-opt-kwds ctc) - blame) + blame #f) (check-procedure val mtd? (->i-mandatory-args ctc) (->i-opt-args ctc) (->i-mandatory-kwds ctc) (->i-opt-kwds ctc) - blame))) + blame #f))) ctc blame swapped-blame ;; used by the #:pre and #:post checking (append blames @@ -313,8 +313,8 @@ [opt-kwds (->i-opt-kwds ctc)]) (λ (val) (if has-rest - (check-procedure/more val mtd? mand-args mand-kwds opt-kwds #f) - (check-procedure val mtd? mand-args opt-args mand-kwds opt-kwds #f))))) + (check-procedure/more val mtd? mand-args mand-kwds opt-kwds #f #f) + (check-procedure val mtd? mand-args opt-args mand-kwds opt-kwds #f #f))))) #:exercise exercise->i #:stronger (λ (this that) (eq? this that)))) ;; WRONG diff --git a/racket/collects/racket/contract/private/arrow-higher-order.rkt b/racket/collects/racket/contract/private/arrow-higher-order.rkt index bcff1fc39d..8015f6c108 100644 --- a/racket/collects/racket/contract/private/arrow-higher-order.rkt +++ b/racket/collects/racket/contract/private/arrow-higher-order.rkt @@ -308,7 +308,7 @@ #`(let-values ([(rng-checker-name ...) (values rng-checker ...)]) (let ([basic-lambda-name basic-lambda]) (arrow:arity-checking-wrapper val - (blame-add-missing-party blame neg-party) + blame neg-party basic-lambda-name void #,min-method-arity @@ -321,7 +321,7 @@ #`(let-values ([(rng-checker-name ...) (values rng-checker ...)]) (let ([kwd-lambda-name kwd-lambda]) (arrow:arity-checking-wrapper val - (blame-add-missing-party blame neg-party) + blame neg-party void kwd-lambda-name #,min-method-arity @@ -335,7 +335,7 @@ (let ([basic-lambda-name basic-lambda] [kwd-lambda-name kwd-lambda]) (arrow:arity-checking-wrapper val - (blame-add-missing-party blame neg-party) + blame neg-party basic-lambda-name kwd-lambda-name #,min-method-arity diff --git a/racket/collects/racket/contract/private/arrow-val-first.rkt b/racket/collects/racket/contract/private/arrow-val-first.rkt index 931eeee516..1345678b5d 100644 --- a/racket/collects/racket/contract/private/arrow-val-first.rkt +++ b/racket/collects/racket/contract/private/arrow-val-first.rkt @@ -911,7 +911,6 @@ (for/list ([kwd (in-list (append mandatory-keywords optional-keywords))] [kwd-proj (in-list (append mandatory-dom-kwd-projs optional-dom-kwd-projs))]) (cons kwd kwd-proj)))) - (define complete-blame (blame-add-missing-party blame neg-party)) (define interposition-proc (make-keyword-procedure @@ -936,7 +935,8 @@ (loop (cdr args) (cdr projs)))]))) (define (result-checker . results) (unless (= rng-len (length results)) - (arrow:bad-number-of-results complete-blame f rng-len results)) + (arrow:bad-number-of-results (blame-add-missing-party blame neg-party) + f rng-len results)) (apply values (for/list ([res (in-list results)] @@ -952,7 +952,7 @@ (cons result-checker args-dealt-with) args-dealt-with))))) - (arrow:arity-checking-wrapper f complete-blame + (arrow:arity-checking-wrapper f blame neg-party interposition-proc interposition-proc min-arity max-arity min-arity max-arity @@ -1176,44 +1176,43 @@ (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 (val-first-proj this)) - (λ (blame) - (define cblame (cthis blame)) - (λ (val) - ((cblame val) #f)))) - #:stronger - (λ (this that) - (and (base->? that) - (= (length (base->-doms that)) - (length (base->-doms this))) - (= (base->-min-arity this) (base->-min-arity that)) - (andmap contract-stronger? (base->-doms that) (base->-doms this)) - (= (length (base->-kwd-infos this)) - (length (base->-kwd-infos that))) - (for/and ([this-kwd-info (base->-kwd-infos this)] - [that-kwd-info (base->-kwd-infos that)]) - (and (equal? (kwd-info-kwd this-kwd-info) - (kwd-info-kwd that-kwd-info)) - (contract-stronger? (kwd-info-ctc that-kwd-info) - (kwd-info-ctc this-kwd-info)))) - (if (base->-rngs this) - (and (base->-rngs that) - (andmap contract-stronger? (base->-rngs this) (base->-rngs that))) - (not (base->-rngs that))) - (not (base->-pre? this)) - (not (base->-pre? that)) - (not (base->-post? this)) - (not (base->-post? that)))) - #:generate ->-generate - #:exercise ->-exercise - #:val-first-projection val-first-proj - #:late-neg-projection late-neg-proj))) + (build-X-property + #:name base->-name + #:first-order ->-first-order + #:projection + (λ (this) + (define cthis (val-first-proj this)) + (λ (blame) + (define cblame (cthis blame)) + (λ (val) + ((cblame val) #f)))) + #:stronger + (λ (this that) + (and (base->? that) + (= (length (base->-doms that)) + (length (base->-doms this))) + (= (base->-min-arity this) (base->-min-arity that)) + (andmap contract-stronger? (base->-doms that) (base->-doms this)) + (= (length (base->-kwd-infos this)) + (length (base->-kwd-infos that))) + (for/and ([this-kwd-info (base->-kwd-infos this)] + [that-kwd-info (base->-kwd-infos that)]) + (and (equal? (kwd-info-kwd this-kwd-info) + (kwd-info-kwd that-kwd-info)) + (contract-stronger? (kwd-info-ctc that-kwd-info) + (kwd-info-ctc this-kwd-info)))) + (if (base->-rngs this) + (and (base->-rngs that) + (andmap contract-stronger? (base->-rngs this) (base->-rngs that))) + (not (base->-rngs that))) + (not (base->-pre? this)) + (not (base->-pre? that)) + (not (base->-post? this)) + (not (base->-post? that)))) + #:generate ->-generate + #:exercise ->-exercise + #:val-first-projection val-first-proj + #:late-neg-projection late-neg-proj)) (define-struct (-> base->) () #:property diff --git a/racket/collects/racket/contract/private/arrow.rkt b/racket/collects/racket/contract/private/arrow.rkt index 42dd7ee2ee..ba27288f4e 100644 --- a/racket/collects/racket/contract/private/arrow.rkt +++ b/racket/collects/racket/contract/private/arrow.rkt @@ -87,46 +87,46 @@ [(p-app-x ...) (generate-temporaries #'(rngs ...))] [(res-x ...) (generate-temporaries #'(rngs ...))]) #`(let ([rngs-x (coerce-contract 'unconstrained-domain-> rngs)] ...) - (let ([proj-x (contract-projection rngs-x)] ...) + (let ([proj-x (get/build-late-neg-projection rngs-x)] ...) (define (projection wrapper get-ctc) (λ (orig-blame) (define ctc (get-ctc)) (let ([rng-blame (blame-add-range-context orig-blame)]) - (let* ([p-app-x (proj-x rng-blame)] ... - [res-checker (λ (res-x ...) (values/drop (p-app-x res-x) ...))]) - (λ (val) - (check-is-a-procedure orig-blame val) + (let* ([p-app-x (proj-x rng-blame)] ...) + (λ (val neg-party) + (check-is-a-procedure orig-blame neg-party val) + (define (res-checker res-x ...) (values/drop (p-app-x res-x neg-party) ...)) (wrapper val (make-keyword-procedure (λ (kwds kwd-vals . args) (with-continuation-mark - contract-continuation-mark-key orig-blame - #,(check-tail-contract - #'(p-app-x ...) - (list #'res-checker) - (λ (s) #`(apply values #,@s kwd-vals args))))) + contract-continuation-mark-key (cons orig-blame neg-party) + #,(check-tail-contract + #'(p-app-x ...) + (list #'res-checker) + (λ (s) #`(apply values #,@s kwd-vals args))))) (λ args (with-continuation-mark - contract-continuation-mark-key orig-blame - #,(check-tail-contract - #'(p-app-x ...) - (list #'res-checker) - (λ (s) #`(apply values #,@s args)))))) + contract-continuation-mark-key (cons orig-blame neg-party) + #,(check-tail-contract + #'(p-app-x ...) + (list #'res-checker) + (λ (s) #`(apply values #,@s args)))))) impersonator-prop:contracted ctc impersonator-prop:application-mark (cons contract-key (list p-app-x ...)))))))) (make-unconstrained-domain-> (list rngs-x ...) projection))))])) -(define (check-is-a-procedure orig-blame val) +(define (check-is-a-procedure orig-blame neg-party val) (unless (procedure? val) - (raise-blame-error orig-blame + (raise-blame-error orig-blame #:missing-party neg-party val '(expected: "a procedure" given: "~v") val))) -(define (make-unconstrained-domain-> ctcs projection) +(define (make-unconstrained-domain-> ctcs late-neg-projection) (define name (apply build-compound-type-name 'unconstrained-domain-> (map contract-name ctcs))) @@ -134,11 +134,11 @@ (if (andmap chaperone-contract? ctcs) (make-chaperone-contract #:name name - #:projection (projection chaperone-procedure (λ () ctc)) + #:late-neg-projection (late-neg-projection chaperone-procedure (λ () ctc)) #:first-order procedure?) (make-contract #:name name - #:projection (projection impersonate-procedure (λ () ctc)) + #:late-neg-projection (late-neg-projection impersonate-procedure (λ () ctc)) #:first-order procedure?))) ctc) @@ -201,18 +201,25 @@ (loop (cdr accepted) req-kwds (cdr opt-kwds))] [else #f]))]))) -(define-for-syntax (create-chaperone blame val pre post this-args doms opt-doms dom-rest req-kwds opt-kwds rngs) +(define-for-syntax (create-chaperone blame neg-party val pre post this-args + doms opt-doms dom-rest req-kwds opt-kwds + rngs) (with-syntax ([blame blame] + [neg-party neg-party] [val val]) (with-syntax ([(pre ...) (if pre (list #`(unless #,pre - (raise-blame-error (blame-swap blame) val "#:pre condition"))) + (raise-blame-error + (blame-swap blame) #:missing-party neg-party + val "#:pre condition"))) null)] [(post ...) (if post (list #`(unless #,post - (raise-blame-error blame val "#:post condition"))) + (raise-blame-error + blame #:missing-party neg-party + val "#:post condition"))) null)]) (with-syntax ([(this-param ...) this-args] [(dom-ctc ...) doms] @@ -240,12 +247,12 @@ (if (and (pair? rngs) (null? (cdr rngs))) (with-syntax ([proj (car (syntax->list #'(rng-ctc ...)))] [name (car (syntax->list #'(rng-x ...)))]) - #'(proj name)) - #'(values/drop (rng-ctc rng-x) ...))]) + #'(proj name neg-party)) + #'(values/drop (rng-ctc rng-x neg-party) ...))]) #'(case-lambda [(rng-x ...) (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key (cons blame neg-party) (let () post ... rng-results))] @@ -267,13 +274,15 @@ [else #'(this-param ... dom-x ... [opt-dom-x unspecified-dom] ...)])] [opt+rest-uses - (for/fold ([i (if dom-rest #'(rest-ctc rest-x) #'null)]) - ([o (in-list (reverse (syntax->list #'([opt-dom-ctc opt-dom-x] ...))))]) + (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) ...))))]) (let* ([l (syntax->list o)] [c (car l)] [x (cadr l)]) #`(let ([r #,i]) - (if (eq? unspecified-dom #,x) r (cons (#,c #,x) r)))))] + (if (eq? unspecified-dom #,x) r (cons (#,c #,x neg-party) r)))))] [(kwd-param ...) (apply append (map list @@ -282,9 +291,12 @@ [kwd-stx (let* ([req-stxs (map (λ (s) (λ (r) #`(cons #,s #,r))) - (syntax->list #'((req-kwd-ctc req-kwd-x) ...)))] + (syntax->list #'((req-kwd-ctc req-kwd-x neg-party) ...)))] [opt-stxs - (map (λ (x c) (λ (r) #`(let ([r #,r]) (if (eq? unspecified-dom #,x) r (cons (#,c #,x) r))))) + (map (λ (x c) (λ (r) #`(let ([r #,r]) + (if (eq? unspecified-dom #,x) + r + (cons (#,c #,x neg-party) r))))) (syntax->list #'(opt-kwd-x ...)) (syntax->list #'(opt-kwd-ctc ...)))] [reqs (map cons req-keywords req-stxs)] @@ -301,16 +313,23 @@ [basic-return (let ([inner-stx-gen (if need-apply-values? - (λ (s) #`(apply values #,@s this-param ... (dom-ctc dom-x) ... opt+rest-uses)) - (λ (s) #`(values/drop #,@s this-param ... (dom-ctc dom-x) ...)))]) + (λ (s) #`(apply values #,@s this-param ... + (dom-ctc dom-x neg-party) ... opt+rest-uses)) + (λ (s) #`(values/drop #,@s this-param ... + (dom-ctc dom-x neg-party) ...)))]) (if no-rng-checking? (inner-stx-gen #'()) - (check-tail-contract #'(rng-ctc ...) #'(rng-checker-name ...) inner-stx-gen)))] + (check-tail-contract #'(rng-ctc ...) + #'(rng-checker-name ...) + inner-stx-gen)))] [kwd-return (let* ([inner-stx-gen (if need-apply-values? - (λ (s k) #`(apply values #,@s #,@k this-param ... (dom-ctc dom-x) ... opt+rest-uses)) - (λ (s k) #`(values/drop #,@s #,@k this-param ... (dom-ctc dom-x) ...)))] + (λ (s k) #`(apply values #,@s #,@k this-param ... + (dom-ctc dom-x neg-party) ... + opt+rest-uses)) + (λ (s k) #`(values/drop #,@s #,@k this-param ... + (dom-ctc dom-x neg-party) ...)))] [outer-stx-gen (if (null? req-keywords) (λ (s) @@ -335,13 +354,13 @@ ;; noticeable in my measurements so far. ;; - stamourv (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key (cons blame neg-party) (let () pre ... basic-return)))] [kwd-lambda-name (gen-id 'kwd-lambda)] [kwd-lambda #`(λ kwd-lam-params (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key (cons blame neg-party) (let () pre ... kwd-return)))]) (with-syntax ([(basic-checker-name) (generate-temporaries '(basic-checker))]) @@ -349,7 +368,7 @@ [(and (null? req-keywords) (null? opt-keywords)) #`(let-values ([(rng-checker-name ...) (values/drop rng-checker ...)]) (let ([basic-lambda-name basic-lambda]) - (arity-checking-wrapper val blame + (arity-checking-wrapper val blame neg-party basic-lambda-name void #,min-method-arity @@ -361,7 +380,7 @@ [(pair? req-keywords) #`(let-values ([(rng-checker-name ...) (values/drop rng-checker ...)]) (let ([kwd-lambda-name kwd-lambda]) - (arity-checking-wrapper val blame + (arity-checking-wrapper val blame neg-party void kwd-lambda-name #,min-method-arity @@ -374,7 +393,7 @@ #`(let-values ([(rng-checker-name ...) (values/drop rng-checker ...)]) (let ([basic-lambda-name basic-lambda] [kwd-lambda-name kwd-lambda]) - (arity-checking-wrapper val blame + (arity-checking-wrapper val blame neg-party basic-lambda-name kwd-lambda-name #,min-method-arity @@ -385,7 +404,7 @@ '(opt-kwd ...))))]))))))))))) ;; should we pass both the basic-lambda and the kwd-lambda? -(define (arity-checking-wrapper val blame basic-lambda kwd-lambda +(define (arity-checking-wrapper val blame neg-party basic-lambda kwd-lambda min-method-arity max-method-arity min-arity max-arity req-kwd opt-kwd) ;; should not build this unless we are in the 'else' case (and maybe not at all) @@ -404,27 +423,28 @@ (define kwd-checker (if (and (null? req-kwd) (null? opt-kwd)) (λ (kwds kwd-args . args) - (raise-no-keywords-arg blame val kwds)) + (raise-no-keywords-arg blame #:missing-party neg-party val kwds)) (λ (kwds kwd-args . args) (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key (cons blame neg-party) (let () (define args-len (length args)) (unless (valid-number-of-args? args) (raise-wrong-number-of-args-error - blame val + blame #:missing-party neg-party 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) (for ([req-kwd (in-list req-kwd)]) (unless (memq req-kwd kwds) - (raise-blame-error (blame-swap blame) val + (raise-blame-error (blame-swap blame) #:missing-party neg-party + val '(expected "keyword argument ~a") req-kwd))) (for ([k (in-list kwds)]) (unless (memq k all-kwds) - (raise-blame-error (blame-swap blame) val + (raise-blame-error (blame-swap blame) #:missing-party neg-party val '(received: "unexpected keyword argument ~a") k))) (keyword-apply kwd-lambda kwds kwd-args args)))))) @@ -432,16 +452,16 @@ (if (null? req-kwd) (λ args (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key (cons blame neg-party) (let () (unless (valid-number-of-args? args) (define args-len (length args)) (raise-wrong-number-of-args-error - blame val + blame #:missing-party neg-party val args-len max-arity min-method-arity max-method-arity)) (apply basic-lambda args)))) (λ args - (raise-blame-error (blame-swap blame) val + (raise-blame-error (blame-swap blame) #:missing-party neg-party val "expected required keyword ~a" (car req-kwd))))) (if (or (not va) (pair? vr) (pair? va)) @@ -509,15 +529,15 @@ mtd? mctc? func)) -(define ((->-proj wrapper) ctc) - (let* ([doms-proj (map contract-projection +(define ((late-neg-->-proj wrapper) ctc) + (let* ([doms-proj (map get/build-late-neg-projection (if (base->-dom-rest/c ctc) (append (base->-doms/c ctc) (list (base->-dom-rest/c ctc))) (base->-doms/c ctc)))] - [doms-optional-proj (map contract-projection (base->-optional-doms/c ctc))] - [rngs-proj (map contract-projection (base->-rngs/c ctc))] - [mandatory-kwds-proj (map contract-projection (base->-mandatory-kwds/c ctc))] - [optional-kwds-proj (map contract-projection (base->-optional-kwds/c ctc))] + [doms-optional-proj (map get/build-late-neg-projection (base->-optional-doms/c ctc))] + [rngs-proj (map get/build-late-neg-projection (base->-rngs/c ctc))] + [mandatory-kwds-proj (map get/build-late-neg-projection (base->-mandatory-kwds/c ctc))] + [optional-kwds-proj (map get/build-late-neg-projection (base->-optional-kwds/c ctc))] [mandatory-keywords (base->-mandatory-kwds ctc)] [optional-keywords (base->-optional-kwds ctc)] [func (base->-func ctc)] @@ -529,11 +549,10 @@ [mtd? (base->-mtd? ctc)]) (λ (orig-blame) (define rng-blame (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)] [n (in-naturals 1)]) - (dom (blame-add-context orig-blame + (dom (blame-add-context orig-blame (if (and has-rest? (n . > . dom-length)) "the rest argument of" @@ -563,11 +582,13 @@ (define the-args (append partial-doms partial-optional-doms partial-mandatory-kwds partial-optional-kwds partial-ranges)) - (λ (val) + (λ (val neg-party) (if has-rest? - (check-procedure/more val mtd? dom-length mandatory-keywords optional-keywords orig-blame) - (check-procedure val mtd? dom-length optionals-length mandatory-keywords optional-keywords orig-blame)) - (define chap/imp-func (apply func orig-blame val the-args)) + (check-procedure/more val mtd? dom-length mandatory-keywords optional-keywords + orig-blame neg-party) + (check-procedure val mtd? dom-length optionals-length mandatory-keywords optional-keywords + orig-blame neg-party)) + (define chap/imp-func (apply func orig-blame neg-party val the-args)) (if post (wrapper val @@ -632,18 +653,17 @@ (define-struct (chaperone-> base->) () #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract - (parameterize ([skip-projection-wrapper? #t]) - (build-chaperone-contract-property - #:projection (->-proj chaperone-procedure) - #:name ->-name - #:first-order ->-first-order - #:stronger ->-stronger?))) + (build-chaperone-contract-property + #:late-neg-projection (late-neg-->-proj chaperone-procedure) + #:name ->-name + #:first-order ->-first-order + #:stronger ->-stronger?)) (define-struct (impersonator-> base->) () #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property - #:projection (->-proj impersonate-procedure) + #:late-neg-projection (late-neg-->-proj impersonate-procedure) #:name ->-name #:first-order ->-first-order #:stronger ->-stronger?)) @@ -796,9 +816,9 @@ (with-syntax ([mtd? (and (syntax-parameter-value #'making-a-method) #t)] [->m-ctc? (and (syntax-parameter-value #'method-contract?) #t)] [outer-lambda - #`(lambda (blame val dom-names ... kwd-names ... rng-names ...) + #`(lambda (blame neg-party val dom-names ... kwd-names ... rng-names ...) #,(create-chaperone - #'blame #'val #f #f + #'blame #'neg-party #'val #f #f (syntax->list #'(this-params ...)) (syntax->list #'(dom-names ...)) null #f (map list (syntax->list #'(kwds ...)) @@ -977,7 +997,7 @@ #''()) #,(if rng-ctc #f #t) mtd? ->m-ctc? - (λ (blame f + (λ (blame neg-party f mandatory-dom-proj ... #,@(if rest-ctc #'(rest-proj) @@ -987,7 +1007,7 @@ optional-dom-kwd-proj ... rng-proj ...) #,(create-chaperone - #'blame #'f pre post + #'blame #'neg-party #'f pre post (syntax->list #'(this-parameter ...)) (syntax->list #'(mandatory-dom-proj ...)) (syntax->list #'(optional-dom-proj ...)) @@ -1249,7 +1269,7 @@ (syntax-local-infer-name stx) #`(λ args (apply f args)))))))))))))])) -(define ((->d-proj wrap-procedure) ->d-stct) +(define ((late-neg-->d-proj wrap-procedure) ->d-stct) (let* ([opt-count (length (base-->d-optional-dom-ctcs ->d-stct))] [mandatory-count (+ (length (base-->d-mandatory-dom-ctcs ->d-stct)) (if (base-->d-mtd? ->d-stct) 1 0))] @@ -1266,28 +1286,32 @@ [else (cons (+ mandatory-count i) (loop (+ i 1)))]))])]) (λ (blame) - (λ (val) - (if (base-->d-rest-ctc ->d-stct) - (check-procedure/more val - (base-->d-mtd? ->d-stct) - (length (base-->d-mandatory-dom-ctcs ->d-stct)) ;dom-length - (base-->d-mandatory-keywords ->d-stct) - (base-->d-optional-keywords ->d-stct) - blame) - (check-procedure val - (base-->d-mtd? ->d-stct) - (length (base-->d-mandatory-dom-ctcs ->d-stct)) ;dom-length - (length (base-->d-optional-dom-ctcs ->d-stct)) ; optionals-length - (base-->d-mandatory-keywords ->d-stct) - (base-->d-optional-keywords ->d-stct) - blame)) - (wrap-procedure - val - (make-keyword-procedure - (λ (kwd-args kwd-arg-vals . raw-orig-args) - (with-continuation-mark - contract-continuation-mark-key blame - (let* ([orig-args (if (base-->d-mtd? ->d-stct) + (define dom-blame (blame-add-context blame "the domain of" #:swap? #t)) + (define rng-blame (blame-add-range-context blame)) + (λ (val neg-party) + (if (base-->d-rest-ctc ->d-stct) + (check-procedure/more val + (base-->d-mtd? ->d-stct) + (length (base-->d-mandatory-dom-ctcs ->d-stct)) ;dom-length + (base-->d-mandatory-keywords ->d-stct) + (base-->d-optional-keywords ->d-stct) + blame + neg-party) + (check-procedure val + (base-->d-mtd? ->d-stct) + (length (base-->d-mandatory-dom-ctcs ->d-stct)) ;dom-length + (length (base-->d-optional-dom-ctcs ->d-stct)) ; optionals-length + (base-->d-mandatory-keywords ->d-stct) + (base-->d-optional-keywords ->d-stct) + blame + neg-party)) + (wrap-procedure + val + (make-keyword-procedure + (λ (kwd-args kwd-arg-vals . raw-orig-args) + (with-continuation-mark + contract-continuation-mark-key (cons blame neg-party) + (let* ([orig-args (if (base-->d-mtd? ->d-stct) (cdr raw-orig-args) raw-orig-args)] [this (and (base-->d-mtd? ->d-stct) (car raw-orig-args))] @@ -1296,7 +1320,7 @@ (base-->d-keywords ->d-stct) kwd-args kwd-arg-vals)]) (when (base-->d-pre-cond ->d-stct) (unless (apply (base-->d-pre-cond ->d-stct) dep-pre-args) - (raise-blame-error (blame-swap blame) + (raise-blame-error (blame-swap blame) #:missing-party neg-party val "#:pre violation~a" (build-values-string ", argument" dep-pre-args)))) @@ -1316,44 +1340,44 @@ (if rng (list (λ orig-results (with-continuation-mark - contract-continuation-mark-key blame - (let* ([range-count (length rng)] - [post-args (append orig-results raw-orig-args)] - [post-non-kwd-arg-count (+ non-kwd-ctc-count range-count)] - [dep-post-args (build-dep-ctc-args post-non-kwd-arg-count - post-args (base-->d-rest-ctc ->d-stct) - (base-->d-keywords ->d-stct) kwd-args kwd-arg-vals)]) - (when (base-->d-post-cond ->d-stct) - (unless (apply (base-->d-post-cond ->d-stct) dep-post-args) - (raise-blame-error blame + contract-continuation-mark-key (cons blame neg-party) + (let* ([range-count (length rng)] + [post-args (append orig-results raw-orig-args)] + [post-non-kwd-arg-count (+ non-kwd-ctc-count range-count)] + [dep-post-args (build-dep-ctc-args post-non-kwd-arg-count + post-args (base-->d-rest-ctc ->d-stct) + (base-->d-keywords ->d-stct) kwd-args kwd-arg-vals)]) + (when (base-->d-post-cond ->d-stct) + (unless (apply (base-->d-post-cond ->d-stct) dep-post-args) + (raise-blame-error blame #:missing-party neg-party + val + "#:post violation~a~a" + (build-values-string ", argument" dep-pre-args) + (build-values-string (if (null? dep-pre-args) + ", result" + "\n result") + orig-results)))) + + (unless (= range-count (length orig-results)) + (raise-blame-error blame #:missing-party neg-party val - "#:post violation~a~a" - (build-values-string ", argument" dep-pre-args) - (build-values-string (if (null? dep-pre-args) - ", result" - "\n result") - orig-results)))) - - (unless (= range-count (length orig-results)) - (raise-blame-error blame - val - "expected ~a results, got ~a" - range-count - (length orig-results))) - (apply - values - (let loop ([results orig-results] - [result-contracts rng]) - (cond - [(null? result-contracts) '()] - [else - (cons - (invoke-dep-ctc (car result-contracts) - (if rng-underscore? #f dep-post-args) - (car results) - blame - #f) - (loop (cdr results) (cdr result-contracts)))]))))))) + "expected ~a results, got ~a" + range-count + (length orig-results))) + (apply + values + (let loop ([results orig-results] + [result-contracts rng]) + (cond + [(null? result-contracts) '()] + [else + (cons + (invoke-dep-ctc (car result-contracts) + (if rng-underscore? #f dep-post-args) + (car results) + rng-blame + neg-party) + (loop (cdr results) (cdr result-contracts)))]))))))) null)) ;; contracted keyword arguments @@ -1365,9 +1389,16 @@ [(or (null? building-kwd-args) (null? all-kwds)) '()] [else (if (eq? (car all-kwds) (car building-kwd-args)) - (cons (invoke-dep-ctc (car kwd-ctcs) dep-pre-args (car building-kwd-arg-vals) blame #t) - (loop (cdr all-kwds) (cdr kwd-ctcs) (cdr building-kwd-args) (cdr building-kwd-arg-vals))) - (loop (cdr all-kwds) (cdr kwd-ctcs) building-kwd-args building-kwd-arg-vals))]))]) + (cons (invoke-dep-ctc (car kwd-ctcs) + dep-pre-args + (car building-kwd-arg-vals) + dom-blame + neg-party) + (loop (cdr all-kwds) (cdr kwd-ctcs) + (cdr building-kwd-args) + (cdr building-kwd-arg-vals))) + (loop (cdr all-kwds) (cdr kwd-ctcs) + building-kwd-args building-kwd-arg-vals))]))]) (if (null? kwd-res) null (list kwd-res))) @@ -1383,20 +1414,24 @@ (cond [(null? args) (if (base-->d-rest-ctc ->d-stct) - (invoke-dep-ctc (base-->d-rest-ctc ->d-stct) dep-pre-args '() blame #t) + (invoke-dep-ctc (base-->d-rest-ctc ->d-stct) dep-pre-args '() + dom-blame neg-party) '())] [(null? non-kwd-ctcs) (if (base-->d-rest-ctc ->d-stct) - (invoke-dep-ctc (base-->d-rest-ctc ->d-stct) dep-pre-args args blame #t) + (invoke-dep-ctc (base-->d-rest-ctc ->d-stct) + dep-pre-args args dom-blame neg-party) ;; ran out of arguments, but don't have a rest parameter. ;; procedure-reduce-arity (or whatever the new thing is ;; going to be called) should ensure this doesn't happen. (error 'shouldnt\ happen))] - [else (cons (invoke-dep-ctc (car non-kwd-ctcs) dep-pre-args (car args) blame #t) + [else (cons (invoke-dep-ctc (car non-kwd-ctcs) + dep-pre-args (car args) + dom-blame neg-party) (loop (cdr args) (cdr non-kwd-ctcs)))])))))))) - impersonator-prop:contracted ->d-stct))))) + impersonator-prop:contracted ->d-stct))))) (define (build-values-string desc dep-pre-args) (cond @@ -1413,15 +1448,14 @@ (loop (cdr lst)))])))])) ;; invoke-dep-ctc : (...? -> ctc) (or/c #f (listof tst)) val pos-blame neg-blame src-info orig-src -> tst -(define (invoke-dep-ctc dep-ctc dep-args val blame dom?) +(define (invoke-dep-ctc dep-ctc dep-args val blame neg-party) (let ([ctc (coerce-contract '->d (if dep-args (apply dep-ctc dep-args) dep-ctc))]) - (((contract-projection ctc) - (if dom? - (blame-add-context blame "the domain of" #:swap? #t) - (blame-add-range-context blame))) - val))) + (((get/build-late-neg-projection ctc) + blame) + val + neg-party))) ;; build-dep-ctc-args : number (listof any) boolean (listof keyword) (listof keyword) (listof any) (define (build-dep-ctc-args non-kwd-ctc-count args rest-arg? all-kwds supplied-kwds supplied-args) @@ -1529,8 +1563,8 @@ [optional-kwds (base-->d-optional-keywords ctc)]) (λ (val) (if (base-->d-rest-ctc ctc) - (check-procedure/more val mtd? dom-length mandatory-kwds optional-kwds #f) - (check-procedure val mtd? dom-length optionals mandatory-kwds optional-kwds #f))))) + (check-procedure/more val mtd? dom-length mandatory-kwds optional-kwds #f #f) + (check-procedure val mtd? dom-length optionals mandatory-kwds optional-kwds #f #f))))) (define (->d-stronger? this that) (eq? this that)) ;; in the struct type descriptions "d???" refers to the arguments (domain) of the function that @@ -1564,7 +1598,7 @@ #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property - #:projection (->d-proj impersonate-procedure) + #:late-neg-projection (late-neg-->d-proj impersonate-procedure) #:name ->d-name #:first-order ->d-first-order #:stronger ->d-stronger?)) @@ -1637,7 +1671,8 @@ ;; check-procedure : ... (or/c #f blame) -> (or/c boolean? void?) ;; if blame is #f, then just return a boolean indicating that this matched ;; (for use in arity checking) -(define (check-procedure val mtd? dom-length optionals mandatory-kwds optional-keywords blame) +(define (check-procedure val mtd? dom-length optionals mandatory-kwds optional-keywords + blame neg-party) (define passes? (and (procedure? val) (procedure-arity-includes?/optionals val (if mtd? (+ dom-length 1) dom-length) optionals) @@ -1646,7 +1681,7 @@ [blame (unless passes? (raise-blame-error - blame + blame #:missing-party neg-party val '(expected " a ~a that accepts ~a~a~a argument~a~a~a" given: "~e") (if mtd? "method" "procedure") @@ -1712,7 +1747,7 @@ ;; check-procedure/more : ... (or/c #f blame) -> (or/c boolean? void?) ;; if blame is #f, then just return a boolean indicating that this matched ;; (for use in arity checking) -(define (check-procedure/more val mtd? dom-length mandatory-kwds optional-kwds blame) +(define (check-procedure/more val mtd? dom-length mandatory-kwds optional-kwds blame neg-party) (define passes? (and (procedure? val) (procedure-accepts-and-more? val (if mtd? (+ dom-length 1) dom-length)) diff --git a/racket/collects/racket/contract/private/case-arrow.rkt b/racket/collects/racket/contract/private/case-arrow.rkt index 1214f2d1ff..0097eb0305 100644 --- a/racket/collects/racket/contract/private/case-arrow.rkt +++ b/racket/collects/racket/contract/private/case-arrow.rkt @@ -74,9 +74,9 @@ [rng (let ([rng-checkers (list #`(case-lambda - [(rng-id ...) (values/drop (rng-proj-x rng-id) ...)] + [(rng-id ...) (values/drop (rng-proj-x rng-id neg-party) ...)] [args - (bad-number-of-results blame f + (bad-number-of-results blame #:missing-party neg-party f #,(length (syntax->list #'(rng-id ...))) args #,n)]))] @@ -85,19 +85,20 @@ (check-tail-contract #'(rng-proj-x ...) rng-checkers (λ (rng-checks) #`(apply values #,@rng-checks this-parameter ... - (dom-proj-x dom-formals) ... - (rst-proj-x rst-formal)))) - (check-tail-contract #'(rng-proj-x ...) rng-checkers - (λ (rng-checks) - #`(values/drop #,@rng-checks this-parameter ... - (dom-proj-x dom-formals) ...)))))] + (dom-proj-x dom-formals neg-party) ... + (rst-proj-x rst-formal neg-party)))) + (check-tail-contract + #'(rng-proj-x ...) rng-checkers + (λ (rng-checks) + #`(values/drop #,@rng-checks this-parameter ... + (dom-proj-x dom-formals neg-party) ...)))))] [rst #`(apply values this-parameter ... - (dom-proj-x dom-formals) ... - (rst-proj-x rst-formal))] + (dom-proj-x dom-formals neg-party) ... + (rst-proj-x rst-formal neg-party))] [else #`(values/drop this-parameter ... - (dom-proj-x dom-formals) ...)])))))) + (dom-proj-x dom-formals neg-party) ...)])))))) (define-syntax (case-> stx) (syntax-case stx () @@ -130,7 +131,7 @@ ctc #,@(apply append (map syntax->list (syntax->list #'((dom-proj-x ...) ...)))) #,@(apply append (map syntax->list (syntax->list #'((rng-proj-x ...) ...))))) - (λ (f) + (λ (f neg-party) (put-it-together #,(let ([case-lam (syntax/loc stx (case-lambda [formals body] ...))]) @@ -138,14 +139,14 @@ #`(let ([#,name #,case-lam]) #,name) case-lam)) (list (list rng-proj-x ...) ...) - f blame wrapper ctc + f blame neg-party wrapper ctc chk #,(and (syntax-parameter-value #'making-a-method) #t))))))))])) -(define (put-it-together the-case-lam range-projections f blame wrapper ctc chk mtd?) +(define (put-it-together the-case-lam range-projections f blame neg-party wrapper ctc chk mtd?) (chk f mtd?) (define checker (make-keyword-procedure - (raise-no-keywords-error f blame) + (raise-no-keywords-error f blame neg-party) (λ args (with-continuation-mark contract-continuation-mark-key blame (apply the-case-lam args))))) @@ -155,17 +156,18 @@ f checker impersonator-prop:contracted ctc - impersonator-prop:blame blame + impersonator-prop:blame (blame-add-missing-party blame neg-party) impersonator-prop:application-mark (cons contract-key same-rngs)) (wrapper f checker impersonator-prop:contracted ctc - impersonator-prop:blame blame))) + impersonator-prop:blame (blame-add-missing-party blame neg-party)))) -(define (raise-no-keywords-error f blame) +(define (raise-no-keywords-error f blame neg-party) (λ (kwds kwd-args . args) - (raise-blame-error blame f "expected no keywords, got keyword ~a" (car kwds)))) + (raise-blame-error blame f #:missing-party neg-party + "expected no keywords, got keyword ~a" (car kwds)))) ;; dom-ctcs : (listof (listof contract)) ;; rst-ctcs : (listof contract) @@ -180,8 +182,7 @@ (define (case->-proj wrapper) (λ (ctc) (define dom-ctcs+case-nums (get-case->-dom-ctcs+case-nums ctc)) - (define rng-ctcs (map contract-projection - (get-case->-rng-ctcs ctc))) + (define rng-late-neg-ctcs (map contract-late-neg-projection (get-case->-rng-ctcs ctc))) (define rst-ctcs (base-case->-rst-ctcs ctc)) (define specs (base-case->-specs ctc)) (λ (blame) @@ -210,7 +211,7 @@ (apply p args)))]) (set! memo (cons (cons f new) memo)) new)))) - rng-ctcs))) + rng-late-neg-ctcs))) (define (chk val mtd?) (cond [(null? specs) @@ -220,8 +221,8 @@ (for-each (λ (dom-length has-rest?) (if has-rest? - (check-procedure/more val mtd? dom-length '() '() blame) - (check-procedure val mtd? dom-length 0 '() '() blame))) + (check-procedure/more val mtd? dom-length '() '() blame #f) + (check-procedure val mtd? dom-length 0 '() '() blame #f))) specs rst-ctcs)])) (apply (base-case->-wrapper ctc) chk @@ -260,7 +261,7 @@ #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract (build-chaperone-contract-property - #:projection (case->-proj chaperone-procedure) + #:late-neg-projection (case->-proj chaperone-procedure) #:name case->-name #:first-order case->-first-order #:stronger case->-stronger?)) @@ -269,7 +270,7 @@ #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property - #:projection (case->-proj impersonate-procedure) + #:late-neg-projection (case->-proj impersonate-procedure) #:name case->-name #:first-order case->-first-order #:stronger case->-stronger?)) @@ -290,11 +291,11 @@ [rst (in-list (base-case->-rst-ctcs ctc))] [i (in-naturals)]) (define dom+case-nums - (map (λ (dom) (cons i (contract-projection dom))) doms)) + (map (λ (dom) (cons i (contract-late-neg-projection dom))) doms)) (append acc (if rst (append dom+case-nums - (list (cons i (contract-projection rst)))) + (list (cons i (contract-late-neg-projection rst)))) dom+case-nums)))) (define (get-case->-rng-ctcs ctc) diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index f01fd1c6b2..0e48a68791 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -57,6 +57,7 @@ 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 + warn-about-val-first? contract-name n->th @@ -276,14 +277,13 @@ (define-struct (chaperone-and/c base-and/c) () #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract - (parameterize ([skip-projection-wrapper? #t]) - (build-chaperone-contract-property - #:projection and-proj - #:late-neg-projection late-neg-and-proj - #:name and-name - #:first-order and-first-order - #:stronger and-stronger? - #:generate and/c-generate?))) + (build-chaperone-contract-property + #:projection and-proj + #:late-neg-projection late-neg-and-proj + #:name and-name + #:first-order and-first-order + #:stronger and-stronger? + #:generate and/c-generate?)) (define-struct (impersonator-and/c base-and/c) () #:property prop:custom-write custom-write-property-proc #:property prop:contract @@ -449,20 +449,21 @@ (build-flat-contract-property #:name (λ (c) `(,name ,(-ctc-x c))) #:first-order (λ (ctc) (define x (-ctc-x ctc)) (λ (y) (and (real? y) ( y x)))) - #:projection (λ (ctc) - (define x (-ctc-x ctc)) - (λ (blame) - (λ (val) - (if (and (real? val) ( val x)) - val - (raise-blame-error - blame val - '(expected: - "a number strictly ~a than ~v" - given: "~v") - less/greater - x - val))))) + #:late-neg-projection + (λ (ctc) + (define x (-ctc-x ctc)) + (λ (blame) + (λ (val neg-party) + (if (and (real? val) ( val x)) + val + (raise-blame-error + blame val #:missing-party neg-party + '(expected: + "a number strictly ~a than ~v" + given: "~v") + less/greater + x + val))))) #:generate (λ (ctc) (define x (-ctc-x ctc)) @@ -968,15 +969,14 @@ (define-struct (chaperone-cons/c the-cons/c) () #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract - (parameterize ([skip-projection-wrapper? #t]) - (build-chaperone-contract-property - #: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 - #:stronger cons/c-stronger? - #:generate cons/c-generate - #:list-contract? cons/c-list-contract?))) + (build-chaperone-contract-property + #: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 + #:stronger cons/c-stronger? + #:generate cons/c-generate + #:list-contract? cons/c-list-contract?)) (define-struct (impersonator-cons/c the-cons/c) () #:property prop:custom-write custom-write-property-proc #:property prop:contract @@ -1355,16 +1355,15 @@ (struct chaperone-list/c generic-list/c () #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract - (parameterize ([skip-projection-wrapper? #t]) - (build-chaperone-contract-property - #:name list/c-name-proc - #:first-order list/c-first-order - #:generate list/c-generate - #:exercise list/c-exercise - #:stronger list/c-stronger - #:projection list/c-chaperone/other-projection - #:late-neg-projection list/c-chaperone/other-late-neg-projection - #:list-contract? (λ (c) #t)))) + (build-chaperone-contract-property + #:name list/c-name-proc + #:first-order list/c-first-order + #:generate list/c-generate + #:exercise list/c-exercise + #:stronger list/c-stronger + #:projection list/c-chaperone/other-projection + #:late-neg-projection list/c-chaperone/other-late-neg-projection + #:list-contract? (λ (c) #t))) (struct higher-order-list/c generic-list/c () #:property prop:custom-write custom-write-property-proc @@ -1913,10 +1912,10 @@ ((proj blame) val)))) (define (generator evt) (values evt (checker evt))) - (λ (val) + (λ (val neg-party) (unless (contract-first-order-passes? evt-ctc val) (raise-blame-error - blame val + blame val #:missing-party neg-party '(expected: "~s" given: "~e") (contract-name evt-ctc) val)) @@ -1944,7 +1943,7 @@ (define-struct chaperone-evt/c (ctcs) #:property prop:chaperone-contract (build-chaperone-contract-property - #:projection evt/c-proj + #:late-neg-projection evt/c-proj #:first-order evt/c-first-order #:stronger evt/c-stronger? #:name evt/c-name)) @@ -2063,33 +2062,95 @@ (define (contract? x) (and (coerce-contract/f x) #t)) (define (contract-projection ctc) - (contract-struct-projection + (get/build-projection (coerce-contract 'contract-projection ctc))) (define (contract-val-first-projection ctc) - (contract-struct-val-first-projection + (get/build-val-first-projection (coerce-contract 'contract-projection ctc))) (define (contract-late-neg-projection ctc) - (contract-struct-late-neg-projection + (get/build-late-neg-projection (coerce-contract 'contract-projection ctc))) -(define (get/build-val-first-projection ctc) - (or (contract-struct-val-first-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 "val-first: ~s" (contract-name ctc)))))))) - +(define-logger racket/contract) (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)))))))) + (cond + [(contract-struct-late-neg-projection ctc) => values] + [else + (log-racket/contract-warning "no late-neg-projection for ~s" ctc) + (cond + [(contract-struct-projection ctc) + => + (λ (projection) + (projection->late-neg-projection projection))] + [(contract-struct-val-first-projection ctc) + => + (λ (val-first-projection) + (val-first-projection->late-neg-projection val-first-projection))] + [else + (first-order->late-neg-projection (contract-struct-first-order ctc) + (contract-struct-name ctc))])])) + +(define (projection->late-neg-projection proj) + (λ (b) + (λ (x neg-party) + ((proj (blame-add-missing-party b neg-party)) x)))) +(define (val-first-projection->late-neg-projection vf-proj) + (λ (b) + (define vf-val-accepter (vf-proj b)) + (λ (x neg-party) + ((vf-val-accepter x) neg-party)))) +(define (first-order->late-neg-projection p? name) + (λ (b) + (λ (x neg-party) + (if (p? x) + x + (raise-blame-error + b x #:missing-party neg-party + '(expected: "~a" given: "~e") + name + x))))) + +(define warn-about-val-first? (make-parameter #t)) +(define (get/build-val-first-projection ctc) + (cond + [(contract-struct-val-first-projection ctc) => values] + [else + (when (warn-about-val-first?) + (log-racket/contract-warning + "building val-first-projection of contract ~s for~a" + ctc + (build-context))) + (late-neg-projection->val-first-projection + (get/build-late-neg-projection ctc))])) +(define (late-neg-projection->val-first-projection lnp) + (λ (b) + (define val+neg-party-accepter (lnp b)) + (λ (x) + (λ (neg-party) + (val+neg-party-accepter x neg-party))))) + +(define (get/build-projection ctc) + (cond + [(contract-struct-projection ctc) => values] + [else + (log-racket/contract-warning + "building projection of contract ~s for~a" + ctc + (build-context)) + (late-neg-projection->projection + (get/build-late-neg-projection ctc))])) +(define (late-neg-projection->projection lnp) + (λ (b) + (define val+np-acceptor (lnp b)) + (λ (x) + (val+np-acceptor x #f)))) + +(define (build-context) + (apply + string-append + (for/list ([i (in-list (continuation-mark-set->context + (current-continuation-marks)))]) + (format "\n ~s" i)))) (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/opters.rkt b/racket/collects/racket/contract/private/opters.rkt index 0ea739207f..b1ef4d8dbe 100644 --- a/racket/collects/racket/contract/private/opters.rkt +++ b/racket/collects/racket/contract/private/opters.rkt @@ -662,7 +662,7 @@ ((next-dom ...) next-doms) (dom-len (length dom-vars))) (syntax (begin - (check-procedure val #f dom-len 0 '() '() #|keywords|# blame) + (check-procedure val #f dom-len 0 '() '() #|keywords|# blame #f) (chaperone-procedure val (case-lambda @@ -743,7 +743,7 @@ (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) + (check-procedure val #f dom-len 0 '() '() blame #f) (chaperone-procedure val (make-keyword-procedure diff --git a/racket/collects/racket/contract/private/orc.rkt b/racket/collects/racket/contract/private/orc.rkt index d61f49dbb0..2b1e410333 100644 --- a/racket/collects/racket/contract/private/orc.rkt +++ b/racket/collects/racket/contract/private/orc.rkt @@ -217,18 +217,17 @@ (define-struct (chaperone-single-or/c single-or/c) () #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract - (parameterize ([skip-projection-wrapper? #t]) - (build-chaperone-contract-property - #:projection single-or/c-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? - #:generate (λ (ctc) (or/c-generate ctc - (cons (single-or/c-ho-ctc ctc) - (single-or/c-flat-ctcs ctc)))) - #:exercise (λ (ctc) (or/c-exercise (list (single-or/c-ho-ctc ctc)))) - #:list-contract? single-or/c-list-contract?))) + (build-chaperone-contract-property + #:projection single-or/c-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? + #:generate (λ (ctc) (or/c-generate ctc + (cons (single-or/c-ho-ctc ctc) + (single-or/c-flat-ctcs ctc)))) + #:exercise (λ (ctc) (or/c-exercise (list (single-or/c-ho-ctc ctc)))) + #:list-contract? single-or/c-list-contract?)) (define-struct (impersonator-single-or/c single-or/c) () #:property prop:custom-write custom-write-property-proc @@ -376,18 +375,17 @@ (define-struct (chaperone-multi-or/c multi-or/c) () #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract - (parameterize ([skip-projection-wrapper? #t]) - (build-chaperone-contract-property - #:projection multi-or/c-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? - #:generate (λ (ctc) (or/c-generate ctc - (append (multi-or/c-ho-ctcs ctc) - (multi-or/c-flat-ctcs ctc)))) - #:exercise (λ (ctc) (or/c-exercise (multi-or/c-ho-ctcs ctc))) - #:list-contract? mult-or/c-list-contract?))) + (build-chaperone-contract-property + #:projection multi-or/c-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? + #:generate (λ (ctc) (or/c-generate ctc + (append (multi-or/c-ho-ctcs ctc) + (multi-or/c-flat-ctcs ctc)))) + #:exercise (λ (ctc) (or/c-exercise (multi-or/c-ho-ctcs ctc))) + #:list-contract? mult-or/c-list-contract?)) (define-struct (impersonator-multi-or/c multi-or/c) () #:property prop:custom-write custom-write-property-proc @@ -539,16 +537,15 @@ (define-struct (chaperone-first-or/c base-first-or/c) () #:property prop:chaperone-contract - (parameterize ([skip-projection-wrapper? #t]) - (build-chaperone-contract-property - #:projection first-or/c-proj - #:late-neg-projection first-or/c-late-neg-proj - #:name first-or/c-name - #:first-order first-or/c-first-order - #:stronger multi-or/c-stronger? - #:generate (λ (ctc) (or/c-generate ctc (base-first-or/c-ctcs ctc))) - #:exercise (λ (ctc) (or/c-exercise (base-first-or/c-ctcs ctc))) - #:list-contract? first-or/c-list-contract?))) + (build-chaperone-contract-property + #:projection first-or/c-proj + #:late-neg-projection first-or/c-late-neg-proj + #:name first-or/c-name + #:first-order first-or/c-first-order + #:stronger multi-or/c-stronger? + #:generate (λ (ctc) (or/c-generate ctc (base-first-or/c-ctcs ctc))) + #:exercise (λ (ctc) (or/c-exercise (base-first-or/c-ctcs ctc))) + #:list-contract? first-or/c-list-contract?)) (define-struct (impersonator-first-or/c base-first-or/c) () #:property prop:contract (build-contract-property @@ -596,7 +593,7 @@ (λ (ctc) (flat-rec-contract-name ctc)) #:stronger (let ([recur? (make-parameter #t)]) - (λ (this that) + (λ (this that) (cond [(equal? this that) #t] [(recur?) diff --git a/racket/collects/racket/contract/private/prop.rkt b/racket/collects/racket/contract/private/prop.rkt index 3c11ea0c82..5e10eeada1 100644 --- a/racket/collects/racket/contract/private/prop.rkt +++ b/racket/collects/racket/contract/private/prop.rkt @@ -35,8 +35,6 @@ make-chaperone-contract make-flat-contract - skip-projection-wrapper? - prop:opt-chaperone-contract prop:opt-chaperone-contract? prop:opt-chaperone-contract-get-test @@ -97,10 +95,9 @@ first-order)) (define (contract-struct-projection c) - (let* ([prop (contract-struct-property c)] - [get-projection (contract-property-projection prop)] - [projection (get-projection c)]) - projection)) + (define prop (contract-struct-property c)) + (define get-projection (contract-property-projection prop)) + (and get-projection (get-projection c))) (define (contract-struct-val-first-projection c) (define prop (contract-struct-property c)) @@ -111,7 +108,7 @@ (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 + (and get-projection (get-projection c))) (define trail (make-parameter #f)) @@ -256,9 +253,7 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define skip-projection-wrapper? (make-parameter #f)) - -(define ((build-property mk default-name projection-wrapper) +(define ((build-property mk default-name proc-name first-order?) #:name [get-name #f] #:first-order [get-first-order #f] #:projection [get-projection #f] @@ -268,76 +263,41 @@ #:generate [generate (λ (ctc) (λ (fuel) #f))] #:exercise [exercise (λ (ctc) (λ (fuel) (values void '())))] #:list-contract? [list-contract? (λ (c) #f)]) - - ;; this code is here to help me find the combinators that - ;; are still using only #:projection and not #:late-neg-projection - #; - (when (and get-projection - (not get-late-neg-projection)) - (printf "missing late-neg-projection ~s\n" - get-projection)) - - (let* ([get-name (or get-name (lambda (c) default-name))] - [get-first-order (or get-first-order get-any?)] - [get-val-first-projection - (or get-val-first-projection - (and (not get-projection) - (get-val-first-first-order-projection get-name get-first-order)))] - [get-late-neg-projection - (or get-late-neg-projection - (and (not get-projection) - (get-late-neg-first-order-projection get-name get-first-order)))] - [get-projection - (cond - [get-projection - (blame-context-projection-wrapper - (if (skip-projection-wrapper?) - get-projection - (projection-wrapper get-projection)))] - [else (val-first-projection->projection get-val-first-projection - get-name - get-first-order)])] - [stronger (or stronger weakest)]) - - (mk get-name get-first-order - get-projection stronger - generate exercise - get-val-first-projection - get-late-neg-projection - list-contract?))) + (unless (or get-first-order + get-projection + get-val-first-projection + get-late-neg-projection) + (error + proc-name + (string-append + "expected either the #:get-projection, #:val-first-project, or #:late-neg-projection" + " to not be #f, but all three were #f"))) + + (mk (or get-name (λ (c) default-name)) + (or get-first-order get-any?) + get-projection + (or stronger weakest) + generate exercise + get-val-first-projection + (cond + [first-order? + (or get-late-neg-projection + (λ (c) + (late-neg-first-order-projection (get-name c) (get-first-order c))))] + [else get-late-neg-projection]) + list-contract?)) (define build-contract-property (procedure-rename - (build-property make-contract-property 'anonymous-contract values) + (build-property make-contract-property 'anonymous-contract 'build-contract-property #f) 'build-contract-property)) -;; Here we'll force the projection to always return the original value, -;; instead of assuming that the provided projection does so appropriately. -(define (flat-projection-wrapper f) - (λ (c) - (let ([proj (f c)]) - (λ (b) - (let ([p (proj b)]) - (λ (v) (p v) v)))))) - (define build-flat-contract-property (procedure-rename (build-property (compose make-flat-contract-property make-contract-property) - 'anonymous-flat-contract - flat-projection-wrapper) + 'anonymous-flat-contract 'build-flat-contract-property #t) 'build-flat-contract-property)) -(define (chaperone-projection-wrapper f) - (λ (c) - (let ([proj (f c)]) - (λ (b) - (let ([p (proj b)]) - (λ (v) - (let ([v* (p v)]) - (unless (chaperone-of? v* v) - (error 'prop:chaperone-contract (format "expected a chaperone of ~v, got ~v" v v*))) - v*))))))) - (define (blame-context-projection-wrapper proj) (λ (ctc) (define c-proj (proj ctc)) @@ -347,8 +307,7 @@ (define build-chaperone-contract-property (procedure-rename (build-property (compose make-chaperone-contract-property make-contract-property) - 'anonymous-chaperone-contract - chaperone-projection-wrapper) + 'anonymous-chaperone-contract 'build-chaperone-contract-property #f) 'build-chaperone-contract-property)) (define (get-any? c) any?) @@ -460,41 +419,12 @@ #:exercise [exercise (λ (ctc) (λ (fuel) (values void '())))] #:list-contract? [list-contract? (λ (ctc) #f)]) - (let* ([name (or name default-name)] - [first-order (or first-order any?)] - [projection (or projection (first-order-projection name first-order))] - [val-first-projection (or val-first-projection - (and (not projection) - (val-first-first-order-projection name first-order)))] - [late-neg-projection (or late-neg-projection - (and (not projection) - (late-neg-first-order-projection name first-order)))] - [stronger (or stronger as-strong?)]) - - (mk name first-order - projection val-first-projection late-neg-projection - stronger - generate exercise - list-contract?))) - -(define ((get-val-first-first-order-projection get-name get-first-order) c) - (val-first-first-order-projection (get-name c) (get-first-order c))) - -(define ((get-late-neg-first-order-projection get-name get-first-order) c) - (late-neg-first-order-projection (get-name c) (get-first-order c))) - -(define (val-first-first-order-projection name p?) - (λ (b) - (λ (v) - (λ (neg-party) - (if (p? v) - v - (raise-blame-error - b #:missing-party neg-party - v - '(expected: "~s" given: "~e") - name - v)))))) + (mk (or name default-name) + (or first-order any?) + projection val-first-projection late-neg-projection + (or stronger as-strong?) + generate exercise + list-contract?)) (define (late-neg-first-order-projection name p?) (λ (b) diff --git a/racket/collects/racket/contract/private/provide.rkt b/racket/collects/racket/contract/private/provide.rkt index 9fd3edbe08..5e7ea939d3 100644 --- a/racket/collects/racket/contract/private/provide.rkt +++ b/racket/collects/racket/contract/private/provide.rkt @@ -384,36 +384,25 @@ ;; ... -> (or/c #f (-> blame val)) (define (do-partial-app ctc val name pos-module-source source) - (define p (contract-struct-val-first-projection ctc)) + (define p (parameterize ([warn-about-val-first? #f]) + ;; when we're building the val-first projection + ;; here we might be needing the plus1 arity + ;; function (which will be on the val first's result) + ;; so this is a legtimate use. don't warn. + (get/build-val-first-projection ctc))) (define blme (make-blame (build-source-location source) name (λ () (contract-name ctc)) pos-module-source #f #t)) + (define neg-accepter ((p blme) val)) - (cond - [p - (define neg-accepter ((p blme) val)) - - ;; we don't have the negative blame here, but we - ;; expect only positive failures from this; do the - ;; check and then toss the results. - (neg-accepter 'incomplete-blame-from-provide.rkt) - - neg-accepter] - [else - (define proj (contract-struct-projection ctc)) - - ;; we don't have the negative blame here, but we - ;; expect only positive failures from this; do the - ;; check and then toss the results. - ((proj blme) val) - - (procedure-rename - (λ (neg-party) - (define complete-blame (blame-add-missing-party blme neg-party)) - ((proj complete-blame) val)) - (string->symbol (format "provide.rkt:neg-party-fn:~s" (contract-name ctc))))])) + ;; we don't have the negative blame here, but we + ;; expect only positive failures from this; do the + ;; check and then toss the results. + (neg-accepter 'incomplete-blame-from-provide.rkt) + + neg-accepter) (define-for-syntax (true-provide/contract provide-stx just-check-errors? who) (syntax-case provide-stx () diff --git a/racket/collects/racket/contract/private/struct-dc.rkt b/racket/collects/racket/contract/private/struct-dc.rkt index a9a0be9096..f35f9c8e03 100644 --- a/racket/collects/racket/contract/private/struct-dc.rkt +++ b/racket/collects/racket/contract/private/struct-dc.rkt @@ -678,36 +678,33 @@ (define-struct (struct/dc base-struct/dc) () #:property prop:chaperone-contract - (parameterize ([skip-projection-wrapper? #t]) - (build-chaperone-contract-property - #:name struct/dc-name - #:first-order struct/dc-first-order - #:projection struct/dc-proj - #:stronger struct/dc-stronger? - #:generate struct/dc-generate - #:exercise struct/dc-exercise))) + (build-chaperone-contract-property + #:name struct/dc-name + #:first-order struct/dc-first-order + #:projection struct/dc-proj + #:stronger struct/dc-stronger? + #:generate struct/dc-generate + #:exercise struct/dc-exercise)) (define-struct (flat-struct/dc base-struct/dc) () #:property prop:flat-contract - (parameterize ([skip-projection-wrapper? #t]) - (build-flat-contract-property - #:name struct/dc-name - #:first-order struct/dc-flat-first-order - #:projection struct/dc-proj - #:stronger struct/dc-stronger? - #:generate struct/dc-generate - #:exercise struct/dc-exercise))) + (build-flat-contract-property + #:name struct/dc-name + #:first-order struct/dc-flat-first-order + #:projection struct/dc-proj + #:stronger struct/dc-stronger? + #:generate struct/dc-generate + #:exercise struct/dc-exercise)) (define-struct (impersonator-struct/dc base-struct/dc) () #:property prop:contract - (parameterize ([skip-projection-wrapper? #t]) - (build-contract-property - #:name struct/dc-name - #:first-order struct/dc-first-order - #:projection struct/dc-proj - #:stronger struct/dc-stronger? - #:generate struct/dc-generate - #:exercise struct/dc-exercise))) + (build-contract-property + #:name struct/dc-name + #:first-order struct/dc-first-order + #:projection struct/dc-proj + #:stronger struct/dc-stronger? + #:generate struct/dc-generate + #:exercise struct/dc-exercise)) (define (build-struct/dc subcontracts constructor pred struct-name here name-info struct/c?) (for ([subcontract (in-list subcontracts)]) From 70ee04d257bee2d63d581af63b8ca9b31aa201b8 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 9 Dec 2015 06:19:48 -0700 Subject: [PATCH 149/369] fix `zo-path` test to check installed packages --- pkgs/racket-test/tests/zo-path.rkt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/racket-test/tests/zo-path.rkt b/pkgs/racket-test/tests/zo-path.rkt index 3cd85db16f..8e3cdf56eb 100644 --- a/pkgs/racket-test/tests/zo-path.rkt +++ b/pkgs/racket-test/tests/zo-path.rkt @@ -26,6 +26,10 @@ (void) (find-collects-dir)) +(fold-files (check-content #rx"[.](?:zo|dep)$") + (void) + (find-pkgs-dir)) + ;; Check rendered docs, too: (fold-files (check-content #rx"[.](?:html)$") (void) From 2743ea06bbc4de7f8c3503e24c9ed0402f0ed5bf Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 9 Dec 2015 15:25:01 -0700 Subject: [PATCH 150/369] avoid paths in `case-lambda` names Filter absolute path names for `case-lambda` in the same way as for `lambda`. --- racket/src/racket/src/marshal.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/racket/src/racket/src/marshal.c b/racket/src/racket/src/marshal.c index c639f9ec2e..8ccc4e553a 100644 --- a/racket/src/racket/src/marshal.c +++ b/racket/src/racket/src/marshal.c @@ -94,6 +94,7 @@ 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); +static Scheme_Object *closure_marshal_name(Scheme_Object *name); void scheme_init_marshal(Scheme_Env *env) { @@ -365,7 +366,7 @@ static Scheme_Object *write_case_lambda(Scheme_Object *obj) l = cons(cl->array[i], l); } - return cons((cl->name ? cl->name : scheme_null), + return cons(closure_marshal_name(cl->name), l); } @@ -759,17 +760,9 @@ static int not_relative_path(Scheme_Object *p, Scheme_Hash_Table *cache) return 0; } -static Scheme_Object *write_compiled_closure(Scheme_Object *obj) +static Scheme_Object *closure_marshal_name(Scheme_Object *name) { - Scheme_Closure_Data *data; - Scheme_Object *name, *l, *code, *ds, *tl_map; - int svec_size, pos; - Scheme_Marshal_Tables *mt; - - data = (Scheme_Closure_Data *)obj; - - if (data->name) { - name = data->name; + if (name) { if (SCHEME_VECTORP(name)) { /* We can only save marshalable src names, which includes paths, symbols, and strings: */ @@ -786,9 +779,22 @@ static Scheme_Object *write_compiled_closure(Scheme_Object *obj) name = SCHEME_VEC_ELS(name)[0]; } } - } else { + } else name = scheme_null; - } + + return name; +} + +static Scheme_Object *write_compiled_closure(Scheme_Object *obj) +{ + Scheme_Closure_Data *data; + Scheme_Object *name, *l, *code, *ds, *tl_map; + int svec_size, pos; + Scheme_Marshal_Tables *mt; + + data = (Scheme_Closure_Data *)obj; + + name = closure_marshal_name(data->name); svec_size = data->closure_size; if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_TYPED_ARGS) { From 1d7429f1d7555aef5ee9214d3d974c2b056428c6 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 9 Dec 2015 16:44:00 -0700 Subject: [PATCH 151/369] match: avoid recording full paths Use a syntax object to store a source location, letting the marshal process for syntax objects deal with non-relative paths. --- racket/collects/racket/match/gen-match.rkt | 10 +++------- racket/collects/racket/match/runtime.rkt | 10 +++++++++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/racket/collects/racket/match/gen-match.rkt b/racket/collects/racket/match/gen-match.rkt index 5e9b2d9be9..c395db09b4 100644 --- a/racket/collects/racket/match/gen-match.rkt +++ b/racket/collects/racket/match/gen-match.rkt @@ -2,7 +2,7 @@ (require "patterns.rkt" "compiler.rkt" syntax/stx syntax/parse racket/syntax - (for-template racket/base (only-in "runtime.rkt" match:error fail))) + (for-template racket/base (only-in "runtime.rkt" match:error fail syntax-srclocs))) (provide go go/one) @@ -33,17 +33,13 @@ (syntax-e #'fname)] [_ 'match])) (define len (length (syntax->list es))) - (define srcloc-list (list #`(quote #,(syntax-source stx)) - #`(quote #,(syntax-line stx)) - #`(quote #,(syntax-column stx)) - #`(quote #,(syntax-position stx)) - #`(quote #,(syntax-span stx)))) + (define srcloc-stx (datum->syntax #f 'srcloc stx)) (define/with-syntax (xs ...) (generate-temporaries es)) (define/with-syntax (exprs ...) es) (define/with-syntax outer-fail (generate-temporary #'fail)) (define/with-syntax orig-expr (if (= 1 len) (stx-car #'(xs ...)) #'(list xs ...))) (define/with-syntax raise-error - (quasisyntax/loc stx (match:error orig-expr (list (srcloc #,@srcloc-list)) 'form-name))) + (quasisyntax/loc stx (match:error orig-expr (syntax-srclocs (quote-syntax #,srcloc-stx)) 'form-name))) (define parsed-clauses (for/list ([clause (syntax->list clauses)] [pats (syntax->list #'(pats ...))] diff --git a/racket/collects/racket/match/runtime.rkt b/racket/collects/racket/match/runtime.rkt index fad9d05615..59a13b73b8 100644 --- a/racket/collects/racket/match/runtime.rkt +++ b/racket/collects/racket/match/runtime.rkt @@ -9,7 +9,8 @@ fail matchable? match-prompt-tag - mlist? mlist->list) + mlist? mlist->list + syntax-srclocs) (define match-prompt-tag (make-continuation-prompt-tag 'match)) @@ -58,3 +59,10 @@ (cond [(null? l) null] [else (cons (mcar l) (mlist->list (mcdr l)))])) + +(define (syntax-srclocs stx) + (list (srcloc (syntax-source stx) + (syntax-line stx) + (syntax-column stx) + (syntax-position stx) + (syntax-span stx)))) From 835d098eb23abe2566a7722b06829aba40349c0d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 9 Dec 2015 17:11:33 -0700 Subject: [PATCH 152/369] racket/contract: fix blame in arre case Remove an incorrect syntax quote that could cause the contract system to be blamed (and also lead to an absolute path in bytecode). --- racket/collects/racket/contract/private/provide.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/racket/contract/private/provide.rkt b/racket/collects/racket/contract/private/provide.rkt index 5e7ea939d3..f11b8413e3 100644 --- a/racket/collects/racket/contract/private/provide.rkt +++ b/racket/collects/racket/contract/private/provide.rkt @@ -244,7 +244,7 @@ (if (and user-rename-id (syntax-source user-rename-id)) user-rename-id - #'ex-id))) + ex-id))) (with-syntax ([code (syntax-property (quasisyntax/loc stx From b7dd829a6f972020e1e718ff320c51e5fb1f6e7a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 9 Dec 2015 17:21:24 -0700 Subject: [PATCH 153/369] bump version number --- 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 f4ac537349..3b2945611d 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.3.0.7") +(define version "6.3.0.8") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index b877a21668..5ba3ed5f84 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.7" +#define MZSCHEME_VERSION "6.3.0.8" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 3 #define MZSCHEME_VERSION_Z 0 -#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) From f5d5277ae73418f5edb0d0cd37733bc4aaa50a3c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 9 Dec 2015 20:34:23 -0700 Subject: [PATCH 154/369] fix binding table when shadowing imports --- pkgs/racket-test-core/tests/racket/stx.rktl | 19 +++++++++++++++++++ racket/src/racket/src/syntax.c | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test-core/tests/racket/stx.rktl b/pkgs/racket-test-core/tests/racket/stx.rktl index 55b2a49253..4b1e343f6d 100644 --- a/pkgs/racket-test-core/tests/racket/stx.rktl +++ b/pkgs/racket-test-core/tests/racket/stx.rktl @@ -2239,6 +2239,25 @@ [current-load-relative-directory (build-path dir "inner")]) (read i))))) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check that shadowing doesn't create an ill-formed internal +;; representation of binding: + +(let () + ;; Make introducers before namespace, so they have older scopes, which + ;; means that bindings will be attached to the namespace's scope: + (define i1 (make-syntax-introducer)) + (define i2 (make-syntax-introducer)) + (define ns (make-base-namespace)) + (eval `(define car 0) ns) + (eval `(define ,(i1 (datum->syntax #f 'car)) 1) ns) + (eval `(define ,(i2 (datum->syntax #f 'car)) 2) ns) + (eval `(require racket/base) ns) ; replaces plain `car` mapping + (write (compile-syntax + #`(quote-syntax #,(parameterize ([current-namespace ns]) + (namespace-syntax-introduce (datum->syntax #f 'car))))) + (open-output-bytes))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index d3c84f460d..0ef0a6d685 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -2655,7 +2655,7 @@ static Scheme_Object *replace_matching_scopes(Scheme_Object *l, Scheme_Scope_Set p = SCHEME_CDR(p); while (c--) { - p = scheme_make_pair(SCHEME_CAR(l), p); + p = scheme_make_mutable_pair(SCHEME_CAR(l), p); l = SCHEME_CDR(l); } From a952f11bc58c343087f8abf15f89bb999191f0f3 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 10 Dec 2015 09:20:25 -0600 Subject: [PATCH 155/369] unbreak the creation of first-order contracts that don't supply a val-first projection --- racket/collects/racket/contract/private/prop.rkt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/racket/collects/racket/contract/private/prop.rkt b/racket/collects/racket/contract/private/prop.rkt index 5e10eeada1..61c90bf389 100644 --- a/racket/collects/racket/contract/private/prop.rkt +++ b/racket/collects/racket/contract/private/prop.rkt @@ -281,9 +281,11 @@ get-val-first-projection (cond [first-order? - (or get-late-neg-projection - (λ (c) - (late-neg-first-order-projection (get-name c) (get-first-order c))))] + (cond + [get-late-neg-projection get-late-neg-projection] + [(and (not get-projection) (not get-val-first-projection)) + (λ (c) (late-neg-first-order-projection (get-name c) (get-first-order c)))] + [else #f])] [else get-late-neg-projection]) list-contract?)) From 4aabe505be4aad4309a89619f633fc66ac109dd8 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 10 Dec 2015 18:35:50 -0600 Subject: [PATCH 156/369] fix missing party and indy blame interaction (also add all of the fields to the equal and hashing functions) --- .../tests/racket/contract/blame.rkt | 131 +++++++++++++++++- .../racket/contract/private/blame.rkt | 43 ++++-- 2 files changed, 157 insertions(+), 17 deletions(-) diff --git a/pkgs/racket-test/tests/racket/contract/blame.rkt b/pkgs/racket-test/tests/racket/contract/blame.rkt index 5840354c41..61f70d0469 100644 --- a/pkgs/racket-test/tests/racket/contract/blame.rkt +++ b/pkgs/racket-test/tests/racket/contract/blame.rkt @@ -2,8 +2,131 @@ (require "test-util.rkt") (parameterize ([current-contract-namespace - (make-basic-contract-namespace 'racket/contract)]) - + (make-basic-contract-namespace 'racket/contract + 'racket/contract/private/blame)]) + + (test/spec-passed/result + 'blame-selector.1 + '(blame-positive (make-blame (srcloc "src.rkt" #f #f #f #f) + 'whatever (λ () 'the-name) 'pos 'neg #t)) + 'pos) + (test/spec-passed/result + 'blame-selector.2 + '(blame-negative (make-blame (srcloc "src.rkt" #f #f #f #f) + 'whatever (λ () 'the-name) 'pos 'neg #t)) + 'neg) + (test/spec-passed/result + 'blame-selector.3 + '(blame-positive + (blame-swap + (make-blame (srcloc "src.rkt" #f #f #f #f) + 'whatever (λ () 'the-name) 'pos 'neg #t))) + 'neg) + (test/spec-passed/result + 'blame-selector.4 + '(blame-original? + (make-blame (srcloc "src.rkt" #f #f #f #f) + 'whatever (λ () 'the-name) 'pos 'neg #t)) + #t) + (test/spec-passed/result + 'blame-selector.5 + '(blame-original? + (blame-swap + (make-blame (srcloc "src.rkt" #f #f #f #f) + 'whatever (λ () 'the-name) 'pos 'neg #t))) + #f) + (test/spec-passed/result + 'blame-selector.6 + '(blame-negative + (blame-replace-negative + (make-blame (srcloc "src.rkt" #f #f #f #f) + 'whatever (λ () 'the-name) 'pos 'neg #t) + 'neg2)) + 'neg2) + (test/spec-passed/result + 'blame-selector.7 + '(blame-positive + (blame-swap + (blame-replace-negative + (make-blame (srcloc "src.rkt" #f #f #f #f) + 'whatever (λ () 'the-name) 'pos 'neg #t) + 'neg2))) + 'neg2) + (test/spec-passed/result + 'blame-selector.8 + '(blame-positive + (make-blame (srcloc "src.rkt" #f #f #f #f) + 'whatever (λ () 'the-name) 'pos #f #t)) + 'pos) + (test/spec-passed/result + 'blame-selector.9 + '(blame-positive + (blame-add-missing-party + (make-blame (srcloc "src.rkt" #f #f #f #f) + 'whatever (λ () 'the-name) 'pos #f #t) + 'neg)) + 'pos) + (test/spec-passed/result + 'blame-selector.10 + '(blame-negative + (blame-add-missing-party + (make-blame (srcloc "src.rkt" #f #f #f #f) + 'whatever (λ () 'the-name) 'pos #f #t) + 'neg)) + 'neg) + (test/spec-passed/result + 'blame-selector.11 + '(blame-negative + (blame-add-missing-party + (blame-swap + (make-blame (srcloc "src.rkt" #f #f #f #f) + 'whatever (λ () 'the-name) 'pos #f #t)) + 'pos)) + 'pos) + (test/spec-passed/result + 'blame-selector.12 + '(blame-positive + (blame-add-missing-party + (blame-swap + (make-blame (srcloc "src.rkt" #f #f #f #f) + 'whatever (λ () 'the-name) 'pos #f #t)) + 'neg)) + 'neg) + (test/spec-passed/result + 'blame-selector.13 + '(blame-negative + (blame-add-missing-party + (blame-replace-negative + (make-blame (srcloc "src.rkt" #f #f #f #f) + 'whatever (λ () 'the-name) 'pos #f #t) + 'neg2) + 'neg)) + 'neg2) + (test/spec-passed/result + 'blame-selector.14 + '(blame-positive + (blame-add-missing-party + (blame-swap + (blame-replace-negative + (make-blame (srcloc "src.rkt" #f #f #f #f) + 'whatever (λ () 'the-name) 'pos #f #t) + 'neg2)) + 'neg)) + 'neg2) + (test/spec-passed/result + 'blame-selector.15 + '(with-handlers ([exn:fail? + (λ (x) (regexp-match? #rx"^blame-add-missing-party:" + (exn-message x)))]) + (blame-add-missing-party + (blame-add-missing-party + (make-blame (srcloc "src.rkt" #f #f #f #f) + 'whatever (λ () 'the-name) 'pos #f #t) + 'neg) + 'neg2) + 'no-exn-raised) + #t) + (contract-eval #:test-case-name "blame.rkt setup.1" '(module blame-ok/c racket/base @@ -158,4 +281,6 @@ (test/no-error '(let () (define-struct/contract thing ([stuff flat-blame-ok/c])) - (thing-stuff (thing 5)))))) + (thing-stuff (thing 5))))) + + ) diff --git a/racket/collects/racket/contract/private/blame.rkt b/racket/collects/racket/contract/private/blame.rkt index 700576e1c4..4779984e22 100644 --- a/racket/collects/racket/contract/private/blame.rkt +++ b/racket/collects/racket/contract/private/blame.rkt @@ -30,7 +30,11 @@ (equal?/recur (blame-contract a) (blame-contract b)) (equal?/recur (blame-positive a) (blame-positive b)) (equal?/recur (blame-negative a) (blame-negative b)) - (equal?/recur (blame-original? a) (blame-original? b)))) + (equal?/recur (blame-original? a) (blame-original? b)) + (equal?/recur (blame-context a) (blame-context b)) + (equal?/recur (blame-top-known? a) (blame-top-known? b)) + (equal?/recur (blame-important a) (blame-important b)) + (equal?/recur (blame-missing-party? a) (blame-missing-party? b)))) (define (blame-hash b hash/recur) (bitwise-xor (hash/recur (blame-source b)) @@ -38,10 +42,17 @@ (hash/recur (blame-contract b)) (hash/recur (blame-positive b)) (hash/recur (blame-negative b)) - (hash/recur (blame-original? b)))) + (hash/recur (blame-original? b)) + (hash/recur (blame-context b)) + (hash/recur (blame-top-known? b)) + (hash/recur (blame-important b)) + (hash/recur (blame-missing-party? b)))) +;; missing-party? field is #t when the missing party +;; is still missing and it is #f when the missing party +;; has been filled in (or if it was filled in from the start) (define-struct blame - [source value build-name positive negative original? context top-known? important] + [source value build-name positive negative original? context top-known? important missing-party?] #:property prop:equal+hash (list blame=? blame-hash blame-hash)) @@ -67,7 +78,8 @@ original? '() #t - #f))]) + #f + (not negative)))]) make-blame)) ;; s : (or/c string? #f) @@ -177,22 +189,25 @@ blame))) (define (blame-add-missing-party b missing-party) + (define (check-and-fail) + (unless (blame-missing-party? b) + (error 'blame-add-missing-party "already have the party: ~s; trying to add ~s" + (if (blame-swapped? b) (blame-positive b) (blame-negative b)) + missing-party))) (cond [(not missing-party) b] [(blame-swapped? b) - (when (blame-positive b) - (error 'add-missing-party "already have the party: ~s; trying to add ~s" - (blame-positive b) - missing-party)) + (check-and-fail) (struct-copy blame b - [positive (list missing-party)])] + [positive (or (blame-positive b) + (list missing-party))] + [missing-party? #f])] [else - (when (blame-negative b) - (error 'add-missing-party "already have the party: ~s; trying to add ~s" - (blame-negative b) - missing-party)) + (check-and-fail) (struct-copy blame b - [negative (list missing-party)])])) + [negative (or (blame-negative b) + (list missing-party))] + [missing-party? #f])])) (define (blame-fmt->-string blame fmt) (cond From 6593594ebfb31c2ef6920b3ad2d0ef8f5d11a2ca Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 10 Dec 2015 18:41:37 -0600 Subject: [PATCH 157/369] port struct/dc to late-neg style projections --- .../racket/contract/private/struct-dc.rkt | 102 ++++++++++-------- 1 file changed, 55 insertions(+), 47 deletions(-) diff --git a/racket/collects/racket/contract/private/struct-dc.rkt b/racket/collects/racket/contract/private/struct-dc.rkt index f35f9c8e03..0a893c8f32 100644 --- a/racket/collects/racket/contract/private/struct-dc.rkt +++ b/racket/collects/racket/contract/private/struct-dc.rkt @@ -223,7 +223,7 @@ (define (struct/dc-first-order ctc) (base-struct/dc-pred ctc)) -(define (struct/dc-proj ctc) +(define (struct/dc-late-neg-proj ctc) (define pred? (base-struct/dc-pred ctc)) (λ (blame) (define orig-blames @@ -240,7 +240,7 @@ (define ctxt-string (format "the ~a field of" (subcontract-field-name subcontract))) (blame-add-context blame ctxt-string #:swap? #t)] [else #f]))) - (define orig-indy-blames + (define orig-indy-blames (for/list ([subcontract (in-list (base-struct/dc-subcontracts ctc))]) (and (subcontract? subcontract) (blame-replace-negative @@ -260,7 +260,7 @@ (cond [(indep? subcontract) (define sub-ctc (indep-ctc subcontract)) - ((contract-projection sub-ctc) blame+ctxt)] + ((contract-late-neg-projection sub-ctc) blame+ctxt)] [else #f]))) (define mut-projs (for/list ([subcontract (in-list (base-struct/dc-subcontracts ctc))] @@ -268,7 +268,7 @@ (cond [(and (indep? subcontract) (mutable? subcontract)) (define sub-ctc (indep-ctc subcontract)) - ((contract-projection sub-ctc) blame+ctxt)] + ((contract-late-neg-projection sub-ctc) blame+ctxt)] [else #f]))) (define orig-indy-projs (for/list ([subcontract (in-list (base-struct/dc-subcontracts ctc))] @@ -276,7 +276,7 @@ (cond [(indep? subcontract) (define sub-ctc (indep-ctc subcontract)) - ((contract-projection sub-ctc) blame+ctxt)] + ((contract-late-neg-projection sub-ctc) blame+ctxt)] [else #f]))) (define orig-mut-indy-projs (for/list ([subcontract (in-list (base-struct/dc-subcontracts ctc))] @@ -284,16 +284,17 @@ (cond [(indep? subcontract) (define sub-ctc (indep-ctc subcontract)) - ((contract-projection sub-ctc) blame+ctxt)] + ((contract-late-neg-projection sub-ctc) blame+ctxt)] [else #f]))) - (λ (v) + (λ (v neg-party) (cond [(and (struct/c-imp-prop-pred? v) (contract-stronger? (struct/c-imp-prop-get v) ctc)) v] [else (unless (pred? v) - (raise-blame-error blame v '(expected: "~a?" given: "~e") + (raise-blame-error blame #:missing-party neg-party + v '(expected: "~a?" given: "~e") (base-struct/dc-struct-name ctc) v)) (define invariant (for/or ([c (in-list (base-struct/dc-subcontracts ctc))]) @@ -319,7 +320,7 @@ v impersonate-args) (if invariant - (add-invariant-checks blame invariant chaperone-args) + (add-invariant-checks blame neg-party invariant chaperone-args) chaperone-args))] [else (define subcontract (car subcontracts)) ;; (or/c subcontract? invariant?) @@ -338,20 +339,20 @@ 'struct/dc (apply (dep-dep-proc subcontract) dep-args)))) (when dep-ctc (check-flat/chaperone dep-ctc subcontract)) - (define dep-ctc-blame-proj (and dep-ctc (contract-projection dep-ctc))) + (define dep-ctc-blame-proj (and dep-ctc (contract-late-neg-projection dep-ctc))) (define-values (new-chaperone-args new-impersonate-args) (cond [(invariant? subcontract) (unless (with-continuation-mark contract-continuation-mark-key blame (apply (invariant-dep-proc subcontract) dep-args)) - (raise-invariant-blame-failure blame v + (raise-invariant-blame-failure blame neg-party v (reverse dep-args) (reverse (invariant-fields subcontract)))) (values chaperone-args impersonate-args)] [(immutable? subcontract) (define (chk fld v) (with-continuation-mark contract-continuation-mark-key blame - (proj v))) + (proj v neg-party))) (chk #f (sel v)) ;; check the field contract immediately (values (if (flat-contract? (indep-ctc subcontract)) chaperone-args @@ -362,7 +363,7 @@ (cache-λ (fld v) (with-continuation-mark contract-continuation-mark-key blame - (proj v))) + (proj v neg-party))) chaperone-args) impersonate-args)] [(mutable? subcontract) @@ -372,23 +373,23 @@ (λ (fld v) (with-continuation-mark contract-continuation-mark-key blame - (proj v))) + (proj v neg-party))) (mutable-set subcontract) (λ (fld v) (with-continuation-mark contract-continuation-mark-key blame - (mut-proj v))) + (mut-proj v neg-party))) impersonate-args)) (values (list* sel (λ (fld v) (with-continuation-mark contract-continuation-mark-key blame - (proj v))) + (proj v neg-party))) (mutable-set subcontract) (λ (fld v) (with-continuation-mark contract-continuation-mark-key blame - (mut-proj v))) + (mut-proj v neg-party))) chaperone-args) impersonate-args))] [else @@ -397,7 +398,7 @@ [(dep-immutable? subcontract) (define (chk fld v) (with-continuation-mark contract-continuation-mark-key blame - (proj v))) + (proj v neg-party))) (chk #f (sel v)) ;; check the field contract immediately (values (if (flat-contract? dep-ctc) chaperone-args @@ -408,7 +409,7 @@ (cache-λ (fld v) (with-continuation-mark contract-continuation-mark-key blame - (proj v))) + (proj v neg-party))) chaperone-args) impersonate-args)] [(dep-mutable? subcontract) @@ -418,12 +419,12 @@ (λ (fld v) (with-continuation-mark contract-continuation-mark-key blame - (proj v))) + (proj v neg-party))) (dep-mutable-set subcontract) (λ (fld v) (with-continuation-mark contract-continuation-mark-key blame - (mut-proj v))) + (mut-proj v neg-party))) chaperone-args) impersonate-args) (values chaperone-args @@ -431,36 +432,37 @@ (λ (fld v) (with-continuation-mark contract-continuation-mark-key blame - (proj v))) + (proj v neg-party))) (dep-mutable-set subcontract) (λ (fld v) (with-continuation-mark contract-continuation-mark-key blame - (mut-proj v))) + (mut-proj v neg-party))) impersonate-args)))] [(dep-on-state-immutable? subcontract) - (proj (sel v)) + (proj (sel v) neg-party) (values (list* sel (λ (strct val) (with-continuation-mark contract-continuation-mark-key blame (build-dep-on-state-proj (base-struct/dc-subcontracts ctc) subcontract strct - orig-indy-projs orig-indy-blames blame val))) + orig-indy-projs orig-indy-blames blame neg-party val))) chaperone-args) impersonate-args)] [(dep-on-state-mutable? subcontract) - (proj (sel v)) + (proj (sel v) neg-party) (define (get-chap-proc strct val) (with-continuation-mark contract-continuation-mark-key blame (build-dep-on-state-proj (base-struct/dc-subcontracts ctc) subcontract strct - orig-indy-projs orig-indy-blames blame val))) + orig-indy-projs orig-indy-blames blame neg-party + val))) (define (set-chap-proc strct val) (with-continuation-mark contract-continuation-mark-key blame (build-dep-on-state-proj (base-struct/dc-subcontracts ctc) subcontract strct - orig-mut-indy-projs orig-mut-indy-blames mut-blame val))) + orig-mut-indy-projs orig-mut-indy-blames mut-blame neg-party val))) (if (eq? (dep-type subcontract) '#:impersonator) (values chaperone-args (list* sel @@ -481,12 +483,14 @@ new-impersonate-args (if (and (subcontract? subcontract) (subcontract-depended-on? subcontract)) (cons (if dep-ctc-blame-proj - ((dep-ctc-blame-proj indy-blame) ((subcontract-ref subcontract) v)) - (indy-proj ((subcontract-ref subcontract) v))) + ((dep-ctc-blame-proj indy-blame) + ((subcontract-ref subcontract) v) + neg-party) + (indy-proj ((subcontract-ref subcontract) v) neg-party)) dep-args) dep-args))]))])))) -(define (check-invariant/mut blame invariant val sel field-v) +(define (check-invariant/mut blame neg-party invariant val sel field-v) (define args (let loop ([sels (invariant-sels invariant)] [args '()]) @@ -498,15 +502,15 @@ (loop (cdr sels) (cons field-v args)) (loop (cdr sels) (cons (sel val) args)))]))) (unless (apply (invariant-dep-proc invariant) args) - (raise-invariant-blame-failure (blame-swap blame) val + (raise-invariant-blame-failure (blame-swap blame) neg-party val (reverse args) (reverse (invariant-fields invariant))))) -(define (raise-invariant-blame-failure blame v vals field-names) +(define (raise-invariant-blame-failure blame neg-party v vals field-names) (raise-blame-error - blame - v + blame #:missing-party neg-party + v "#:inv does not hold~a" (apply string-append @@ -515,7 +519,7 @@ [field-name (in-list field-names)]) (format "\n ~a: ~e" field-name dep-arg))))) -(define (add-invariant-checks blame invariant chaperone-args) +(define (add-invariant-checks blame neg-party invariant chaperone-args) (let loop ([invariant-field-sels/muts (for/list ([sel (in-list (invariant-sels invariant))] [mut (in-list (invariant-muts invariant))] @@ -531,7 +535,7 @@ (define mut (cdr sel/mut)) (list mut (λ (stct field-v) - (check-invariant/mut blame invariant stct sel field-v) + (check-invariant/mut blame neg-party invariant stct sel field-v) field-v))))] [else (define fn (car chaperone-args)) @@ -548,7 +552,7 @@ [which (list* fn (λ (stct field-v) - (check-invariant/mut blame invariant stct sel field-v) + (check-invariant/mut blame neg-party invariant stct sel field-v) (proc stct field-v)) (loop (remove-ith invariant-field-sels/muts which) (cddr chaperone-args)))] @@ -565,7 +569,8 @@ (cdr l) (cons (car l) (remove-ith (cdr l) (- i 1))))])) -(define (build-dep-on-state-proj orig-subcontracts this-subcontract strct projs blames blame val) +(define (build-dep-on-state-proj orig-subcontracts this-subcontract strct projs + blames blame neg-party val) (let loop ([subcontracts orig-subcontracts] [blames blames] [projs projs] @@ -582,7 +587,7 @@ (define the-ctc (coerce-contract 'struct/dc (apply (dep-dep-proc this-subcontract) dep-args))) (check-flat/chaperone the-ctc subcontract) - (((contract-projection the-ctc) blame) val)] + (((contract-late-neg-projection the-ctc) blame) val neg-party)] [else (define indy-blame (car blames)) (define proj (car projs)) @@ -591,7 +596,7 @@ (coerce-contract 'struct/dc (apply (dep-dep-proc subcontract) dep-args)))) - (define dep-ctc-blame-proj (and dep-ctc (contract-projection dep-ctc))) + (define dep-ctc-blame-proj (and dep-ctc (contract-late-neg-projection dep-ctc))) (when (dep? subcontract) (check-flat/chaperone dep-ctc subcontract)) @@ -599,8 +604,10 @@ (define new-dep-args (if (and (subcontract? subcontract) (subcontract-depended-on? subcontract)) (cons (if dep-ctc-blame-proj - ((dep-ctc-blame-proj indy-blame) ((subcontract-ref subcontract) strct)) - (proj ((subcontract-ref subcontract) strct))) + ((dep-ctc-blame-proj indy-blame) + ((subcontract-ref subcontract) strct) + neg-party) + (proj ((subcontract-ref subcontract) strct) neg-party)) dep-args) dep-args)) (loop (cdr subcontracts) @@ -681,7 +688,7 @@ (build-chaperone-contract-property #:name struct/dc-name #:first-order struct/dc-first-order - #:projection struct/dc-proj + #:late-neg-projection struct/dc-late-neg-proj #:stronger struct/dc-stronger? #:generate struct/dc-generate #:exercise struct/dc-exercise)) @@ -691,7 +698,7 @@ (build-flat-contract-property #:name struct/dc-name #:first-order struct/dc-flat-first-order - #:projection struct/dc-proj + #:late-neg-projection struct/dc-late-neg-proj #:stronger struct/dc-stronger? #:generate struct/dc-generate #:exercise struct/dc-exercise)) @@ -701,7 +708,7 @@ (build-contract-property #:name struct/dc-name #:first-order struct/dc-first-order - #:projection struct/dc-proj + #:late-neg-projection struct/dc-late-neg-proj #:stronger struct/dc-stronger? #:generate struct/dc-generate #:exercise struct/dc-exercise)) @@ -1443,7 +1450,8 @@ (blame-add-context blame (format "the ~a field of" fld))) (define (struct/dc-error blame obj what) - (raise-blame-error blame obj + (raise-blame-error blame + obj '(expected: "a struct of type ~a") what)) From acbcff1bf4db067511cb7025fe47f3de17143c40 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Fri, 11 Dec 2015 10:14:12 -0500 Subject: [PATCH 158/369] Make zo-path checking available as a library. --- pkgs/racket-test/tests/zo-path.rkt | 38 ++++++++++++++++-------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/pkgs/racket-test/tests/zo-path.rkt b/pkgs/racket-test/tests/zo-path.rkt index 8e3cdf56eb..e211ea2600 100644 --- a/pkgs/racket-test/tests/zo-path.rkt +++ b/pkgs/racket-test/tests/zo-path.rkt @@ -1,6 +1,8 @@ #lang racket (require setup/dirs) +(provide check-one) + ;; Paths from the build location shouldn't show up in bytecode files ;; or documentation. Check ".zo", ".dep", and ".html" files in the ;; build on the assumption that the first three elements of the @@ -11,26 +13,26 @@ (regexp-quote (path->bytes (apply build-path - (take (explode-path (find-collects-dir)) + (take (explode-path (find-collects-dir)) 3)))))) -(define (check-content rx:name) - (lambda (name kind v) - (when (regexp-match? rx:name name) - (call-with-input-file* name - (lambda (in) - (when (regexp-match? rx:dir in) - (eprintf "Found ~s in ~s\n" rx:dir name))))))) +(define (check-one file) + (call-with-input-file* + file + (lambda (in) + (when (regexp-match? rx:dir in) + (eprintf "Found ~s in ~s\n" rx:dir file))))) -(fold-files (check-content #rx"[.](?:zo|dep)$") - (void) - (find-collects-dir)) +(define ((check-content rx:name) name kind v) + (when (regexp-match? rx:name name) + (check-one name))) -(fold-files (check-content #rx"[.](?:zo|dep)$") - (void) - (find-pkgs-dir)) +(module+ main + (fold-files (check-content #rx"[.](?:zo|dep)$") + (void) + (find-pkgs-dir)) -;; Check rendered docs, too: -(fold-files (check-content #rx"[.](?:html)$") - (void) - (find-doc-dir)) + ;; Check rendered docs, too: + (fold-files (check-content #rx"[.](?:html)$") + (void) + (find-doc-dir))) From e45e5712de55ed638d62c9eafd027dbff535100c Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Fri, 11 Dec 2015 13:11:48 -0500 Subject: [PATCH 159/369] Use `quote-srcloc` to avoid paths in the compiled code. Closes #1165. --- racket/collects/racket/contract/private/provide.rkt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/racket/collects/racket/contract/private/provide.rkt b/racket/collects/racket/contract/private/provide.rkt index f11b8413e3..12055dcadc 100644 --- a/racket/collects/racket/contract/private/provide.rkt +++ b/racket/collects/racket/contract/private/provide.rkt @@ -267,12 +267,7 @@ ;; syntax -> syntax ;; returns an expression that evaluates to the source location of the argument (define-for-syntax (stx->srcloc-expr srcloc-stx) - #`(vector - '#,(syntax-source srcloc-stx) - #,(syntax-line srcloc-stx) - #,(syntax-column srcloc-stx) - #,(syntax-position srcloc-stx) - #,(syntax-span srcloc-stx))) + #`(quote-srcloc #,srcloc-stx)) (define-for-syntax (internal-function-to-be-figured-out ctrct id From 4354ce45d8658cbad5005f56e02b48b1e6a5ccd0 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 11 Dec 2015 10:06:13 -0700 Subject: [PATCH 160/369] use `scribble/examples' for the Reference Port `examples`, `interactions`, etc., to use the new `examples` form of `scribble/examples`. The main intended effect is to ensure that errors are produced by examples only as specifically indicated. --- .../compatibility/scribblings/package.scrbl | 10 +- pkgs/racket-doc/info.rkt | 2 +- .../reference/async-channels.scrbl | 42 +- .../scribblings/reference/block.scrbl | 2 +- .../scribblings/reference/bytes.scrbl | 2 +- .../scribblings/reference/chaperones.scrbl | 20 +- .../scribblings/reference/class.scrbl | 642 +++++++++--------- .../scribblings/reference/contracts.scrbl | 229 ++++--- .../scribblings/reference/custom-ports.scrbl | 4 +- .../scribblings/reference/custom-write.scrbl | 38 +- .../scribblings/reference/define-struct.scrbl | 68 +- .../scribblings/reference/dicts.scrbl | 16 +- .../scribblings/reference/evts.scrbl | 1 - .../scribblings/reference/exns.scrbl | 25 +- .../scribblings/reference/fasl.scrbl | 2 +- .../scribblings/reference/file-ports.scrbl | 4 +- .../scribblings/reference/filesystem.scrbl | 10 +- .../scribblings/reference/fixnums.scrbl | 2 +- .../scribblings/reference/flonums.scrbl | 2 +- .../scribblings/reference/for.scrbl | 18 +- .../scribblings/reference/format.scrbl | 43 +- .../scribblings/reference/futures.scrbl | 4 +- .../scribblings/reference/generic.scrbl | 4 +- .../scribblings/reference/hashes.scrbl | 4 +- .../scribblings/reference/logging.scrbl | 8 +- .../scribblings/reference/match.scrbl | 53 +- pkgs/racket-doc/scribblings/reference/mz.rkt | 4 +- .../scribblings/reference/numbers.scrbl | 12 +- .../scribblings/reference/pairs.scrbl | 18 +- .../scribblings/reference/port-lib.scrbl | 2 +- .../scribblings/reference/procedures.scrbl | 72 +- .../scribblings/reference/regexps.scrbl | 2 +- .../scribblings/reference/sandbox.scrbl | 18 +- .../scribblings/reference/sequences.scrbl | 56 +- .../scribblings/reference/serialization.scrbl | 2 +- .../scribblings/reference/sets.scrbl | 7 +- .../scribblings/reference/shared.scrbl | 12 +- .../scribblings/reference/splicing.scrbl | 15 +- .../scribblings/reference/string-ports.scrbl | 2 +- .../scribblings/reference/strings.scrbl | 2 +- .../scribblings/reference/struct.scrbl | 60 +- .../scribblings/reference/stx-comp.scrbl | 2 +- .../scribblings/reference/stx-ops.scrbl | 2 +- .../scribblings/reference/stx-param.scrbl | 5 +- .../scribblings/reference/stx-trans.scrbl | 4 +- .../scribblings/reference/syntax-model.scrbl | 4 +- .../scribblings/reference/syntax-util.scrbl | 11 +- .../scribblings/reference/syntax.scrbl | 152 +++-- .../scribblings/reference/trace.scrbl | 3 +- .../scribblings/reference/values.scrbl | 2 +- .../scribblings/reference/vectors.scrbl | 4 +- 51 files changed, 898 insertions(+), 830 deletions(-) diff --git a/pkgs/racket-doc/compatibility/scribblings/package.scrbl b/pkgs/racket-doc/compatibility/scribblings/package.scrbl index 16f5939195..278b64082d 100644 --- a/pkgs/racket-doc/compatibility/scribblings/package.scrbl +++ b/pkgs/racket-doc/compatibility/scribblings/package.scrbl @@ -2,7 +2,7 @@ @(require scribblings/reference/mz (for-label compatibility/package)) @(define pack-eval (make-base-eval)) -@interaction-eval[#:eval pack-eval (require compatibility/package)] +@examples[#:hidden #:eval pack-eval (require compatibility/package)] @title[#:tag "compatibility-package"]{Limiting Scope: @racket[define-package], @racket[open-package], ...} @@ -61,11 +61,11 @@ is the exported one. (define-package presents (doll) (define doll "Molly Coddle") (define robot "Destructo")) -doll -robot +(eval:error doll) +(eval:error robot) (open-package presents) doll -robot +(eval:error robot) (define-package big-russian-doll (middle-russian-doll) (define-package middle-russian-doll (little-russian-doll) (define little-russian-doll "Anastasia"))) @@ -95,7 +95,7 @@ the defined bindings remain hidden outside the (package-begin (define secret "mimi") (list secret)) -secret +(eval:error secret) ]} @deftogether[( diff --git a/pkgs/racket-doc/info.rkt b/pkgs/racket-doc/info.rkt index 48eca51fa1..e80f691186 100644 --- a/pkgs/racket-doc/info.rkt +++ b/pkgs/racket-doc/info.rkt @@ -6,7 +6,7 @@ "base" "net-lib" "sandbox-lib" - "scribble-lib" + ["scribble-lib" #:version "1.14"] "racket-index")) (define build-deps '("rackunit-doc" "compatibility" diff --git a/pkgs/racket-doc/scribblings/reference/async-channels.scrbl b/pkgs/racket-doc/scribblings/reference/async-channels.scrbl index 9da432a95e..9c4d6bcc85 100644 --- a/pkgs/racket-doc/scribblings/reference/async-channels.scrbl +++ b/pkgs/racket-doc/scribblings/reference/async-channels.scrbl @@ -70,27 +70,27 @@ synchronization} when @racket[(async-channel-put ach v)] would return a value (i.e., when the channel holds fewer values already than its limit); @resultItself{asychronous channel-put event}.} -@defexamples[#:eval (async-eval) -(define (server input-channel output-channel) - (thread (lambda () - (define (get) - (async-channel-get input-channel)) - (define (put x) - (async-channel-put output-channel x)) - (define (do-large-computation) - (sqrt 9)) - (let loop ([data (get)]) - (case data - [(quit) (void)] - [(add) (begin - (put (+ 1 (get))) - (loop (get)))] - [(long) (begin - (put (do-large-computation)) - (loop (get)))]))))) - -(define to-server (make-async-channel)) -(define from-server (make-async-channel)) +@examples[#:eval (async-eval) #:once +(eval:no-prompt + (define (server input-channel output-channel) + (thread (lambda () + (define (get) + (async-channel-get input-channel)) + (define (put x) + (async-channel-put output-channel x)) + (define (do-large-computation) + (sqrt 9)) + (let loop ([data (get)]) + (case data + [(quit) (void)] + [(add) (begin + (put (+ 1 (get))) + (loop (get)))] + [(long) (begin + (put (do-large-computation)) + (loop (get)))]))))) + (define to-server (make-async-channel)) + (define from-server (make-async-channel))) (server to-server from-server) diff --git a/pkgs/racket-doc/scribblings/reference/block.scrbl b/pkgs/racket-doc/scribblings/reference/block.scrbl index 61a3aad2ad..2d757c3c92 100644 --- a/pkgs/racket-doc/scribblings/reference/block.scrbl +++ b/pkgs/racket-doc/scribblings/reference/block.scrbl @@ -1,5 +1,5 @@ #lang scribble/doc -@(require "mz.rkt" scribble/eval (for-label racket/block)) +@(require "mz.rkt" (for-label racket/block)) @(define ev (make-base-eval)) @(ev '(require racket/block)) diff --git a/pkgs/racket-doc/scribblings/reference/bytes.scrbl b/pkgs/racket-doc/scribblings/reference/bytes.scrbl index 4b2f62222f..97de7fdd4b 100644 --- a/pkgs/racket-doc/scribblings/reference/bytes.scrbl +++ b/pkgs/racket-doc/scribblings/reference/bytes.scrbl @@ -643,7 +643,7 @@ normally identified by @racket[""]). See also @section{Additional Byte String Functions} @note-lib[racket/bytes] @(define string-eval (make-base-eval)) -@(interaction-eval #:eval string-eval (require racket/bytes racket/list)) +@@examples[#:hidden #:eval string-eval (require racket/bytes racket/list)] @defproc[(bytes-append* [str bytes?] ... [strs (listof bytes?)]) bytes?]{ @; Note: this is exactly the same description as the one for append* diff --git a/pkgs/racket-doc/scribblings/reference/chaperones.scrbl b/pkgs/racket-doc/scribblings/reference/chaperones.scrbl index 646be4c8ec..ec16c2cbbf 100644 --- a/pkgs/racket-doc/scribblings/reference/chaperones.scrbl +++ b/pkgs/racket-doc/scribblings/reference/chaperones.scrbl @@ -924,11 +924,12 @@ procedure. (lambda (n) (* n 2)) (lambda (n) (+ n 1)))) - (call-with-continuation-prompt - (lambda () - (abort-current-continuation bad-chaperone 5)) - bad-chaperone - (lambda (n) n)) + (eval:error + (call-with-continuation-prompt + (lambda () + (abort-current-continuation bad-chaperone 5)) + bad-chaperone + (lambda (n) n))) (define good-chaperone (chaperone-prompt-tag @@ -966,10 +967,11 @@ given. (lambda (l) (map char-upcase l)) string->list)) - (with-continuation-mark bad-chaperone "timballo" - (continuation-mark-set-first - (current-continuation-marks) - bad-chaperone)) + (eval:error + (with-continuation-mark bad-chaperone "timballo" + (continuation-mark-set-first + (current-continuation-marks) + bad-chaperone))) (define (checker s) (if (> (string-length s) 5) diff --git a/pkgs/racket-doc/scribblings/reference/class.scrbl b/pkgs/racket-doc/scribblings/reference/class.scrbl index 9eb15c1fb7..e95455db04 100644 --- a/pkgs/racket-doc/scribblings/reference/class.scrbl +++ b/pkgs/racket-doc/scribblings/reference/class.scrbl @@ -71,11 +71,10 @@ ) -@(interaction-eval #:eval class-eval (require racket/class racket/contract)) -@(interaction-eval - #:eval class-ctc-eval - (require racket/class racket/contract)) - +@examples[#:hidden #:eval class-eval + (require racket/class racket/contract)] +@examples[#:hidden #:eval class-ctc-eval + (require racket/class racket/contract)] @title[#:tag "mzlib:class" #:style 'toc]{Classes and Objects} @@ -196,8 +195,9 @@ is the most specific requirement from its superinterfaces. If the superinterfaces specify inconsistent derivation requirements, the @exnraise[exn:fail:object]. -@defexamples[ +@examples[ #:eval class-ctc-eval +#:no-prompt (define file-interface<%> (interface () open close read-byte write-byte)) (define directory-interface<%> @@ -226,8 +226,9 @@ extended to produce the internal structure type for instances of the class (so that no information about fields is accessible to the structure type property's guard, if any). -@defexamples[ +@examples[ #:eval class-eval +#:no-prompt (define i<%> (interface* () ([prop:custom-write (lambda (obj port mode) (void))]) method1 method2 method3)) @@ -387,8 +388,9 @@ calling subclass augmentations of methods (see Like @racket[class*], but omits the @racket[_interface-expr]s, for the case that none are needed. -@defexamples[ +@examples[ #:eval class-eval +#:no-prompt (define book-class% (class object% (field (pages 5)) @@ -404,15 +406,16 @@ to the current object (i.e., the object being initialized or whose method was called). Use outside the body of a @racket[class*] form is a syntax error. -@defexamples[ +@examples[ #:eval class-eval -(define (describe obj) - (printf "Hello ~a\n" obj)) -(define table% - (class object% - (define/public (describe-self) - (describe this)) - (super-new))) +(eval:no-prompt + (define (describe obj) + (printf "Hello ~a\n" obj)) + (define table% + (class object% + (define/public (describe-self) + (describe this)) + (super-new)))) (send (new table%) describe-self) ]} @@ -423,21 +426,22 @@ of the current object (i.e., the object being initialized or whose method was called). Use outside the body of a @racket[class*] form is a syntax error. -@defexamples[ +@examples[ #:eval class-eval -(define account% - (class object% - (super-new) - (init-field balance) - (define/public (add n) - (new this% [balance (+ n balance)])))) -(define savings% - (class account% - (super-new) - (inherit-field balance) - (define interest 0.04) - (define/public (add-interest) - (send this add (* interest balance))))) +(eval:no-prompt + (define account% + (class object% + (super-new) + (init-field balance) + (define/public (add n) + (new this% [balance (+ n balance)])))) + (define savings% + (class account% + (super-new) + (inherit-field balance) + (define interest 0.04) + (define/public (add-interest) + (send this add (* interest balance)))))) (let* ([acct (new savings% [balance 500])] [acct (send acct add 500)] [acct (send acct add-interest)]) @@ -447,7 +451,7 @@ a syntax error. @defclassforms[ [(inspect inspector-expr) ()] [(init init-decl ...) ("clinitvars") - @defexamples[#:eval class-eval + @examples[#:eval class-eval (class object% (super-new) (init turnip @@ -455,7 +459,7 @@ a syntax error. [carrot 'good] [(internal-rutabaga rutabaga) 'okay]))]] [(init-field init-decl ...) ("clinitvars" "clfields") - @defexamples[#:eval class-eval + @examples[#:eval class-eval (class object% (super-new) (init-field turkey @@ -463,181 +467,202 @@ a syntax error. [chicken 7] [(internal-emu emu) 13]))]] [(field field-decl ...) ("clfields") - @defexamples[#:eval class-eval + @examples[#:eval class-eval (class object% (super-new) (field [minestrone 'ready] [(internal-coq-au-vin coq-au-vin) 'stewing]))]] [(inherit-field maybe-renamed ...) ("clfields") - @defexamples[#:eval class-eval - (define cookbook% - (class object% - (super-new) - (field [recipes '(caldo-verde oyakodon eggs-benedict)] - [pages 389]))) + @examples[#:eval class-eval + (eval:no-prompt + (define cookbook% + (class object% + (super-new) + (field [recipes '(caldo-verde oyakodon eggs-benedict)] + [pages 389])))) (class cookbook% (super-new) (inherit-field recipes [internal-pages pages]))]] [* ((init-rest id) (init-rest)) ("clinitvars") - @defexamples[#:eval class-eval - (define fruit-basket% - (class object% - (super-new) - (init-rest fruits) - (displayln fruits))) - (make-object fruit-basket% 'kiwi 'lychee 'melon)]] - [(public maybe-renamed ...) ("clmethoddefs") - @defexamples[#:eval class-eval - (define jumper% + @examples[#:eval class-eval + (eval:no-prompt + (define fruit-basket% (class object% (super-new) - (define (skip) 'skip) - (define (hop) 'hop) - (public skip [hop jump]))) + (init-rest fruits) + (displayln fruits)))) + (make-object fruit-basket% 'kiwi 'lychee 'melon)]] + [(public maybe-renamed ...) ("clmethoddefs") + @examples[#:eval class-eval + (eval:no-prompt + (define jumper% + (class object% + (super-new) + (define (skip) 'skip) + (define (hop) 'hop) + (public skip [hop jump])))) (send (new jumper%) skip) (send (new jumper%) jump)]] [(pubment maybe-renamed ...) ("clmethoddefs") - @defexamples[#:eval class-eval - (define runner% - (class object% - (super-new) - (define (run) 'run) - (define (trot) 'trot) - (pubment run [trot jog]))) + @examples[#:eval class-eval + (eval:no-prompt + (define runner% + (class object% + (super-new) + (define (run) 'run) + (define (trot) 'trot) + (pubment run [trot jog])))) (send (new runner%) run) (send (new runner%) jog)]] [(public-final maybe-renamed ...) ("clmethoddefs") - @defexamples[#:eval class-eval - (define point% - (class object% - (super-new) - (init-field [x 0] [y 0]) - (define (get-x) x) - (define (do-get-y) y) - (public-final get-x [do-get-y get-y]))) + @examples[#:eval class-eval + (eval:no-prompt + (define point% + (class object% + (super-new) + (init-field [x 0] [y 0]) + (define (get-x) x) + (define (do-get-y) y) + (public-final get-x [do-get-y get-y])))) (send (new point% [x 1] [y 3]) get-y) - (class point% - (super-new) - (define (get-x) 3.14) - (override get-x))]] + (eval:error + (class point% + (super-new) + (define (get-x) 3.14) + (override get-x)))]] [(override maybe-renamed ...) ("clmethoddefs") - @defexamples[#:eval class-eval - (define sheep% - (class object% - (super-new) - (define/public (bleat) - (displayln "baaaaaaaaah")))) - (define confused-sheep% - (class sheep% - (super-new) - (define (bleat) - (super bleat) - (displayln "???")) - (override bleat))) + @examples[#:eval class-eval + (eval:no-prompt + (define sheep% + (class object% + (super-new) + (define/public (bleat) + (displayln "baaaaaaaaah"))))) + (eval:no-prompt + (define confused-sheep% + (class sheep% + (super-new) + (define (bleat) + (super bleat) + (displayln "???")) + (override bleat)))) (send (new sheep%) bleat) (send (new confused-sheep%) bleat)]] [(overment maybe-renamed ...) ("clmethoddefs") - @defexamples[#:eval class-eval - (define turkey% - (class object% - (super-new) - (define/public (gobble) - (displayln "gobble gobble")))) - (define extra-turkey% - (class turkey% - (super-new) - (define (gobble) - (super gobble) - (displayln "gobble gobble gobble") - (inner (void) gobble)) - (overment gobble))) - (define cyborg-turkey% - (class extra-turkey% - (super-new) - (define/augment (gobble) - (displayln "110011111011111100010110001011011001100101")))) + @examples[#:eval class-eval + (eval:no-prompt + (define turkey% + (class object% + (super-new) + (define/public (gobble) + (displayln "gobble gobble"))))) + (eval:no-prompt + (define extra-turkey% + (class turkey% + (super-new) + (define (gobble) + (super gobble) + (displayln "gobble gobble gobble") + (inner (void) gobble)) + (overment gobble)))) + (eval:no-prompt + (define cyborg-turkey% + (class extra-turkey% + (super-new) + (define/augment (gobble) + (displayln "110011111011111100010110001011011001100101"))))) (send (new extra-turkey%) gobble) (send (new cyborg-turkey%) gobble)]] [(override-final maybe-renamed ...) ("clmethoddefs") - @defexamples[#:eval class-eval - (define meeper% - (class object% - (super-new) - (define/public (meep) - (displayln "meep")))) - (define final-meeper% - (class meeper% - (super-new) - (define (meep) - (super meep) - (displayln "This meeping ends with me")) - (override-final meep))) + @examples[#:eval class-eval + (eval:no-prompt + (define meeper% + (class object% + (super-new) + (define/public (meep) + (displayln "meep"))))) + (eval:no-prompt + (define final-meeper% + (class meeper% + (super-new) + (define (meep) + (super meep) + (displayln "This meeping ends with me")) + (override-final meep)))) (send (new meeper%) meep) (send (new final-meeper%) meep)]] [(augment maybe-renamed ...) ("clmethoddefs") - @defexamples[#:eval class-eval - (define buzzer% - (class object% - (super-new) - (define/pubment (buzz) - (displayln "bzzzt") - (inner (void) buzz)))) - (define loud-buzzer% - (class buzzer% - (super-new) - (define (buzz) - (displayln "BZZZZZZZZZT")) - (augment buzz))) + @examples[#:eval class-eval + (eval:no-prompt + (define buzzer% + (class object% + (super-new) + (define/pubment (buzz) + (displayln "bzzzt") + (inner (void) buzz))))) + (eval:no-prompt + (define loud-buzzer% + (class buzzer% + (super-new) + (define (buzz) + (displayln "BZZZZZZZZZT")) + (augment buzz)))) (send (new buzzer%) buzz) (send (new loud-buzzer%) buzz)]] [(augride maybe-renamed ...) ("clmethoddefs")] [(augment-final maybe-renamed ...) ("clmethoddefs")] [(private id ...) ("clmethoddefs") - @defexamples[#:eval class-eval - (define light% - (class object% - (super-new) - (define on? #t) - (define (toggle) (set! on? (not on?))) - (private toggle) - (define (flick) (toggle)) - (public flick))) - (send (new light%) toggle) + @examples[#:eval class-eval + (eval:no-prompt + (define light% + (class object% + (super-new) + (define on? #t) + (define (toggle) (set! on? (not on?))) + (private toggle) + (define (flick) (toggle)) + (public flick)))) + (eval:error (send (new light%) toggle)) (send (new light%) flick)]] [(abstract id ...) ("clmethoddefs") - @defexamples[#:eval class-eval - (define train% - (class object% - (super-new) - (abstract get-speed) - (init-field [position 0]) - (define/public (move) - (new this% [position (+ position (get-speed))])))) - (define acela% - (class train% - (super-new) - (define/override (get-speed) 241))) - (define talgo-350% - (class train% - (super-new) - (define/override (get-speed) 330))) - (new train%) + @examples[#:eval class-eval + (eval:no-prompt + (define train% + (class object% + (super-new) + (abstract get-speed) + (init-field [position 0]) + (define/public (move) + (new this% [position (+ position (get-speed))]))))) + (eval:no-prompt + (define acela% + (class train% + (super-new) + (define/override (get-speed) 241)))) + (eval:no-prompt + (define talgo-350% + (class train% + (super-new) + (define/override (get-speed) 330)))) + (eval:error (new train%)) (send (new acela%) move)]] [(inherit maybe-renamed ...) ("classinherit") - @defexamples[#:eval class-eval - (define alarm% - (class object% - (super-new) - (define/public (alarm) - (displayln "beeeeeeeep")))) - (define car-alarm% - (class alarm% - (super-new) - (init-field proximity) - (inherit alarm) - (when (< proximity 10) - (alarm)))) + @examples[#:eval class-eval + (eval:no-prompt + (define alarm% + (class object% + (super-new) + (define/public (alarm) + (displayln "beeeeeeeep"))))) + (eval:no-prompt + (define car-alarm% + (class alarm% + (super-new) + (init-field proximity) + (inherit alarm) + (when (< proximity 10) + (alarm))))) (new car-alarm% [proximity 5])]] [(inherit/super maybe-renamed ...) ("classinherit")] [(inherit/inner maybe-renamed ...) ("classinherit")] @@ -1067,21 +1092,22 @@ hidden name (except as a top-level definition). The @racket[interface->method-names] procedure does not expose hidden names. -@defexamples[ +@examples[ #:eval class-eval -(define-values (r o) - (let () - (define-local-member-name m) - (define c% (class object% - (define/public (m) 10) - (super-new))) - (define o (new c%)) +(eval:no-prompt + (define-values (r o) + (let () + (define-local-member-name m) + (define c% (class object% + (define/public (m) 10) + (super-new))) + (define o (new c%)) - (values (send o m) - o))) + (values (send o m) + o)))) r -(send o m) +(eval:error (send o m)) ]} @@ -1121,28 +1147,27 @@ Produces an integer hash code consistent with @racket[member-name-key=?] comparisons, analogous to @racket[equal-hash-code].} -@defexamples[ +@examples[ #:eval class-eval -(define (make-c% key) - (define-member-name m key) - (class object% - (define/public (m) 10) - (super-new))) +(eval:no-prompt + (define (make-c% key) + (define-member-name m key) + (class object% + (define/public (m) 10) + (super-new)))) (send (new (make-c% (member-name-key m))) m) -(send (new (make-c% (member-name-key p))) m) +(eval:error (send (new (make-c% (member-name-key p))) m)) (send (new (make-c% (member-name-key p))) p) -] -@defs+int[ -#:eval class-eval -[(define (fresh-c%) +(eval:no-prompt + (define (fresh-c%) (let ([key (generate-member-key)]) (values (make-c% key) key))) - (define-values (fc% key) (fresh-c%))] + (define-values (fc% key) (fresh-c%))) -(send (new fc%) m) +(eval:error (send (new fc%) m)) (let () (define-member-name p key) (send (new fc%) p)) @@ -1352,15 +1377,16 @@ the last method call, which is expected to be an object. Each This is the functional analogue of @racket[send*]. -@defexamples[#:eval class-eval -(define point% - (class object% - (super-new) - (init-field [x 0] [y 0]) - (define/public (move-x dx) - (new this% [x (+ x dx)])) - (define/public (move-y dy) - (new this% [y (+ y dy)])))) +@examples[#:eval class-eval +(eval:no-prompt + (define point% + (class object% + (super-new) + (init-field [x 0] [y 0]) + (define/public (move-x dx) + (new this% [x (+ x dx)])) + (define/public (move-y dy) + (new this% [y (+ y dy)]))))) (send+ (new point%) (move-x 5) @@ -1802,21 +1828,21 @@ The external contracts are as follows: If only the field name is present, this is equivalent to insisting only that the method is present in the class. - @defexamples[#:eval - class-eval - (define woody% - (class object% - (define/public (draw who) - (format "reach for the sky, ~a" who)) - (super-new))) + @examples[#:eval class-eval + (eval:no-prompt + (define woody% + (class object% + (define/public (draw who) + (format "reach for the sky, ~a" who)) + (super-new))) - (define/contract woody+c% - (class/c [draw (->m symbol? string?)]) - woody%) + (define/contract woody+c% + (class/c [draw (->m symbol? string?)]) + woody%)) (send (new woody%) draw #f) (send (new woody+c%) draw 'zurg) - (send (new woody+c%) draw #f)] + (eval:error (send (new woody+c%) draw #f))] } @item{An external field contract, tagged with @racket[field], describes the behavior of the value contained in that field when accessed from outside @@ -1827,28 +1853,29 @@ The external contracts are as follows: If only the field name is present, this is equivalent to using the contract @racket[any/c] (but it is checked more efficiently). - @defexamples[#:eval - class-eval - (define woody/hat% - (class woody% - (field [hat-location 'uninitialized]) - (define/public (lose-hat) (set! hat-location 'lost)) - (define/public (find-hat) (set! hat-location 'on-head)) - (super-new))) - (define/contract woody/hat+c% - (class/c [draw (->m symbol? string?)] - [lose-hat (->m void?)] - [find-hat (->m void?)] - (field [hat-location (or/c 'on-head 'lost)])) - woody/hat%) + @examples[#:eval class-eval + (eval:no-prompt + (define woody/hat% + (class woody% + (field [hat-location 'uninitialized]) + (define/public (lose-hat) (set! hat-location 'lost)) + (define/public (find-hat) (set! hat-location 'on-head)) + (super-new))) + (define/contract woody/hat+c% + (class/c [draw (->m symbol? string?)] + [lose-hat (->m void?)] + [find-hat (->m void?)] + (field [hat-location (or/c 'on-head 'lost)])) + woody/hat%)) (get-field hat-location (new woody/hat%)) (let ([woody (new woody/hat+c%)]) (send woody lose-hat) (get-field hat-location woody)) - (get-field hat-location (new woody/hat+c%)) - (let ([woody (new woody/hat+c%)]) - (set-field! hat-location woody 'under-the-dresser))] + (eval:error (get-field hat-location (new woody/hat+c%))) + (eval:error + (let ([woody (new woody/hat+c%)]) + (set-field! hat-location woody 'under-the-dresser)))] } @item{An initialization argument contract, tagged with @racket[init], @@ -1861,28 +1888,29 @@ The external contracts are as follows: If only the initialization argument name is present, this is equivalent to using the contract @racket[any/c] (but it is checked more efficiently). - @defexamples[#:eval - class-eval - (define woody/init-hat% - (class woody% - (init init-hat-location) - (field [hat-location init-hat-location]) - (define/public (lose-hat) (set! hat-location 'lost)) - (define/public (find-hat) (set! hat-location 'on-head)) - (super-new))) - (define/contract woody/init-hat+c% - (class/c [draw (->m symbol? string?)] - [lose-hat (->m void?)] - [find-hat (->m void?)] - (init [init-hat-location (or/c 'on-head 'lost)]) - (field [hat-location (or/c 'on-head 'lost)])) - woody/init-hat%) + @examples[#:eval class-eval + (eval:no-prompt + (define woody/init-hat% + (class woody% + (init init-hat-location) + (field [hat-location init-hat-location]) + (define/public (lose-hat) (set! hat-location 'lost)) + (define/public (find-hat) (set! hat-location 'on-head)) + (super-new))) + (define/contract woody/init-hat+c% + (class/c [draw (->m symbol? string?)] + [lose-hat (->m void?)] + [find-hat (->m void?)] + (init [init-hat-location (or/c 'on-head 'lost)]) + (field [hat-location (or/c 'on-head 'lost)])) + woody/init-hat%)) (get-field hat-location (new woody/init-hat+c% [init-hat-location 'lost])) - (get-field hat-location - (new woody/init-hat+c% - [init-hat-location 'slinkys-mouth]))] + (eval:error + (get-field hat-location + (new woody/init-hat+c% + [init-hat-location 'slinkys-mouth])))] } @item{The contracts listed in an @racket[init-field] section are @@ -1906,18 +1934,19 @@ As with the external contracts, when a method or field name is specified contracted class's method implementation is no longer the entry point for dynamic dispatch. - @defexamples[#:eval - class-eval + @examples[#:eval class-eval (new (class woody+c% (inherit draw) (super-new) (printf "woody sez: “~a”\n" (draw "evil dr porkchop")))) - (define/contract woody+c-inherit% - (class/c (inherit [draw (->m symbol? string?)])) - woody+c%) - (new (class woody+c-inherit% - (inherit draw) - (printf "woody sez: ~a\n" (draw "evil dr porkchop"))))] + (eval:no-prompt + (define/contract woody+c-inherit% + (class/c (inherit [draw (->m symbol? string?)])) + woody+c%)) + (eval:error + (new (class woody+c-inherit% + (inherit draw) + (printf "woody sez: ~a\n" (draw "evil dr porkchop")))))] } @item{A method contract tagged with @racket[super] describes the behavior of @@ -1932,18 +1961,18 @@ As with the external contracts, when a method or field name is specified contract the controls how the @racket[super] methods must be invoked. - @defexamples[#:eval - class-eval - (define/contract woody2+c% - (class/c (super [draw (->m symbol? string?)])) - (class woody% - (define/override draw - (case-lambda - [(a) (super draw a)] - [(a b) (string-append (super draw a) - " and " - (super draw b))])) - (super-new))) + @examples[#:eval class-eval + (eval:no-prompt + (define/contract woody2+c% + (class/c (super [draw (->m symbol? string?)])) + (class woody% + (define/override draw + (case-lambda + [(a) (super draw a)] + [(a b) (string-append (super draw a) + " and " + (super draw b))])) + (super-new)))) (send (new woody2+c%) draw 'evil-dr-porkchop 'zurg) (send (new woody2+c%) draw "evil dr porkchop" "zurg")] @@ -1971,27 +2000,28 @@ As with the external contracts, when a method or field name is specified add a contract to make sure that overriding @racket[draw] doesn't break @racket[draw2]. - @defexamples[#:eval - class-eval - (define/contract woody2+override/c% - (class/c (override [draw (->m symbol? string?)])) - (class woody+c% - (inherit draw) - (define/public (draw2 a b) - (string-append (draw a) - " and " - (draw b))) - (super-new))) + @examples[#:eval class-eval + (eval:no-prompt + (define/contract woody2+override/c% + (class/c (override [draw (->m symbol? string?)])) + (class woody+c% + (inherit draw) + (define/public (draw2 a b) + (string-append (draw a) + " and " + (draw b))) + (super-new))) - (define woody2+broken-draw - (class woody2+override/c% - (define/override (draw x) - 'not-a-string) - (super-new))) - - (send (new woody2+broken-draw) draw2 - 'evil-dr-porkchop - 'zurg)] + (define woody2+broken-draw + (class woody2+override/c% + (define/override (draw x) + 'not-a-string) + (super-new)))) + + (eval:error + (send (new woody2+broken-draw) draw2 + 'evil-dr-porkchop + 'zurg))] } @@ -2390,7 +2420,7 @@ A @racket[print] request is directed to @racket[custom-write].} Returns @racket[#t] if @racket[v] is an object, @racket[#f] otherwise. -@defexamples[#:eval class-eval +@examples[#:eval class-eval (object? (new object%)) (object? object%) (object? "clam chowder") @@ -2401,7 +2431,7 @@ Returns @racket[#t] if @racket[v] is an object, @racket[#f] otherwise. Returns @racket[#t] if @racket[v] is a class, @racket[#f] otherwise. -@defexamples[#:eval class-eval +@examples[#:eval class-eval (class? object%) (class? (class object% (super-new))) (class? (new object%)) @@ -2413,7 +2443,7 @@ Returns @racket[#t] if @racket[v] is a class, @racket[#f] otherwise. Returns @racket[#t] if @racket[v] is an interface, @racket[#f] otherwise. -@defexamples[#:eval class-eval +@examples[#:eval class-eval (interface? (interface () empty cons first rest)) (interface? object%) (interface? "gazpacho") @@ -2424,7 +2454,7 @@ Returns @racket[#t] if @racket[v] is an interface, @racket[#f] otherwise. Returns @racket[#t] if @racket[v] is a @tech{generic}, @racket[#f] otherwise. -@defexamples[#:eval class-eval +@examples[#:eval class-eval (define c% (class object% (super-new) @@ -2448,7 +2478,7 @@ This procedure is similar in spirit to @racket[eq?] but also works properly with contracts (and has a stronger guarantee). -@defexamples[#:eval class-ctc-eval +@examples[#:eval class-ctc-eval (define obj-1 (new object%)) (define obj-2 (new object%)) (define/contract obj-3 (object/c) obj-1) @@ -2468,7 +2498,7 @@ This procedure is similar in spirit to Like @racket[object=?], but accepts @racket[#f] for either argument and returns @racket[#t] if both arguments are @racket[#f]. -@defexamples[#:eval class-ctc-eval +@examples[#:eval class-ctc-eval (object-or-false=? #f (new object%)) (object-or-false=? (new object%) #f) (object-or-false=? #f #f) @@ -2482,7 +2512,7 @@ returns @racket[#t] if both arguments are @racket[#f]. Returns a vector representing @racket[object] that shows its inspectable fields, analogous to @racket[struct->vector]. -@defexamples[#:eval class-eval +@examples[#:eval class-eval (object->vector (new object%)) (object->vector (new (class object% (super-new) @@ -2494,7 +2524,7 @@ inspectable fields, analogous to @racket[struct->vector]. Returns the interface implicitly defined by @racket[class]. -@defexamples[#:eval class-eval +@examples[#:eval class-eval (class->interface object%) ]} @@ -2504,7 +2534,7 @@ Returns the interface implicitly defined by @racket[class]. Returns the interface implicitly defined by the class of @racket[object]. -@defexamples[#:eval class-eval +@examples[#:eval class-eval (object-interface (new object%)) ]} @@ -2515,7 +2545,7 @@ Returns @racket[#t] if @racket[v] is an instance of a class @racket[type] or a class that implements an interface @racket[type], @racket[#f] otherwise. -@defexamples[#:eval class-eval +@examples[#:eval class-eval (define point<%> (interface () get-x get-y)) (define 2d-point% (class* object% (point<%>) @@ -2536,7 +2566,7 @@ Returns @racket[#t] if @racket[v] is an instance of a class Returns @racket[#t] if @racket[v] is a class derived from (or equal to) @racket[cls], @racket[#f] otherwise. -@defexamples[#:eval class-eval +@examples[#:eval class-eval (subclass? (class object% (super-new)) object%) (subclass? object% (class object% (super-new))) (subclass? object% object%) @@ -2548,7 +2578,7 @@ to) @racket[cls], @racket[#f] otherwise. Returns @racket[#t] if @racket[v] is a class that implements @racket[intf], @racket[#f] otherwise. -@defexamples[#:eval class-eval +@examples[#:eval class-eval (define i<%> (interface () go)) (define c% (class* object% (i<%>) @@ -2565,7 +2595,7 @@ Returns @racket[#t] if @racket[v] is a class that implements Returns @racket[#t] if @racket[v] is an interface that extends @racket[intf], @racket[#f] otherwise. -@defexamples[#:eval class-eval +@examples[#:eval class-eval (define point<%> (interface () get-x get-y)) (define colored-point<%> (interface (point<%>) color)) @@ -2581,7 +2611,7 @@ Returns @racket[#t] if @racket[intf] (or any of its ancestor interfaces) includes a member with the name @racket[sym], @racket[#f] otherwise. -@defexamples[#:eval class-eval +@examples[#:eval class-eval (define i<%> (interface () get-x get-y)) (method-in-interface? 'get-x i<%>) (method-in-interface? 'get-z i<%>) @@ -2595,7 +2625,7 @@ including methods inherited from superinterfaces, but not including methods whose names are local (i.e., declared with @racket[define-local-member-name]). -@defexamples[#:eval class-eval +@examples[#:eval class-eval (define i<%> (interface () get-x get-y)) (interface->method-names i<%>) ]} @@ -2607,7 +2637,7 @@ methods whose names are local (i.e., declared with Returns @racket[#t] if @racket[object] has a method named @racket[sym] that accepts @racket[cnt] arguments, @racket[#f] otherwise. -@defexamples[#:eval class-eval +@examples[#:eval class-eval (define c% (class object% (super-new) @@ -2628,7 +2658,7 @@ Returns a list of all of the names of the fields bound in not including fields whose names are local (i.e., declared with @racket[define-local-member-name]). -@defexamples[#:eval class-eval +@examples[#:eval class-eval (field-names (new object%)) (field-names (new (class object% (super-new) (field [x 0] [y 0])))) ]} diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index 0b29fdddf8..93888ce6c7 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -440,13 +440,14 @@ Returns a contract that recognizes a list whose every element matches the contract @racket[c]. Beware that when this contract is applied to a value, the result is not necessarily @racket[eq?] to the input. -@examples[#:eval (contract-eval) +@examples[#:eval (contract-eval) #:once (define/contract some-numbers (listof number?) (list 1 2 3)) - (define/contract just-one-number - (listof number?) - 11)] + (eval:error + (define/contract just-one-number + (listof number?) + 11))] } @@ -457,14 +458,15 @@ Returns a contract that recognizes non-empty lists whose elements match the contract @racket[c]. Beware that when this contract is applied to a value, the result is not necessarily @racket[eq?] to the input. -@examples[#:eval (contract-eval) +@examples[#:eval (contract-eval) #:once (define/contract some-numbers (non-empty-listof number?) (list 1 2 3)) - (define/contract not-enough-numbers - (non-empty-listof number?) - (list))] + (eval:error + (define/contract not-enough-numbers + (non-empty-listof number?) + (list)))] } @defproc[(list*of [c contract?]) contract?]{ @@ -476,14 +478,15 @@ its @racket[cdr] position is expected to be @racket[(list*of c)]. Otherwise, it is expected to match @racket[c]. Beware that when this contract is applied to a value, the result is not necessarily @racket[eq?] to the input. -@examples[#:eval (contract-eval) +@examples[#:eval (contract-eval) #:once (define/contract improper-numbers (list*of number?) (cons 1 (cons 2 3))) - (define/contract not-improper-numbers - (list*of number?) - (list 1 2 3))] + (eval:error + (define/contract not-improper-numbers + (list*of number?) + (list 1 2 3)))] @history[#:added "6.1.1.1"] } @@ -499,14 +502,15 @@ necessarily @racket[eq?] to the input. If the @racket[cdr-c] contract is a @racket[list-contract?], then @racket[cons/c] returns a @racket[list-contract?]. -@examples[#:eval (contract-eval) +@examples[#:eval (contract-eval) #:once (define/contract a-pair-of-numbers (cons/c number? number?) (cons 1 2)) - (define/contract not-a-pair-of-numbers - (cons/c number? number?) - (cons #f #t))] + (eval:error + (define/contract not-a-pair-of-numbers + (cons/c number? number?) + (cons #f #t)))] @history[#:changed "6.0.1.13" @list{Added the @racket[list-contract?] propagating behavior.}] } @@ -525,14 +529,15 @@ In the first case, the contract on the @racket[cdr-id] portion of the contract may depend on the value in the @racket[car-id] portion of the pair and in the second case, the reverse is true. -@examples[#:eval (contract-eval) +@examples[#:eval (contract-eval) #:once (define/contract an-ordered-pair-of-reals (cons/dc [hd real?] [tl (hd) (>=/c hd)]) (cons 1 2)) - (define/contract not-an-ordered-pair-of-reals - (cons/dc [hd real?] [tl (hd) (>=/c hd)]) - (cons 2 1))] + (eval:error + (define/contract not-an-ordered-pair-of-reals + (cons/dc [hd real?] [tl (hd) (>=/c hd)]) + (cons 2 1)))] @history[#:added "6.1.1.6"] } @@ -653,7 +658,7 @@ Produces a contract on parameters whose values must match @racket[_out]. When the value in the contracted parameter is set, it must match @racket[_in]. -@examples[#:eval (contract-eval) +@examples[#:eval (contract-eval) #:once (define/contract current-snack (parameter/c string?) (make-parameter "potato-chip")) @@ -663,9 +668,10 @@ is set, it must match @racket[_in]. (parameter/c string? baked/c) (make-parameter "turkey" (λ (s) (string-append "roasted " s)))) -(current-snack 'not-a-snack) -(parameterize ([current-dinner "tofurkey"]) - (current-dinner)) +(eval:error (current-snack 'not-a-snack)) +(eval:error + (parameterize ([current-dinner "tofurkey"]) + (current-dinner))) ]} @@ -683,18 +689,18 @@ Produces a contract for procedures that accept @racket[n] argument Produces a contract that recognizes @racket[hash] tables with keys and values as specified by the @racket[key] and @racket[val] arguments. -@examples[#:eval - (contract-eval) +@examples[#:eval (contract-eval) #:once (define/contract good-hash (hash/c integer? boolean?) (hash 1 #t 2 #f 3 #t)) - (define/contract bad-hash - (hash/c integer? boolean?) - (hash 1 "elephant" - 2 "monkey" - 3 "manatee"))] + (eval:error + (define/contract bad-hash + (hash/c integer? boolean?) + (hash 1 "elephant" + 2 "monkey" + 3 "manatee")))] There are a number of technicalities that control how @racket[hash/c] contracts behave. @@ -703,17 +709,15 @@ behave. a flat contract, and the @racket[key] and @racket[val] arguments must also be flat contracts. -@examples[#:eval - (contract-eval) +@examples[#:eval (contract-eval) #:once (flat-contract? (hash/c integer? boolean?)) (flat-contract? (hash/c integer? boolean? #:flat? #t)) - (hash/c integer? (-> integer? integer?) #:flat? #t)] + (eval:error (hash/c integer? (-> integer? integer?) #:flat? #t))] Such flat contracts will be unsound if applied to mutable hash tables, as they will not check future mutations to the hash table. -@examples[#:eval - (contract-eval) +@examples[#:eval (contract-eval) #:once (define original-h (make-hasheq)) (define/contract ctc-h (hash/c integer? boolean? #:flat? #t) @@ -725,15 +729,13 @@ If the @racket[immutable] argument is @racket[#t] and the @racket[key] and @racket[val] arguments are @racket[flat-contract?]s, the result will be a @racket[flat-contract?]. -@examples[#:eval - (contract-eval) +@examples[#:eval (contract-eval) #:once (flat-contract? (hash/c integer? boolean? #:immutable #t))] If either the domain or the range is a @racket[chaperone-contract?], then the result will be a @racket[chaperone-contract?]. -@examples[#:eval - (contract-eval) +@examples[#:eval (contract-eval) #:once (flat-contract? (hash/c (-> integer? integer?) boolean? #:immutable #t)) (chaperone-contract? (hash/c (-> integer? integer?) boolean? @@ -744,11 +746,11 @@ be a @racket[chaperone-contract?]. If the @racket[key] argument is a @racket[chaperone-contract?] but not a @racket[flat-contract?], then the resulting contract can be applied only to @racket[equal?]-based hash tables. -@examples[#:eval - (contract-eval) - (define/contract h - (hash/c (-> integer? integer?) any/c) - (make-hasheq))] +@examples[#:eval (contract-eval) #:once + (eval:error + (define/contract h + (hash/c (-> integer? integer?) any/c) + (make-hasheq)))] Also, when such a @racket[hash/c] contract is applied to a hash table, the result is not @racket[eq?] to the input. The result of applying the contract will be a copy for immutable hash tables, @@ -777,16 +779,16 @@ for mutable hash tables. and it may also be @racket['impersonator], in which case they may be any @racket[contract?]s. The default is @racket['chaperone]. - @examples[#:eval - (contract-eval) + @examples[#:eval (contract-eval) #:once (define/contract h (hash/dc [k real?] [v (k) (>=/c k)]) (hash 1 3 2 4)) - (define/contract h - (hash/dc [k real?] [v (k) (>=/c k)]) - (hash 3 1 - 4 2))] + (eval:error + (define/contract h + (hash/dc [k real?] [v (k) (>=/c k)]) + (hash 3 1 + 4 2)))] } @@ -801,12 +803,12 @@ is a chaperone contract. Otherwise, the resulting contract is an impersonator contract. When a channel contract is applied to a channel, the resulting channel is not @racket[eq?] to the input. -@examples[#:eval (contract-eval) +@examples[#:eval (contract-eval) #:once (define/contract chan (channel/c string?) (make-channel)) (thread (λ () (channel-get chan))) - (channel-put chan 'not-a-string) + (eval:error (channel-put chan 'not-a-string)) ]} @@ -832,19 +834,20 @@ If @racket[maybe-call/cc] is provided, then the provided contracts are used to check the return values from a continuation captured with @racket[call-with-current-continuation]. -@examples[#:eval (contract-eval) +@examples[#:eval (contract-eval) #:once (define/contract tag (prompt-tag/c (-> number? string?)) (make-continuation-prompt-tag)) - (call-with-continuation-prompt - (lambda () - (number->string - (call-with-composable-continuation - (lambda (k) - (abort-current-continuation tag k))))) - tag - (lambda (k) (k "not a number"))) + (eval:error + (call-with-continuation-prompt + (lambda () + (number->string + (call-with-composable-continuation + (lambda (k) + (abort-current-continuation tag k))))) + tag + (lambda (k) (k "not a number")))) ] } @@ -858,17 +861,18 @@ If the argument @racket[contract] is a chaperone contract, the resulting contract will also be a @tech{chaperone} contract. Otherwise, the contract is an @tech{impersonator} contract. -@examples[#:eval (contract-eval) +@examples[#:eval (contract-eval) #:once (define/contract mark-key (continuation-mark-key/c (-> symbol? (listof symbol?))) (make-continuation-mark-key)) - (with-continuation-mark - mark-key - (lambda (s) (append s '(truffle fudge ganache))) - (let ([mark-value (continuation-mark-set-first - (current-continuation-marks) mark-key)]) - (mark-value "chocolate-bar"))) + (eval:error + (with-continuation-mark + mark-key + (lambda (s) (append s '(truffle fudge ganache))) + (let ([mark-value (continuation-mark-set-first + (current-continuation-marks) mark-key)]) + (mark-value "chocolate-bar")))) ] } @@ -880,7 +884,7 @@ Returns a contract that recognizes @tech{synchronizable event}s whose The resulting contract is always a @tech{chaperone} contract and its arguments must all be chaperone contracts. -@defexamples[#:eval (contract-eval) +@examples[#:eval (contract-eval) #:once (define/contract my-evt (evt/c evt?) always-evt) @@ -888,7 +892,7 @@ arguments must all be chaperone contracts. (evt/c number? number?) (alarm-evt (+ (current-inexact-milliseconds) 50))) (sync my-evt) - (sync failing-evt) + (eval:error (sync failing-evt)) ] } @@ -1372,14 +1376,14 @@ by some @racket[x] in positive position with respect to @racket[parametric->/c]) are checked for the appropriate wrapper. If they have it, they are unwrapped; if they do not, a contract violation is signaled. -@examples[#:eval (contract-eval) +@examples[#:eval (contract-eval) #:once (define/contract (check x y) (parametric->/c [X] (boolean? X . -> . X)) (if (or (not x) (equal? y 'surprise)) 'invalid y)) (check #t 'ok) -(check #f 'ignored) +(eval:error (check #f 'ignored)) (check #t 'surprise) ] } @@ -1589,8 +1593,7 @@ the export. should be reported in terms of the public module instead of the private one. - @examples[#:eval - (contract-eval) + @examples[#:eval (contract-eval) #:once (module private-implementation racket/base (require racket/contract) (define (recip x) (/ 1 x)) @@ -1603,7 +1606,7 @@ the export. (provide (recontract-out recip))) (require 'public) - (recip +nan.0)] + (eval:error (recip +nan.0))] Replacing the use of @racket[recontract-out] with just @racket[recip] would result in a contract violation blaming @@ -1671,7 +1674,7 @@ For the definition of @racket[free-var-list], see @racket[with-contract]. (-> real? real?) (* 660 fr)) (code:comment "a contract violation expected here:") - (furlongs->feet "not a furlong") + (eval:error (furlongs->feet "not a furlong")) ] The @racket[define/contract] form treats the individual definition as @@ -1682,7 +1685,7 @@ positions of the contract. Since the contract boundary is between the definition and the surrounding context, references to @racket[id] inside the @racket[define/contract] form are not checked. -@examples[#:eval (contract-eval) +@examples[#:eval (contract-eval) #:once (code:comment "an unsual predicate that prints when called") (define (printing-int? x) (displayln "I was called") @@ -1692,7 +1695,7 @@ between the definition and the surrounding context, references to (if (zero? n) 1 (* n (fact (sub1 n))))) - (fact 5) (code:comment "only prints twice, not for each recursive call") + (code:line (fact 5) (code:comment "only prints twice, not for each recursive call")) ] If a free-var-list is given, then any uses of the free variables @@ -1700,7 +1703,7 @@ inside the @racket[body] will be protected with contracts that blame the context of the @racket[define/contract] form for the positive positions and the @racket[define/contract] form for the negative ones. -@examples[#:eval (contract-eval) +@examples[#:eval (contract-eval) #:once (define (integer->binary-string n) (number->string n 2)) (define/contract (numbers->strings lst) @@ -1708,7 +1711,7 @@ positions and the @racket[define/contract] form for the negative ones. #:freevar integer->binary-string (-> exact-integer? string?) (code:comment "mistake, lst might contain inexact numbers") (map integer->binary-string lst)) - (numbers->strings '(4.0 3.3 5.8)) + (eval:error (numbers->strings '(4.0 3.3 5.8))) ]} @defform*[[(define-struct/contract struct-id ([field contract-expr] ...) @@ -1725,15 +1728,15 @@ The @racket[define-struct/contract] form only allows a subset of the @racket[#:auto-value], @racket[#:omit-define-syntaxes], @racket[#:property] and @racket[#:omit-define-values]. -@examples[#:eval (contract-eval) +@examples[#:eval (contract-eval) #:once (define-struct/contract fish ([color number?])) (make-fish 5) -(make-fish #f) +(eval:error (make-fish #f)) (define-struct/contract (salmon fish) ([ocean symbol?])) (make-salmon 5 'atlantic) -(make-salmon 5 #f) -(make-salmon #f 'pacific) +(eval:error (make-salmon 5 #f)) +(eval:error (make-salmon #f 'pacific)) ]} @defform[(invariant-assertion invariant-expr expr)]{ @@ -1750,7 +1753,7 @@ The @racket[define-struct/contract] form only allows a subset of the recursive calls, when an invariant is used on the right-hand side of a definition: - @examples[#:eval + @examples[#:eval furlongs->feet-eval (define furlongss->feets (invariant-assertion @@ -1766,7 +1769,7 @@ The @racket[define-struct/contract] form only allows a subset of the (furlongss->feets (list 1 2 3)) - (furlongss->feets (list 1 327 3))] + (eval:error (furlongss->feets (list 1 327 3)))] @history[#:added "6.0.1.11"] @@ -1810,8 +1813,7 @@ The @racket[define-struct/contract] form only allows a subset of the it can be any of the things that the third argument to @racket[datum->syntax] can be. - @examples[#:eval - (contract-eval) + @examples[#:eval (contract-eval) #:once (module server racket/base (require racket/contract/base) (define (f x) #f) @@ -1823,8 +1825,8 @@ The @racket[define-struct/contract] form only allows a subset of the (define (servers-fault) (g 1)) (provide servers-fault clients-fault)) (require 'client) - (clients-fault) - (servers-fault)] + (eval:error (clients-fault)) + (eval:error (servers-fault))] } @@ -1856,10 +1858,9 @@ produces @racket[#f], no name is printed. Otherwise, it is also formatted as by @racket[display]. More precisely, the @racket[value-name-expr] ends up in the @racket[blame-name] field of the blame record, which is used as the first portion of the error message. -@examples[#:eval - (contract-eval) - (contract integer? #f 'pos 'neg 'timothy #f) - (contract integer? #f 'pos 'neg #f #f)] +@examples[#:eval (contract-eval) #:once + (eval:error (contract integer? #f 'pos 'neg 'timothy #f)) + (eval:error (contract integer? #f 'pos 'neg #f #f))] If specified, @racket[source-location-expr] indicates the source location reported by contract violations. The expression must produce a @racket[srcloc] @@ -2016,11 +2017,11 @@ was passed as the second argument to @racket[contract-stronger?]. The @racket[is-list-contract?] argument is used by the @racket[list-contract?] predicate to determine if this is a contract that accepts only @racket[list?] values. -@defexamples[#:eval (contract-eval) +@examples[#:eval (contract-eval) #:once (define int/c (make-flat-contract #:name 'int/c #:first-order integer?)) (contract int/c 1 'positive 'negative) -(contract int/c "not one" 'positive 'negative) +(eval:error (contract int/c "not one" 'positive 'negative)) (int/c 1) (int/c "not one") (define int->int/c @@ -2039,12 +2040,12 @@ to determine if this is a contract that accepts only @racket[list?] values. b f '(expected "a function of one argument" given: "~e") f))))))) -(contract int->int/c "not fun" 'positive 'negative) +(eval:error (contract int->int/c "not fun" 'positive 'negative)) (define halve (contract int->int/c (λ (x) (/ x 2)) 'positive 'negative)) (halve 2) -(halve 1/2) -(halve 1) +(eval:error (halve 1/2)) +(eval:error (halve 1)) ] @history[#:changed "6.0.1.13" @list{Added the @racket[#:list-contract?] argument.}] @@ -2154,12 +2155,12 @@ contracts. The error messages assume that the function named by or @racket["a conjunct of"] (in the case of an @racket[and/c] contract). For example, consider this contract violation: - @interaction[#:eval (contract-eval) + @examples[#:label #f #:eval (contract-eval) #:once (define/contract f (list/c (-> integer? integer?)) (list (λ (x) x))) -((car f) #f) +(eval:error ((car f) #f)) ] It shows that the portion of the contract being violated is the first occurrence of @racket[integer?], because the @racket[->] and @@ -2293,7 +2294,7 @@ returns a string that is put into the contract error message. Note that the value is often already included in the message that indicates the violation. -@defexamples[#:eval (contract-eval) +@examples[#:eval (contract-eval) #:once (define (show-blame-error blame value message) (string-append "Contract Violation!\n" @@ -2309,8 +2310,8 @@ the message that indicates the violation. (-> integer? integer?) (/ x 2)) (f 2) -(f 1) -(f 1/2) +(eval:error (f 1)) +(eval:error (f 1/2)) ] } @@ -2697,7 +2698,7 @@ are below): This function is conservative, so it may return @racket[#f] when @racket[x] does, in fact, accept fewer values. -@examples[#:eval (contract-eval) +@examples[#:eval (contract-eval) #:once (contract-stronger? integer? integer?) (contract-stronger? (between/c 25 75) (between/c 0 100)) (contract-stronger? (between/c 0 100) (between/c 25 75)) @@ -2851,13 +2852,15 @@ expression, then @racket[opt/c] raises an error using @racket[id] as the name of the primitive, instead of using the name @racket[opt/c]. -@examples[#:eval (contract-eval) - (define/contract (f x) - (opt/c '(not-a-contract)) - x) - (define/contract (f x) - (opt/c '(not-a-contract) #:error-name define/contract) - x)] +@examples[#:eval (contract-eval) #:once + (eval:error + (define/contract (f x) + (opt/c '(not-a-contract)) + x)) + (eval:error + (define/contract (f x) + (opt/c '(not-a-contract) #:error-name define/contract) + x))] } diff --git a/pkgs/racket-doc/scribblings/reference/custom-ports.scrbl b/pkgs/racket-doc/scribblings/reference/custom-ports.scrbl index 4cc96f8846..ac690a17ba 100644 --- a/pkgs/racket-doc/scribblings/reference/custom-ports.scrbl +++ b/pkgs/racket-doc/scribblings/reference/custom-ports.scrbl @@ -455,7 +455,7 @@ The arguments implement the port as follows: ;; The port doesn't supply procedures to implement progress events: (port-provides-progress-evts? infinite-ones) -(port-progress-evt infinite-ones) +(eval:error (port-progress-evt infinite-ones)) ;; Non-byte port results: (define infinite-voids @@ -464,7 +464,7 @@ The arguments implement the port as follows: (lambda (s) (lambda args 'void)) (lambda (skip s evt) (lambda args 'void)) void)) -(read-char infinite-voids) +(eval:error (read-char infinite-voids)) (read-char-or-special infinite-voids) ;; This port produces 0, 1, 2, 0, 1, 2, etc., but it is not diff --git a/pkgs/racket-doc/scribblings/reference/custom-write.scrbl b/pkgs/racket-doc/scribblings/reference/custom-write.scrbl index 30bba2b84c..ed0d66af3d 100644 --- a/pkgs/racket-doc/scribblings/reference/custom-write.scrbl +++ b/pkgs/racket-doc/scribblings/reference/custom-write.scrbl @@ -47,25 +47,27 @@ angle brackets in @racket[write] and @racket[print] mode and no brackets in @racket[display] mode. Elements of the tuple are printed recursively, so that graph and cycle structure can be represented. -@defexamples[ -(define (tuple-print tuple port mode) - (when mode (write-string "<" port)) - (let ([l (tuple-ref tuple)] - [recur (case mode - [(#t) write] - [(#f) display] - [else (lambda (p port) (print p port mode))])]) - (unless (zero? (vector-length l)) - (recur (vector-ref l 0) port) - (for-each (lambda (e) - (write-string ", " port) - (recur e port)) - (cdr (vector->list l))))) - (when mode (write-string ">" port))) +@examples[ +(eval:no-prompt + (define (tuple-print tuple port mode) + (when mode (write-string "<" port)) + (let ([l (tuple-ref tuple)] + [recur (case mode + [(#t) write] + [(#f) display] + [else (lambda (p port) (print p port mode))])]) + (unless (zero? (vector-length l)) + (recur (vector-ref l 0) port) + (for-each (lambda (e) + (write-string ", " port) + (recur e port)) + (cdr (vector->list l))))) + (when mode (write-string ">" port)))) -(struct tuple (ref) - #:methods gen:custom-write - [(define write-proc tuple-print)]) +(eval:no-prompt + (struct tuple (ref) + #:methods gen:custom-write + [(define write-proc tuple-print)])) (display (tuple #(1 2 "a"))) diff --git a/pkgs/racket-doc/scribblings/reference/define-struct.scrbl b/pkgs/racket-doc/scribblings/reference/define-struct.scrbl index 967813a6f4..3ce4bc3892 100644 --- a/pkgs/racket-doc/scribblings/reference/define-struct.scrbl +++ b/pkgs/racket-doc/scribblings/reference/define-struct.scrbl @@ -3,8 +3,8 @@ racket/generic)) @(define posn-eval (make-base-eval)) -@(interaction-eval #:eval posn-eval - (require racket/match racket/stream (for-syntax racket/base))) +@examples[#:hidden #:eval posn-eval + (require racket/match racket/stream (for-syntax racket/base))] @title[#:tag "define-struct"]{Defining Structure Types: @racket[struct]} @@ -141,7 +141,7 @@ multiple times, attaches a property value to the structure type; see (unless (and (real? temp) (>= temp -273.15)) (error "not a valid temperature")) temp)) - (celsius -275) + (eval:error (celsius -275)) ] @margin-note{Use the @racket[prop:procedure] property to implement an @@ -195,7 +195,7 @@ name, as do the various procedures that are bound by @racket[struct]. @examples[#:eval posn-eval (struct circle (radius) #:reflection-name ') (circle 15) - (circle-radius "bad") + (eval:error (circle-radius "bad")) ] If @racket[#:methods gen:name method-defs] is provided, then @@ -225,11 +225,12 @@ supplied, then the @racket[struct] form is equivalent to @examples[#:eval posn-eval (struct square (side) #:omit-define-syntaxes) - (match (square 5) - (code:comment "fails to match because syntax is omitted") - [(struct square x) x]) + (eval:error + (match (square 5) + (code:comment "fails to match because syntax is omitted") + [(struct square x) x])) (struct ellipse (width height) #:omit-define-values) - ellipse-width + (eval:error ellipse-width) ] If @racket[#:auto] is supplied as a @racket[field-option], then the @@ -247,20 +248,20 @@ error is reported. If any @racket[field-option] or @racket[struct-option] keyword is repeated, other than @racket[#:property], a syntax error is reported. -@defexamples[ +@examples[ #:eval posn-eval -(struct posn (x y [z #:auto]) - #:auto-value 0 - #:transparent) +(eval:no-prompt + (struct posn (x y [z #:auto #:mutable]) + #:auto-value 0 + #:transparent)) (posn 1 2) (posn? (posn 1 2)) (posn-y (posn 1 2)) -] +(posn-z (posn 1 2)) -@defs+int[ -#:eval posn-eval -[(struct color-posn posn (hue) #:mutable) - (define cp (color-posn 1 2 "blue"))] +(eval:no-prompt + (struct color-posn posn (hue) #:mutable) + (define cp (color-posn 1 2 "blue"))) (color-posn-hue cp) cp (set-posn-z! cp 3) @@ -280,11 +281,12 @@ expression is an exact, non-negative integer that corresponds to the position within the structure declaration of the field named by @racket[field-id]. -@defexamples[ +@examples[ #:eval posn-eval -(struct mood-procedure (base rating) - #:property prop:procedure (struct-field-index base)) -(define happy+ (mood-procedure add1 10)) +(eval:no-prompt + (struct mood-procedure (base rating) + #:property prop:procedure (struct-field-index base)) + (define happy+ (mood-procedure add1 10))) (happy+ 2) (mood-procedure-rating happy+) ]} @@ -305,11 +307,12 @@ provided. This form is provided for backwards compatibility; @racket[struct] is preferred. -@defexamples[ +@examples[ #:eval posn-eval -(define-struct posn (x y [z #:auto]) - #:auto-value 0 - #:transparent) +(eval:no-prompt + (define-struct posn (x y [z #:auto]) + #:auto-value 0 + #:transparent)) (make-posn 1 2) (posn? (make-posn 1 2)) (posn-y (make-posn 1 2)) @@ -326,20 +329,21 @@ the sub-form for error reporting is that it starts with @racket[id]. The @racket[define-struct/derived] form is intended for use by macros that expand to @racket[define-struct]. -@defexamples[ +@examples[ #:eval posn-eval -(define-syntax (define-xy-struct stx) - (syntax-case stx () - [(ds name . rest) - (with-syntax ([orig stx]) - #'(define-struct/derived orig name (x y) . rest))])) +(eval:no-prompt + (define-syntax (define-xy-struct stx) + (syntax-case stx () + [(ds name . rest) + (with-syntax ([orig stx]) + #'(define-struct/derived orig name (x y) . rest))]))) (define-xy-struct posn) (posn-x (make-posn 1 2)) (define-xy-struct posn #:mutable) (set-posn-x! (make-posn 1 2) 0) (code:comment "this next line will cause an error due to a bad keyword") -(define-xy-struct posn #:bad-option) +(eval:error (define-xy-struct posn #:bad-option)) ]} @; ---------------------------------------- diff --git a/pkgs/racket-doc/scribblings/reference/dicts.scrbl b/pkgs/racket-doc/scribblings/reference/dicts.scrbl index 97a7fb4103..28345f2bc2 100644 --- a/pkgs/racket-doc/scribblings/reference/dicts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/dicts.scrbl @@ -1,8 +1,8 @@ #lang scribble/doc -@(require "mz.rkt" scribble/eval (for-label racket/generic)) +@(require "mz.rkt" (for-label racket/generic)) @(define dict-eval (make-base-eval)) -@(interaction-eval #:eval dict-eval (require racket/dict racket/generic)) +@examples[#:hidden #:eval dict-eval (require racket/dict racket/generic)] @title[#:tag "dicts"]{Dictionaries} @@ -200,12 +200,12 @@ result: @examples[ #:eval dict-eval (dict-ref #hash((a . "apple") (b . "beer")) 'a) -(dict-ref #hash((a . "apple") (b . "beer")) 'c) +(eval:error (dict-ref #hash((a . "apple") (b . "beer")) 'c)) (dict-ref #hash((a . "apple") (b . "beer")) 'c #f) (dict-ref '((a . "apple") (b . "banana")) 'b) (dict-ref #("apple" "banana") 1) (dict-ref #("apple" "banana") 3 #f) -(dict-ref #("apple" "banana") -3 #f) +(eval:error (dict-ref #("apple" "banana") -3 #f)) ]} @defproc[(dict-set! [dict (and/c dict? (not/c immutable?))] @@ -461,10 +461,10 @@ Supported for any @racket[dict] that implements @racket[dict-ref] and @examples[ #:eval dict-eval -(dict-ref! (make-hasheq '((a . "apple") (b . "beer"))) 'a) +(dict-ref! (make-hasheq '((a . "apple") (b . "beer"))) 'a #f) (dict-ref! (make-hasheq '((a . "apple") (b . "beer"))) 'c 'cabbage) (define h (make-hasheq '((a . "apple") (b . "beer")))) -(dict-ref h 'c) +(eval:error (dict-ref h 'c)) (dict-ref! h 'c (λ () 'cabbage)) (dict-ref h 'c) ]} @@ -486,7 +486,7 @@ Supported for any @racket[dict] that implements @racket[dict-ref] and @examples[ #:eval dict-eval (define h (make-hash)) -(dict-update! h 'a add1) +(eval:error (dict-update! h 'a add1)) (dict-update! h 'a add1 0) h (define v (vector #f #f #f)) @@ -512,7 +512,7 @@ Supported for any @racket[dict] that implements @racket[dict-ref] and @examples[ #:eval dict-eval -(dict-update #hash() 'a add1) +(eval:error (dict-update #hash() 'a add1)) (dict-update #hash() 'a add1 0) (dict-update #hash((a . "apple") (b . "beer")) 'b string-length) ]} diff --git a/pkgs/racket-doc/scribblings/reference/evts.scrbl b/pkgs/racket-doc/scribblings/reference/evts.scrbl index 0e810e41ef..02808a0265 100644 --- a/pkgs/racket-doc/scribblings/reference/evts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/evts.scrbl @@ -1,6 +1,5 @@ #lang scribble/doc @(require scribble/struct - scribble/eval "mz.rkt" (for-label racket/async-channel)) diff --git a/pkgs/racket-doc/scribblings/reference/exns.scrbl b/pkgs/racket-doc/scribblings/reference/exns.scrbl index 9b43d8b07e..316d506bc0 100644 --- a/pkgs/racket-doc/scribblings/reference/exns.scrbl +++ b/pkgs/racket-doc/scribblings/reference/exns.scrbl @@ -103,7 +103,7 @@ exception handler obtains control, and the handler itself is (+ 5 (raise (make-my-exception "failed" (current-continuation-marks))))) -(raise 'failed #t) +(eval:error (raise 'failed #t)) ]} @defproc*[([(error [sym symbol?]) any] @@ -145,9 +145,9 @@ In all cases, the constructed message string is passed to @racket[make-exn:fail], and the resulting exception is raised. @examples[ -(error 'failed) -(error "failed" 23 'pizza (list 1 2 3)) -(error 'method-a "failed because ~a" "no argument supplied") +(eval:error (error 'failed)) +(eval:error (error "failed" 23 'pizza (list 1 2 3))) +(eval:error (error 'method-a "failed because ~a" "no argument supplied")) ]} @@ -187,17 +187,17 @@ message names the bad argument and also lists the other arguments. If (if (not (integer? bits)) (raise-argument-error 'feed-machine "integer?" bits) "fed the machine")) -(feed-machine 'turkey) +(eval:error (feed-machine 'turkey)) (define (feed-cow animal) (if (not (eq? animal 'cow)) (raise-argument-error 'feed-cow "'cow" animal) "fed the cow")) -(feed-cow 'turkey) +(eval:error (feed-cow 'turkey)) (define (feed-animals cow sheep goose cat) (if (not (eq? goose 'goose)) (raise-argument-error 'feed-animals "'goose" 2 cow sheep goose cat) "fed the animals")) -(feed-animals 'cow 'sheep 'dog 'cat) +(eval:error (feed-animals 'cow 'sheep 'dog 'cat)) ]} @@ -224,10 +224,11 @@ using the error value conversion handler (see @racket[error-value->string-handler]). @examples[ + (eval:error (raise-arguments-error 'eat "fish is smaller than its given meal" "fish" 12 - "meal" 13) + "meal" 13)) ]} @@ -254,10 +255,10 @@ less than} the size of a collection---for example, @racket[(sub1 (vector-length _vec))], @racket[(sub1 (length _lst))], and so on. @examples[ -(raise-range-error 'vector-ref "vector" "starting " 5 #(1 2 3 4) 0 3) -(raise-range-error 'vector-ref "vector" "ending " 5 #(1 2 3 4) 0 3) -(raise-range-error 'vector-ref "vector" "" 3 #() 0 -1) -(raise-range-error 'vector-ref "vector" "ending " 1 #(1 2 3 4) 2 3 0) +(eval:error (raise-range-error 'vector-ref "vector" "starting " 5 #(1 2 3 4) 0 3)) +(eval:error (raise-range-error 'vector-ref "vector" "ending " 5 #(1 2 3 4) 0 3)) +(eval:error (raise-range-error 'vector-ref "vector" "" 3 #() 0 -1)) +(eval:error (raise-range-error 'vector-ref "vector" "ending " 1 #(1 2 3 4) 2 3 0)) ]} diff --git a/pkgs/racket-doc/scribblings/reference/fasl.scrbl b/pkgs/racket-doc/scribblings/reference/fasl.scrbl index a440bd731b..84bd774431 100644 --- a/pkgs/racket-doc/scribblings/reference/fasl.scrbl +++ b/pkgs/racket-doc/scribblings/reference/fasl.scrbl @@ -2,7 +2,7 @@ @(require "mz.rkt" (for-label racket/fasl)) @(define fasl-eval (make-base-eval)) -@(interaction-eval #:eval fasl-eval (require racket/fasl)) +@examples[#:hidden #:eval fasl-eval (require racket/fasl)] @title[#:tag "fasl"]{Fast-Load Serialization} diff --git a/pkgs/racket-doc/scribblings/reference/file-ports.scrbl b/pkgs/racket-doc/scribblings/reference/file-ports.scrbl index 19c1df8ba4..969fea7a46 100644 --- a/pkgs/racket-doc/scribblings/reference/file-ports.scrbl +++ b/pkgs/racket-doc/scribblings/reference/file-ports.scrbl @@ -27,8 +27,8 @@ (delete-file i))))) (clean) (begin0 - (defexamples #:eval my-eval - expr ...) + (examples #:eval my-eval + expr ...) (clean)))])) "") diff --git a/pkgs/racket-doc/scribblings/reference/filesystem.scrbl b/pkgs/racket-doc/scribblings/reference/filesystem.scrbl index b25348c850..93a5f5400e 100644 --- a/pkgs/racket-doc/scribblings/reference/filesystem.scrbl +++ b/pkgs/racket-doc/scribblings/reference/filesystem.scrbl @@ -7,7 +7,9 @@ setup/cross-system)) @(define file-eval (make-base-eval)) -@(interaction-eval #:eval file-eval (begin (require racket/file) (define filename (make-temporary-file)))) +@examples[#:hidden #:eval file-eval + (require racket/file) + (define filename (make-temporary-file))] @title{Filesystem} @@ -1428,7 +1430,7 @@ and bitwise operations such as @racket[bitwise-ior], and @racket[bitwise-and].} -@(interaction-eval #:eval file-eval (begin - (delete-file filename) - (delete-file (make-lock-file-name filename)))) +@examples[#:hidden #:eval file-eval + (delete-file filename) + (delete-file (make-lock-file-name filename))] @(close-eval file-eval) diff --git a/pkgs/racket-doc/scribblings/reference/fixnums.scrbl b/pkgs/racket-doc/scribblings/reference/fixnums.scrbl index f63da787de..9719bd3925 100644 --- a/pkgs/racket-doc/scribblings/reference/fixnums.scrbl +++ b/pkgs/racket-doc/scribblings/reference/fixnums.scrbl @@ -7,7 +7,7 @@ racket/require)) @(define flfx-eval (make-base-eval)) -@(interaction-eval #:eval flfx-eval (require racket/fixnum)) +@examples[#:hidden #:eval flfx-eval (require racket/fixnum)] @title[#:tag "fixnums"]{Fixnums} diff --git a/pkgs/racket-doc/scribblings/reference/flonums.scrbl b/pkgs/racket-doc/scribblings/reference/flonums.scrbl index 377d66455f..8bb56b69a2 100644 --- a/pkgs/racket-doc/scribblings/reference/flonums.scrbl +++ b/pkgs/racket-doc/scribblings/reference/flonums.scrbl @@ -2,7 +2,7 @@ @(require "mz.rkt" (for-label racket/flonum)) @(define fl-eval (make-base-eval)) -@(interaction-eval #:eval fl-eval (require racket/flonum)) +@examples[#:hidden #:eval fl-eval (require racket/flonum)] @title[#:tag "flonums"]{Flonums} diff --git a/pkgs/racket-doc/scribblings/reference/for.scrbl b/pkgs/racket-doc/scribblings/reference/for.scrbl index eaff5d42f8..7f2d862d7b 100644 --- a/pkgs/racket-doc/scribblings/reference/for.scrbl +++ b/pkgs/racket-doc/scribblings/reference/for.scrbl @@ -379,10 +379,11 @@ source for all syntax errors. @code:comment{If we misuse for/digits, we can get good error reporting} @code:comment{because the use of orig-datum allows for source correlation:} -(for/digits - [a (in-list '(1 2 3))] - [b (in-list '(4 5 6))] - (+ a b)) +(eval:error + (for/digits + [a (in-list '(1 2 3))] + [b (in-list '(4 5 6))] + (+ a b))) (for/digits ([a (in-list '(1 2 3))] @@ -426,10 +427,11 @@ Like @racket[for*/fold], but the extra @racket[orig-datum] is used as the source (values (+ n (* d k)) (* k 10)))]) n))])) -(for*/digits - [ds (in-list '((8 3) (1 1)))] - [d (in-list ds)] - d) +(eval:error + (for*/digits + [ds (in-list '((8 3) (1 1)))] + [d (in-list ds)] + d)) (for*/digits ([ds (in-list '((8 3) (1 1)))] diff --git a/pkgs/racket-doc/scribblings/reference/format.scrbl b/pkgs/racket-doc/scribblings/reference/format.scrbl index 7a240c8307..4a5bccf01d 100644 --- a/pkgs/racket-doc/scribblings/reference/format.scrbl +++ b/pkgs/racket-doc/scribblings/reference/format.scrbl @@ -1,7 +1,6 @@ #lang scribble/doc @(require scribble/manual scribble/struct - scribble/eval "mz.rkt" (for-label racket/contract racket/math @@ -40,7 +39,7 @@ with @racket[separator] between consecutive items, and then pads or truncates the string to be at least @racket[min-width] characters and at most @racket[max-width] characters. -@interaction[#:eval the-eval +@examples[#:eval the-eval (~a "north") (~a 'south) (~a #"east") @@ -70,7 +69,7 @@ truncated and the end of the string is replaced with @racket[limit-marker]. If @racket[limit-marker] is longer than @racket[max-width], an exception is raised. -@interaction[#:eval the-eval +@examples[#:eval the-eval (~a "abcde" #:max-width 5) (~a "abcde" #:max-width 4) (~a "abcde" #:max-width 4 #:limit-marker "*") @@ -95,7 +94,7 @@ of @racket[right-pad-string] in its entirety. Thus left padding starts with the start of @racket[left-pad-string] and right padding ends with the end of @racket[right-pad-string]. -@interaction[#:eval the-eval +@examples[#:eval the-eval (~a "apple" #:min-width 20 #:align 'left) (~a "pear" #:min-width 20 #:align 'left #:right-pad-string " .") (~a "plum" #:min-width 20 #:align 'right #:left-pad-string ". ") @@ -107,7 +106,7 @@ Use @racket[width] to set both @racket[max-width] and @racket[min-width] simultaneously, ensuring that the resulting string is exactly @racket[width] characters long: -@interaction[#:eval the-eval +@examples[#:label #f #:eval the-eval (~a "terse" #:width 6) (~a "loquacious" #:width 6) ] @@ -131,7 +130,7 @@ Like @racket[~a], but each value is converted like @racket[(format "~v" v)], the default separator is @racket[" "], and the default limit marker is @racket["..."]. -@interaction[#:eval the-eval +@examples[#:eval the-eval (~v "north") (~v 'south) (~v #"east") @@ -141,7 +140,7 @@ marker is @racket["..."]. Use @racket[~v] to produce text that talks about Racket values. -@interaction[#:eval the-eval +@examples[#:eval the-eval (let ([nums (for/list ([i 10]) i)]) (~a "The even numbers in " (~v nums) " are " (~v (filter even? nums)) ".")) @@ -165,7 +164,7 @@ Like @racket[~a], but each value is converted like @racket[(format "~s" v)], the default separator is @racket[" "], and the default limit marker is @racket["..."]. -@interaction[#:eval the-eval +@examples[#:eval the-eval (~s "north") (~s 'south) (~s #"east") @@ -192,7 +191,7 @@ Like @racket[~a], but each value is converted like @racket[(format "~e" v)], the default separator is @racket[" "], and the default limit marker is @racket["..."]. -@interaction[#:eval the-eval +@examples[#:eval the-eval (~e "north") (~e 'south) (~e #"east") @@ -241,7 +240,7 @@ The optional arguments control number formatting: in positional or exponential notation. If @racket[notation] is a function, it is applied to @racket[x] to get the notation to be used. -@interaction[#:eval the-eval +@examples[#:eval the-eval (~r 12345) (~r 12345 #:notation 'exponential) (let ([pick-notation @@ -266,7 +265,7 @@ point are dropped the decimal point is also dropped. If @racket[precision] is @racket[(list '= _digits)], then exactly @racket[_digits] digits after the decimal point are used, and the decimal point is never dropped. -@interaction[#:eval the-eval +@examples[#:eval the-eval (~r pi) (~r pi #:precision 4) (~r pi #:precision 0) @@ -282,7 +281,7 @@ with fewer than @racket[min-width] digits (including the decimal point but not including the sign indicator), the digits are left-padded using @racket[pad-string]. -@interaction[#:eval the-eval +@examples[#:eval the-eval (~r 17) (~r 17 #:min-width 4) (~r -42 #:min-width 4) @@ -298,7 +297,7 @@ number to at least @racket[min-width] characters (not including the sign indicator). The padding is placed between the sign and the normal digits of @racket[x]. -@interaction[#:eval the-eval +@examples[#:eval the-eval (~r 17 #:min-width 4 #:pad-string "0") (~r -42 #:min-width 4 #:pad-string "0") ]} @@ -311,7 +310,7 @@ indicated: generated if @racket[x] is either positive or zero, and a minus sign is prefixed if @racket[x] is negative. - @interaction[#:eval the-eval + @examples[#:eval the-eval (for/list ([x '(17 0 -42)]) (~r x)) ]} @@ -319,14 +318,14 @@ indicated: @racket[x] is zero, a plus sign is prefixed if @racket[x] is positive, and a minus sign is prefixed if @racket[x] is negative. - @interaction[#:eval the-eval + @examples[#:eval the-eval (for/list ([x '(17 0 -42)]) (~r x #:sign '+)) ]} @item{If @racket[sign] is @racket['++], a plus sign is prefixed if @racket[x] is zero or positive, and a minus sign is prefixed if @racket[x] is negative. - @interaction[#:eval the-eval + @examples[#:eval the-eval (for/list ([x '(17 0 -42)]) (~r x #:sign '++)) ]} @@ -334,7 +333,7 @@ indicated: @racket[x] is zero or positive, and the number is enclosed in parentheses if @racket[x] is negative. - @interaction[#:eval the-eval + @examples[#:eval the-eval (for/list ([x '(17 0 -42)]) (~r x #:sign 'parens)) ]} @@ -344,7 +343,7 @@ indicated: either a string to be used as a prefix or a list containing two strings: a prefix and a suffix. - @interaction[#:eval the-eval + @examples[#:eval the-eval (let ([sign-table '(("" " up") "an even " ("" " down"))]) (for/list ([x '(17 0 -42)]) (~r x #:sign sign-table))) ] @@ -359,7 +358,7 @@ indicated: used. If @racket[base] is @racket[(list 'up _base*)] and @racket[_base*] is greater than @racket[10], then upper-case letters are used. -@interaction[#:eval the-eval +@examples[#:eval the-eval (~r 100 #:base 7) (~r 4.5 #:base 2) (~r 3735928559 #:base 16) @@ -374,7 +373,7 @@ explicit sign (as with a @racket[sign] of @racket['++]) and at least two digits, separated from the significand by the ``exponent marker'' @racket[format-exponent]: -@interaction[#:eval the-eval +@examples[#:label #f #:eval the-eval (~r 1234 #:notation 'exponential #:format-exponent "E") ] @@ -382,7 +381,7 @@ If @racket[format-exponent] is @racket[#f], the ``exponent marker'' is @racket["e"] if @racket[base] is @racket[10] and a string involving @racket[base] otherwise: -@interaction[#:eval the-eval +@examples[#:label #f #:eval the-eval (~r 1234 #:notation 'exponential) (~r 1234 #:notation 'exponential #:base 8) ] @@ -390,7 +389,7 @@ If @racket[format-exponent] is @racket[#f], the ``exponent marker'' is If @racket[format-exponent] is a procedure, it is applied to the exponent and the resulting string is appended to the significand: -@interaction[#:eval the-eval +@examples[#:label #f #:eval the-eval (~r 1234 #:notation 'exponential #:format-exponent (lambda (e) (format "E~a" e))) ]} diff --git a/pkgs/racket-doc/scribblings/reference/futures.scrbl b/pkgs/racket-doc/scribblings/reference/futures.scrbl index aed4951c54..caa0113072 100644 --- a/pkgs/racket-doc/scribblings/reference/futures.scrbl +++ b/pkgs/racket-doc/scribblings/reference/futures.scrbl @@ -2,7 +2,7 @@ @(require "mz.rkt" (for-label racket/future)) @(define future-eval (make-base-eval)) -@(interaction-eval #:eval future-eval (require racket/future)) +@examples[#:hidden #:eval future-eval (require racket/future)] @(define time-id @racketidfont{time}) @@ -67,7 +67,7 @@ execute through a call to @racket[touch], however. future, the given @racket[thunk] may run speculatively in parallel to other computations, as described above. - @interaction[ + @examples[ #:eval future-eval (let ([f (future (lambda () (+ 1 2)))]) (list (+ 3 4) (touch f))) diff --git a/pkgs/racket-doc/scribblings/reference/generic.scrbl b/pkgs/racket-doc/scribblings/reference/generic.scrbl index 7f0136aa66..2195bc4b25 100644 --- a/pkgs/racket-doc/scribblings/reference/generic.scrbl +++ b/pkgs/racket-doc/scribblings/reference/generic.scrbl @@ -132,7 +132,7 @@ method} called @racket[name] that does not support the @techlink{generic instance} @racket[v]. @examples[#:eval evaluator -(raise-support-error 'some-method-name '("arbitrary" "instance" "value")) +(eval:error (raise-support-error 'some-method-name '("arbitrary" "instance" "value"))) ] } @@ -233,7 +233,7 @@ syntax error.} make-num) (define z (make-num-contracted 10)) -(gen-print* z #:width "not a number" #:height 5) +(eval:error (gen-print* z #:width "not a number" #:height 5)) ] @defform[(generic-instance/c gen-id [method-id method-ctc] ...) diff --git a/pkgs/racket-doc/scribblings/reference/hashes.scrbl b/pkgs/racket-doc/scribblings/reference/hashes.scrbl index 227199413c..3a9809f319 100644 --- a/pkgs/racket-doc/scribblings/reference/hashes.scrbl +++ b/pkgs/racket-doc/scribblings/reference/hashes.scrbl @@ -546,7 +546,7 @@ key @racket[k] and value @racket[v], if a mapping from @racket[k] to some value @racket[v0] already exists, it is replaced with a mapping from @racket[k] to @racket[(combine/key k v0 v)]. -@defexamples[ +@examples[ #:eval the-eval (hash-union (make-immutable-hash '([1 . one])) (make-immutable-hash '([2 . two])) @@ -574,7 +574,7 @@ key @racket[k] and value @racket[v], if a mapping from @racket[k] to some value @racket[v0] already exists, it is replaced with a mapping from @racket[k] to @racket[(combine/key k v0 v)]. -@defexamples[ +@examples[ #:eval the-eval (define h (make-hash)) h diff --git a/pkgs/racket-doc/scribblings/reference/logging.scrbl b/pkgs/racket-doc/scribblings/reference/logging.scrbl index 170dff5826..1353136daa 100644 --- a/pkgs/racket-doc/scribblings/reference/logging.scrbl +++ b/pkgs/racket-doc/scribblings/reference/logging.scrbl @@ -324,8 +324,8 @@ argument list takes precedence.} @note-lib[racket/logging] @(require (for-label racket/logging)) @(define log-eval (make-base-eval)) -@(interaction-eval #:eval log-eval - (require racket/logging)) +@examples[#:hidden #:eval log-eval + (require racket/logging)] @defproc[(log-level/c [v any/c]) boolean?]{ @@ -353,7 +353,7 @@ Runs @racket[proc], calling @racket[interceptor] on any log event that would be received by @racket[(make-log-receiver (current-logger) level topic ... ...)]. Returns whatever @racket[proc] returns. -@defexamples[ +@examples[ #:eval log-eval (let ([warning-counter 0]) (with-intercepted-logging @@ -381,7 +381,7 @@ Runs @racket[proc], outputting any logging that would be received by @racket[(make-log-receiver (current-logger) level topic ... ...)] to @racket[port]. Returns whatever @racket[proc] returns. -@defexamples[ +@examples[ #:eval log-eval (let ([my-log (open-output-string)]) (with-logging-to-port my-log diff --git a/pkgs/racket-doc/scribblings/reference/match.scrbl b/pkgs/racket-doc/scribblings/reference/match.scrbl index 73e64e23be..05f59838d5 100644 --- a/pkgs/racket-doc/scribblings/reference/match.scrbl +++ b/pkgs/racket-doc/scribblings/reference/match.scrbl @@ -2,8 +2,8 @@ @(require "mz.rkt" "match-grammar.rkt" racket/match) @(define match-eval (make-base-eval)) -@(interaction-eval #:eval match-eval (require racket/match racket/list)) -@(interaction-eval #:eval match-eval (require (for-syntax racket/base))) +@examples[#:hidden #:eval match-eval (require racket/match racket/list)] +@examples[#:hidden #:eval match-eval (require (for-syntax racket/base))] @title[#:tag "match"]{Pattern Matching} @@ -239,9 +239,9 @@ In more detail, patterns match as follows: @racket[struct] declaration can provide the structure type information. - @defexamples[ + @examples[ #:eval match-eval - (define-struct tree (val left right)) + (eval:no-prompt (define-struct tree (val left right))) (match (make-tree 0 (make-tree 1 #f #f) #f) [(tree a (tree b _ _) _) (list a b)]) ]} @@ -430,27 +430,30 @@ many values to expect from @racket[expr]. The arguments are ordered as they appear in the function header for matching purposes. - @defexamples[#:eval match-eval - (define/match (fact n) - [(0) 1] - [(n) (* n (fact (sub1 n)))]) + @examples[#:eval match-eval + (eval:no-prompt + (define/match (fact n) + [(0) 1] + [(n) (* n (fact (sub1 n)))])) (fact 5) ] The function header may also contain optional or keyword arguments, may have curried arguments, and may also contain a rest argument. - @defexamples[#:eval match-eval - (define/match ((f x) #:y [y '(1 2 3)]) - [((regexp #rx"p+") `(,a 2 3)) a] - [(_ _) #f]) + @examples[#:eval match-eval + (eval:no-prompt + (define/match ((f x) #:y [y '(1 2 3)]) + [((regexp #rx"p+") `(,a 2 3)) a] + [(_ _) #f])) ((f "ape") #:y '(5 2 3)) ((f "dog")) - (define/match (g x y . rst) - [(0 0 '()) #t] - [(5 5 '(5 5)) #t] - [(_ _ _) #f]) + (eval:no-prompt + (define/match (g x y . rst) + [(0 0 '()) #t] + [(5 5 '(5 5)) #t] + [(_ _ _) #f])) (g 0 0) (g 5 5 5 5) (g 1 2) @@ -586,9 +589,10 @@ are used as binding identifiers (like any other identifier) when they appear anywhere except the first position in a sequence. For example, to extend the pattern matcher and destructure syntax lists, -@defs+int[ +@examples[#:label #f #:eval match-eval - ((define (syntax-list? x) + (eval:no-prompt + (define (syntax-list? x) (and (syntax? x) (list? (syntax->list x)))) (define-match-expander syntax-list @@ -602,8 +606,7 @@ For example, to extend the pattern matcher and destructure syntax lists, (and (identifier? stx) (free-identifier=? stx keyword)))) (define or-keyword? (make-keyword-predicate #'or)) - (define and-keyword? (make-keyword-predicate #'and)) - ) + (define and-keyword? (make-keyword-predicate #'and))) (match #'(or 3 4) [(syntax-list (? or-keyword?) b c) @@ -622,9 +625,10 @@ And here is an example showing how @racket[define-match-expander]-bound identifiers are not treated specially unless they appear in the first position of pattern sequence. -@defs+int[ +@examples[#:label #f #:eval match-eval - ((define-match-expander nil + (eval:no-prompt + (define-match-expander nil (λ (stx) #''()) (λ (stx) #''())) (define (len l) @@ -728,9 +732,10 @@ not provided, it defaults to @racket[equal?]. Any field of @racket[struct-id] may be omitted, and such fields can occur in any order. - @defexamples[ + @examples[ #:eval match-eval - (define-struct tree (val left right)) + (eval:no-prompt + (define-struct tree (val left right))) (match (make-tree 0 (make-tree 1 #f #f) #f) [(struct* tree ([val a] [left (struct* tree ([right #f] [val b]))])) diff --git a/pkgs/racket-doc/scribblings/reference/mz.rkt b/pkgs/racket-doc/scribblings/reference/mz.rkt index 6d58dea556..28f95342b9 100644 --- a/pkgs/racket-doc/scribblings/reference/mz.rkt +++ b/pkgs/racket-doc/scribblings/reference/mz.rkt @@ -2,13 +2,13 @@ (require scribble/struct scribble/manual - scribble/eval + scribble/examples scribble/decode racket/contract "../icons.rkt") (provide (all-from-out scribble/manual) - (all-from-out scribble/eval) + (all-from-out scribble/examples) (all-from-out racket/contract)) (require (for-label racket)) diff --git a/pkgs/racket-doc/scribblings/reference/numbers.scrbl b/pkgs/racket-doc/scribblings/reference/numbers.scrbl index 30647d85da..1ce1061240 100644 --- a/pkgs/racket-doc/scribblings/reference/numbers.scrbl +++ b/pkgs/racket-doc/scribblings/reference/numbers.scrbl @@ -8,7 +8,7 @@ racket/random)) @(define math-eval (make-base-eval)) -@(interaction-eval #:eval math-eval (require racket/math)) +@examples[#:hidden #:eval math-eval (require racket/math)] @title[#:tag "numbers" #:style '(toc)]{Numbers} @@ -193,12 +193,12 @@ number, @racket[#f] otherwise.} @defproc[(even? [n integer?]) boolean?]{ Returns @racket[(zero? (modulo n 2))]. -@mz-examples[(even? 10.0) (even? 11) (even? +inf.0)]} +@mz-examples[(even? 10.0) (even? 11) (eval:error (even? +inf.0))]} @defproc[(odd? [n integer?]) boolean?]{ Returns @racket[(not (even? n))]. -@mz-examples[(odd? 10.0) (odd? 11) (odd? +inf.0)]} +@mz-examples[(odd? 10.0) (odd? 11) (eval:error (odd? +inf.0))]} @defproc[(exact? [z number?]) boolean?]{ Returns @racket[#t] if @racket[z] @@ -289,7 +289,7 @@ If @racket[z] is exact @racket[0] and no @racket[w] is exact Returns @racket[(truncate (/ n m))]. -@mz-examples[(quotient 10 3) (quotient -10.0 3) (quotient +inf.0 3)]} +@mz-examples[(quotient 10 3) (quotient -10.0 3) (eval:error (quotient +inf.0 3))]} @defproc[(remainder [n integer?] [m integer?]) integer?]{ @@ -307,7 +307,7 @@ Returns @racket[_q] with the same sign as @racket[n] such that If @racket[m] is exact @racket[0], the @exnraise[exn:fail:contract:divide-by-zero]. -@mz-examples[(remainder 10 3) (remainder -10.0 3) (remainder 10.0 -3) (remainder -10 -3) (remainder +inf.0 3)]} +@mz-examples[(remainder 10 3) (remainder -10.0 3) (remainder 10.0 -3) (remainder -10 -3) (eval:error (remainder +inf.0 3))]} @defproc[(quotient/remainder [n integer?] [m integer?]) (values integer? integer?)]{ @@ -336,7 +336,7 @@ Returns @racket[_q] with the same sign as @racket[m] where If @racket[m] is exact @racket[0], the @exnraise[exn:fail:contract:divide-by-zero]. -@mz-examples[(modulo 10 3) (modulo -10.0 3) (modulo 10.0 -3) (modulo -10 -3) (modulo +inf.0 3)]} +@mz-examples[(modulo 10 3) (modulo -10.0 3) (modulo 10.0 -3) (modulo -10 -3) (eval:error (modulo +inf.0 3))]} @defproc[(add1 [z number?]) number?]{ Returns @racket[(+ z 1)].} diff --git a/pkgs/racket-doc/scribblings/reference/pairs.scrbl b/pkgs/racket-doc/scribblings/reference/pairs.scrbl index 88b87c44f2..a39319377d 100644 --- a/pkgs/racket-doc/scribblings/reference/pairs.scrbl +++ b/pkgs/racket-doc/scribblings/reference/pairs.scrbl @@ -249,7 +249,8 @@ merely start with a chain of at least @racket[(add1 pos)] pairs. (list-ref (list 'a 'b 'c) 0) (list-ref (list 'a 'b 'c) 1) (list-ref (list 'a 'b 'c) 2) - (list-ref (cons 1 2) 0)]} + (list-ref (cons 1 2) 0) + (eval:error (list-ref (cons 1 2) 1))]} @defproc[(list-tail [lst any/c] [pos exact-nonnegative-integer?]) @@ -264,8 +265,9 @@ must merely start with a chain of at least @racket[pos] pairs. @mz-examples[ (list-tail (list 1 2 3 4) 2) - (list-ref (cons 1 2) 1) - (list-ref 'not-a-pair 0)]} + (list-tail (cons 1 2) 1) + (eval:error (list-tail (cons 1 2) 2)) + (list-tail 'not-a-pair 0)]} @defproc*[([(append [lst list?] ...) list?] @@ -342,7 +344,7 @@ If the @racket[lst]s are empty, then @racket[#t] is returned. @mz-examples[ (andmap positive? '(1 2 3)) - (andmap positive? '(1 2 a)) + (eval:error (andmap positive? '(1 2 a))) (andmap positive? '(1 -2 a)) (andmap + '(1 2 3) '(4 5 6))]} @@ -711,8 +713,8 @@ Like @racket[assoc], but finds an element using the predicate @note-lib[racket/list] @(define list-eval (make-base-eval)) -@(interaction-eval #:eval list-eval - (require racket/list (only-in racket/function negate))) +@examples[#:hidden #:eval list-eval + (require racket/list (only-in racket/function negate))] @defthing[empty null?]{ @@ -1329,7 +1331,7 @@ Computes the n-ary cartesian product of the given lists. Returns a list that is like @racket[lst], omitting the first element of @racket[lst] for which @racket[pred] produces a true value. -@defexamples[ +@examples[ #:eval list-eval (remf negative? '(1 -2 3 4 -5)) ] @@ -1342,7 +1344,7 @@ for which @racket[pred] produces a true value. Like @racket[remf], but removes all the elements for which @racket[pred] produces a true value. -@defexamples[ +@examples[ #:eval list-eval (remf* negative? '(1 -2 3 4 -5)) ] diff --git a/pkgs/racket-doc/scribblings/reference/port-lib.scrbl b/pkgs/racket-doc/scribblings/reference/port-lib.scrbl index 9a854b3456..7f0a3d4403 100644 --- a/pkgs/racket-doc/scribblings/reference/port-lib.scrbl +++ b/pkgs/racket-doc/scribblings/reference/port-lib.scrbl @@ -9,7 +9,7 @@ @section{Port String and List Conversions} @(define port-eval (make-base-eval)) -@(interaction-eval #:eval port-eval (require racket/port)) +@examples[#:hidden #:eval port-eval (require racket/port)] @defproc[(port->list [r (input-port? . -> . any/c) read] [in input-port? (current-input-port)]) (listof any/c)]{ diff --git a/pkgs/racket-doc/scribblings/reference/procedures.scrbl b/pkgs/racket-doc/scribblings/reference/procedures.scrbl index 9815a5a6e2..ac3ee93956 100644 --- a/pkgs/racket-doc/scribblings/reference/procedures.scrbl +++ b/pkgs/racket-doc/scribblings/reference/procedures.scrbl @@ -123,9 +123,10 @@ not require any other keywords, and it must accept as many by-position arguments as supplied via the @racket[v]s and @racket[lst]; otherwise, the @exnraise[exn:fail:contract]. -@defexamples[ -(define (f x #:y y #:z [z 10]) - (list x y z)) +@examples[ +(eval:no-prompt + (define (f x #:y y #:z [z 10]) + (list x y z))) (keyword-apply f '(#:y) '(2) '(1)) (keyword-apply f '(#:y #:z) '(2 3) '(1)) (keyword-apply f #:z 7 '(#:y) '(2) '(1)) @@ -207,7 +208,7 @@ arity-reduced procedure) or @racket[arity] must be the empty list @examples[ (define my+ (procedure-reduce-arity + 2)) (my+ 1 2) -(my+ 1 2 3) +(eval:error (my+ 1 2 3)) ]} @defproc[(procedure-keywords [proc procedure?]) @@ -256,19 +257,21 @@ The result of @racket[procedure-arity] and @racket[object-name] on the new procedure is the same as for @racket[plain-proc]. See also @racket[procedure-reduce-keyword-arity] and @racket[procedure-rename]. -@defexamples[ -(define show - (make-keyword-procedure (lambda (kws kw-args . rest) - (list kws kw-args rest)))) +@examples[ +(eval:no-prompt + (define show + (make-keyword-procedure (lambda (kws kw-args . rest) + (list kws kw-args rest))))) (show 1) (show #:init 0 1 2 3 #:extra 4) -(define show2 - (make-keyword-procedure (lambda (kws kw-args . rest) - (list kws kw-args rest)) - (lambda args - (list->vector args)))) +(eval:no-prompt + (define show2 + (make-keyword-procedure (lambda (kws kw-args . rest) + (list kws kw-args rest)) + (lambda args + (list->vector args))))) (show2 1) (show2 #:init 0 1 2 3 #:extra 4) ]} @@ -291,15 +294,16 @@ must require no more keywords than the ones listed in @racket[allowed-kws] (or it must allow all keywords if @racket[allowed-kws] is @racket[#f]). -@defexamples[ -(define orig-show - (make-keyword-procedure (lambda (kws kw-args . rest) - (list kws kw-args rest)))) -(define show (procedure-reduce-keyword-arity - orig-show 3 '(#:init) '(#:extra #:init))) +@examples[ +(eval:no-prompt + (define orig-show + (make-keyword-procedure (lambda (kws kw-args . rest) + (list kws kw-args rest)))) + (define show (procedure-reduce-keyword-arity + orig-show 3 '(#:init) '(#:extra #:init)))) (show #:init 0 1 2 3 #:extra 4) -(show 1) -(show #:init 0 1 2 3 #:extra 4 #:more 7) +(eval:error (show 1)) +(eval:error (show #:init 0 1 2 3 #:extra 4 #:more 7)) ]} @defstruct[arity-at-least ([value exact-nonnegative-integer?])]{ @@ -452,7 +456,7 @@ property is not associated with a procedure structure type. (apply pairs more))]))) (pairs 1 2 3 4) -(pairs 5)]} +(eval:error (pairs 5))]} @defthing[prop:checked-procedure struct-type-property?]{ @@ -517,7 +521,7 @@ applied.} @note-lib[racket/function] @(define fun-eval (make-base-eval)) -@(interaction-eval #:eval fun-eval (require racket/function)) +@examples[#:hidden #:eval fun-eval (require racket/function)] @defproc[(identity [v any/c]) any/c]{ Returns @racket[v]. @@ -540,13 +544,15 @@ The @racket[thunk] form creates a nullary function that evaluates the given body. The @racket[thunk*] form is similar, except that the resulting function accepts any arguments (including keyword arguments). -@defexamples[ +@examples[ #:eval fun-eval -(define th1 (thunk (define x 1) (printf "~a\n" x))) +(eval:no-prompt + (define th1 (thunk (define x 1) (printf "~a\n" x)))) (th1) -(th1 'x) -(th1 #:y 'z) -(define th2 (thunk* (define x 1) (printf "~a\n" x))) +(eval:error (th1 'x)) +(eval:error (th1 #:y 'z)) +(eval:no-prompt + (define th2 (thunk* (define x 1) (printf "~a\n" x)))) (th2) (th2 'x) (th2 #:y 'z) @@ -567,9 +573,10 @@ returns the @racket[not] of @racket[proc]'s result. Combines calls to each function with @racket[and]. Equivalent to @racket[(and (f x ...) ...)] -@defexamples[ +@examples[ #:eval fun-eval -(define f (conjoin exact? integer?)) +(eval:no-prompt + (define f (conjoin exact? integer?))) (f 1) (f 1.0) (f 1/2) @@ -583,9 +590,10 @@ Combines calls to each function with @racket[and]. Equivalent to Combines calls to each function with @racket[or]. Equivalent to @racket[(or (f x ...) ...)] -@defexamples[ +@examples[ #:eval fun-eval -(define f (disjoin exact? integer?)) +(eval:no-prompt + (define f (disjoin exact? integer?))) (f 1) (f 1.0) (f 1/2) diff --git a/pkgs/racket-doc/scribblings/reference/regexps.scrbl b/pkgs/racket-doc/scribblings/reference/regexps.scrbl index 5a218ddc1f..9472e06c95 100644 --- a/pkgs/racket-doc/scribblings/reference/regexps.scrbl +++ b/pkgs/racket-doc/scribblings/reference/regexps.scrbl @@ -240,7 +240,7 @@ returns the source byte string for a @tech{regexp value}. @examples[ (byte-regexp #"ap*le") (object-name #rx#"ap*le") -(byte-regexp "ap*le") +(eval:error (byte-regexp "ap*le")) ]} @defproc[(byte-pregexp [bstr bytes?]) byte-pregexp?]{ diff --git a/pkgs/racket-doc/scribblings/reference/sandbox.scrbl b/pkgs/racket-doc/scribblings/reference/sandbox.scrbl index 45d8b6a43b..03a5655594 100644 --- a/pkgs/racket-doc/scribblings/reference/sandbox.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sandbox.scrbl @@ -6,7 +6,7 @@ racket/gui/dynamic)) @(define box-eval (make-base-eval)) -@(interaction-eval #:eval box-eval (require racket/sandbox)) +@examples[#:hidden #:eval box-eval (require racket/sandbox)] @title{Sandboxed Evaluation} @@ -147,11 +147,12 @@ The following examples illustrate the difference between an evaluator that puts the program in a module and one that merely initializes a top-level namespace: -@interaction[ +@examples[#:label #f #:eval box-eval -(define base-module-eval - (code:comment @#,t{a module cannot have free variables...}) - (make-evaluator 'racket/base '(define (f) later))) +(eval:error + (define base-module-eval + (code:comment @#,t{a module cannot have free variables...}) + (make-evaluator 'racket/base '(define (f) later)))) (define base-module-eval (make-evaluator 'racket/base '(define (f) later) '(define later 5))) @@ -229,9 +230,10 @@ of communication makes it impossible to have nested (or concurrent) calls to a single evaluator. Usually this is not a problem, but in some cases you can get the evaluator function available inside the sandboxed code, for example: -@interaction[#:eval box-eval -(let ([e (make-evaluator 'racket/base)]) - (e `(,e 1))) +@examples[#:label #f #:eval box-eval +(eval:error + (let ([e (make-evaluator 'racket/base)]) + (e `(,e 1)))) ] An error will be signaled in such cases. diff --git a/pkgs/racket-doc/scribblings/reference/sequences.scrbl b/pkgs/racket-doc/scribblings/reference/sequences.scrbl index c49ced9fb3..4891e55e13 100644 --- a/pkgs/racket-doc/scribblings/reference/sequences.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sequences.scrbl @@ -26,7 +26,7 @@ vice-versa. @(define sequence-evaluator (let ([evaluator (make-base-eval)]) (evaluator '(require racket/generic racket/list racket/stream racket/sequence - racket/contract)) + racket/contract racket/dict)) evaluator)) @guideintro["sequences"]{sequences} @@ -152,7 +152,7 @@ each element in the sequence. Returns @racket[#t] if @racket[v] can be used as a @tech{sequence}, @racket[#f] otherwise. -@interaction[#:eval sequence-evaluator +@examples[#:eval sequence-evaluator (sequence? 42) (sequence? '(a b c)) (sequence? "word") @@ -169,12 +169,12 @@ each element in the sequence. @racket[step] is non-negative, or less or equal to @racket[end] if @racket[step] is negative. @speed[in-range "number"] - Example: gaussian sum - @interaction[#:eval sequence-evaluator + + @examples[#:label "Example: gaussian sum" #:eval sequence-evaluator (for/sum ([x (in-range 10)]) x)] - Example: sum of even numbers - @interaction[#:eval sequence-evaluator + + @examples[#:label "Example: sum of even numbers" #:eval sequence-evaluator (for/sum ([x (in-range 0 100 2)]) x)] } @@ -184,7 +184,7 @@ each element in the sequence. integers starting with @racket[start], where each element is one more than the preceding element. @speed[in-naturals "integer"] - @interaction[#:eval sequence-evaluator + @examples[#:eval sequence-evaluator (for/list ([k (in-naturals)] [x (in-range 10)]) (list k x))] @@ -197,7 +197,7 @@ each element in the sequence. @info-on-seq["pairs" "lists"] @speed[in-list "list"] - @interaction[#:eval sequence-evaluator + @examples[#:eval sequence-evaluator (for/list ([x (in-list '(3 1 4))]) `(,x ,(* x x)))] } @@ -207,7 +207,7 @@ each element in the sequence. @info-on-seq["mpairs" "mutable lists"] @speed[in-mlist "mutable list"] - @interaction[#:eval sequence-evaluator + @examples[#:eval sequence-evaluator (for/list ([x (in-mlist (mcons "RACKET" (mcons "LANG" '())))]) (string-length x))] } @@ -242,7 +242,7 @@ each element in the sequence. @speed[in-vector "vector"] - @interaction[#:eval sequence-evaluator + @examples[#:eval sequence-evaluator (define (histogram vector-of-words) (define a-hash (make-hash)) (for ([word (in-vector vector-of-words)]) @@ -266,7 +266,7 @@ each element in the sequence. @speed[in-string "string"] - @interaction[#:eval sequence-evaluator + @examples[#:eval sequence-evaluator (define (line-count str) (for/sum ([ch (in-string str)]) (if (char=? #\newline ch) 1 0))) @@ -288,7 +288,7 @@ each element in the sequence. @speed[in-bytes "byte string"] - @interaction[#:eval sequence-evaluator + @examples[#:eval sequence-evaluator (define (has-eof? bs) (for/or ([ch (in-bytes bs)]) (= ch 0))) @@ -797,27 +797,30 @@ for instance, a wrapped list is not guaranteed to satisfy @racket[list?]. If @racket[min-count] is a number, the stream is required to have at least that many elements in it. -@defexamples[ +@examples[ #:eval sequence-evaluator (define/contract predicates (sequence/c (-> any/c boolean?)) (in-list (list integer? string->symbol))) -(for ([P predicates]) - (printf "~s\n" (P "cat"))) +(eval:error + (for ([P predicates]) + (printf "~s\n" (P "cat")))) (define/contract numbers&strings (sequence/c number? string?) (in-dict (list (cons 1 "one") (cons 2 "two") (cons 3 'three)))) -(for ([(N S) numbers&strings]) - (printf "~s: ~a\n" N S)) +(eval:error + (for ([(N S) numbers&strings]) + (printf "~s: ~a\n" N S))) (define/contract a-sequence (sequence/c #:min-count 2 char?) "x") -(for ([x a-sequence] - [i (in-naturals)]) - (printf "~a is ~a\n" i x)) +(eval:error + (for ([x a-sequence] + [i (in-naturals)]) + (printf "~a is ~a\n" i x))) ] } @@ -1202,11 +1205,12 @@ values from the generator. literal, exact, non-negative integer. @examples[#:eval generator-eval - (let ([g (in-generator - (let loop ([n 3]) - (unless (zero? n) (yield n (add1 n)) (loop (sub1 n)))))]) - (let-values ([(not-empty? next) (sequence-generate g)]) - (let loop () (when (not-empty?) (next) (loop))) 'done)) + (eval:error + (let ([g (in-generator + (let loop ([n 3]) + (unless (zero? n) (yield n (add1 n)) (loop (sub1 n)))))]) + (let-values ([(not-empty? next) (sequence-generate g)]) + (let loop () (when (not-empty?) (next) (loop))) 'done))) (let ([g (in-generator #:arity 2 (let loop ([n 3]) (unless (zero? n) (yield n (add1 n)) (loop (sub1 n)))))]) @@ -1216,7 +1220,7 @@ values from the generator. To use an existing generator as a sequence, use @racket[in-producer] with a stop-value known for the generator: - @interaction[#:eval generator-eval + @examples[#:label #f #:eval generator-eval (define abc-generator (generator () (for ([x '(a b c)]) (yield x)))) diff --git a/pkgs/racket-doc/scribblings/reference/serialization.scrbl b/pkgs/racket-doc/scribblings/reference/serialization.scrbl index 980bdd5dc2..2962dc1db5 100644 --- a/pkgs/racket-doc/scribblings/reference/serialization.scrbl +++ b/pkgs/racket-doc/scribblings/reference/serialization.scrbl @@ -2,7 +2,7 @@ @(require "mz.rkt" racket/serialize (for-label racket/serialize racket/fasl)) @(define ser-eval (make-base-eval)) -@(interaction-eval #:eval ser-eval (require racket/serialize)) +@examples[#:hidden #:eval ser-eval (require racket/serialize)] @title[#:tag "serialization"]{Serialization} diff --git a/pkgs/racket-doc/scribblings/reference/sets.scrbl b/pkgs/racket-doc/scribblings/reference/sets.scrbl index 875c189a93..f14c27b0ab 100644 --- a/pkgs/racket-doc/scribblings/reference/sets.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sets.scrbl @@ -3,7 +3,7 @@ @title[#:tag "sets"]{Sets} @(define set-eval (make-base-eval)) -@(interaction-eval #:eval set-eval (require racket/set)) +@examples[#:hidden #:eval set-eval (require racket/set)] A @deftech{set} represents a collection of distinct elements. The following datatypes are all sets: @@ -446,7 +446,7 @@ Supported for any @racket[st] that @impl{implements} @racket[set-add] and @supp (set-union (seteq)) (set-union (set 1 2) (set 2 3)) (set-union (list 1 2) (list 2 3)) -(set-union (set 1 2) (seteq 2 3)) (code:comment "Sets of different types cannot be unioned.") +(eval:error (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?] ...) void?]{ @@ -598,8 +598,7 @@ Supported for any @racket[st] and @racket[st2] that both @supp{support} (set=? (set 1 2 3) (set 1)) (set=? (set 1 2 3) (set 1 2 3)) (set=? (seteq 1 2) (mutable-seteq 2 1)) -(set=? (seteq 1 2) (seteqv 1 2)) (code:comment "Sets of different types cannot -be compared.") +(eval:error (set=? (seteq 1 2) (seteqv 1 2))) (code:comment "Sets of different types cannot be compared") ] } diff --git a/pkgs/racket-doc/scribblings/reference/shared.scrbl b/pkgs/racket-doc/scribblings/reference/shared.scrbl index e2fad691e4..ecdcfd3cfc 100644 --- a/pkgs/racket-doc/scribblings/reference/shared.scrbl +++ b/pkgs/racket-doc/scribblings/reference/shared.scrbl @@ -3,7 +3,7 @@ @(define shared-eval (make-base-eval)) -@(interaction-eval #:eval shared-eval (require racket/shared)) +@examples[#:hidden #:eval shared-eval (require racket/shared)] @(define maker (make-element #f (list @@ -125,11 +125,11 @@ that can be created via mutation). (shared ([a (cons 1 b)] [b 7]) a) -(shared ([a a]) (code:comment @#,t{no indirection...}) - a) -(shared ([a (cons 1 b)] (code:comment @#,t{@racket[b] is early...}) - [b a]) - a) +(eval:error (shared ([a a]) (code:comment @#,t{no indirection...}) + a)) +(eval:error (shared ([a (cons 1 b)] (code:comment @#,t{@racket[b] is early...}) + [b a]) + a)) (shared ([a (mcons 1 b)] (code:comment @#,t{@racket[b] is patchable...}) [b a]) a) diff --git a/pkgs/racket-doc/scribblings/reference/splicing.scrbl b/pkgs/racket-doc/scribblings/reference/splicing.scrbl index d657dfd1c6..1d24b111af 100644 --- a/pkgs/racket-doc/scribblings/reference/splicing.scrbl +++ b/pkgs/racket-doc/scribblings/reference/splicing.scrbl @@ -2,9 +2,9 @@ @(require "mz.rkt" (for-label racket/splicing racket/stxparam racket/local)) @(define splice-eval (make-base-eval)) -@interaction-eval[#:eval splice-eval (require racket/splicing - racket/stxparam - (for-syntax racket/base))] +@examples[#:hidden #:eval splice-eval (require racket/splicing + racket/stxparam + (for-syntax racket/base))] @title[#:tag "splicing"]{Local Binding with Splicing Body} @@ -35,7 +35,7 @@ definition context (in the same way as for @racket[begin]). (splicing-let-syntax ([one (lambda (stx) #'1)]) (define o one)) o -one +(eval:error one) ] When a splicing binding form occurs in a @tech{top-level context} or @@ -46,9 +46,10 @@ once during compilation as in @racket[let-syntax], etc. @examples[ #:eval splice-eval -(splicing-letrec ([x bad] - [bad 1]) - x)] +(eval:error + (splicing-letrec ([x bad] + [bad 1]) + x))] If a definition within a splicing form is intended to be local to the splicing body, then the identifier should have a true value for the diff --git a/pkgs/racket-doc/scribblings/reference/string-ports.scrbl b/pkgs/racket-doc/scribblings/reference/string-ports.scrbl index 0c53ddba87..9894e605ca 100644 --- a/pkgs/racket-doc/scribblings/reference/string-ports.scrbl +++ b/pkgs/racket-doc/scribblings/reference/string-ports.scrbl @@ -2,7 +2,7 @@ @(require "mz.rkt") @(define sp-eval (make-base-eval)) -@(interaction-eval #:eval sp-eval (require racket/list)) +@examples[#:hidden #:eval sp-eval (require racket/list)] @title[#:tag "stringport"]{String Ports} diff --git a/pkgs/racket-doc/scribblings/reference/strings.scrbl b/pkgs/racket-doc/scribblings/reference/strings.scrbl index 9439bb362a..97427350e8 100644 --- a/pkgs/racket-doc/scribblings/reference/strings.scrbl +++ b/pkgs/racket-doc/scribblings/reference/strings.scrbl @@ -378,7 +378,7 @@ allocated string).} @note-lib[racket/string] @(define string-eval (make-base-eval)) -@(interaction-eval #:eval string-eval (require racket/string racket/list)) +@examples[#:hidden #:eval string-eval (require racket/string racket/list)] @defproc[(string-append* [str string?] ... [strs (listof string?)]) string?]{ @; Note: this is exactly the same description as the one for append* diff --git a/pkgs/racket-doc/scribblings/reference/struct.scrbl b/pkgs/racket-doc/scribblings/reference/struct.scrbl index 4fc17890de..1d0aa270ba 100644 --- a/pkgs/racket-doc/scribblings/reference/struct.scrbl +++ b/pkgs/racket-doc/scribblings/reference/struct.scrbl @@ -197,52 +197,52 @@ The result of @racket[make-struct-type] is five values: @examples[ #:eval struct-eval -(define-values (struct:a make-a a? a-ref a-set!) - (make-struct-type 'a #f 2 1 'uninitialized)) -(define an-a (make-a 'x 'y)) + +(eval:no-prompt + (define-values (struct:a make-a a? a-ref a-set!) + (make-struct-type 'a #f 2 1 'uninitialized)) + (define an-a (make-a 'x 'y))) + (a-ref an-a 1) (a-ref an-a 2) (define a-first (make-struct-field-accessor a-ref 0)) (a-first an-a) -] -@interaction[ -#:eval struct-eval -(define-values (struct:b make-b b? b-ref b-set!) - (make-struct-type 'b struct:a 1 2 'b-uninitialized)) -(define a-b (make-b 'x 'y 'z)) +(eval:no-prompt + (define-values (struct:b make-b b? b-ref b-set!) + (make-struct-type 'b struct:a 1 2 'b-uninitialized)) + (define a-b (make-b 'x 'y 'z))) + (a-ref a-b 1) (a-ref a-b 2) (b-ref a-b 0) (b-ref a-b 1) (b-ref a-b 2) -] -@interaction[ -#:eval struct-eval -(define-values (struct:c make-c c? c-ref c-set!) - (make-struct-type - 'c struct:b 0 0 #f null (make-inspector) #f null - (code:comment #,(t "guard checks for a number, and makes it inexact")) - (lambda (a1 a2 b1 name) - (unless (number? a2) - (error (string->symbol (format "make-~a" name)) - "second field must be a number")) - (values a1 (exact->inexact a2) b1)))) -(make-c 'x 'y 'z) +(eval:no-prompt + (define-values (struct:c make-c c? c-ref c-set!) + (make-struct-type + 'c struct:b 0 0 #f null (make-inspector) #f null + (code:comment #,(t "guard checks for a number, and makes it inexact")) + (lambda (a1 a2 b1 name) + (unless (number? a2) + (error (string->symbol (format "make-~a" name)) + "second field must be a number")) + (values a1 (exact->inexact a2) b1))))) + +(eval:error (make-c 'x 'y 'z)) (define a-c (make-c 'x 2 'z)) (a-ref a-c 1) -]} -@interaction[ -#:eval struct-eval -(define p1 #s(p a b c)) -(define-values (struct:p make-p p? p-ref p-set!) - (make-struct-type 'p #f 3 0 #f null 'prefab #f '(0 1 2))) +(eval:no-prompt + (define p1 #s(p a b c)) + (define-values (struct:p make-p p? p-ref p-set!) + (make-struct-type 'p #f 3 0 #f null 'prefab #f '(0 1 2)))) + (p? p1) (p-ref p1 0) (make-p 'x 'y 'z) -] +]} @defproc[(make-struct-field-accessor [accessor-proc struct-accessor-procedure?] [field-pos exact-nonnegative-integer?] @@ -667,7 +667,7 @@ the inaccessible fields are omitted from the list. (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)) +(eval:error (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) diff --git a/pkgs/racket-doc/scribblings/reference/stx-comp.scrbl b/pkgs/racket-doc/scribblings/reference/stx-comp.scrbl index 762da318bf..8b4478c889 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-comp.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-comp.scrbl @@ -2,7 +2,7 @@ @(require "mz.rkt") @(define stx-eval (make-base-eval)) -@(interaction-eval #:eval stx-eval (require (for-syntax racket/base))) +@examples[#:hidden #:eval stx-eval (require (for-syntax racket/base))] @title[#:tag "stxcmp"]{Syntax Object Bindings} diff --git a/pkgs/racket-doc/scribblings/reference/stx-ops.scrbl b/pkgs/racket-doc/scribblings/reference/stx-ops.scrbl index 9ba322a818..3616be07a1 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-ops.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-ops.scrbl @@ -1,5 +1,5 @@ #lang scribble/doc -@(require "mz.rkt" scribble/eval) +@(require "mz.rkt") @(define stx-eval (make-base-eval)) @(stx-eval '(require (for-syntax racket/base))) diff --git a/pkgs/racket-doc/scribblings/reference/stx-param.scrbl b/pkgs/racket-doc/scribblings/reference/stx-param.scrbl index d17a3d02b5..d6ae7ab106 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-param.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-param.scrbl @@ -1,6 +1,5 @@ #lang scribble/doc @(require "mz.rkt" - scribble/eval (for-label racket/stxparam racket/stxparam-exptime racket/splicing)) @(define the-eval (make-base-eval)) @@ -30,7 +29,7 @@ used as a macro that expands to a use of the target identifier, but @racket[syntax-local-value] of @racket[id] does not produce the target's value. -@defexamples[#:eval the-eval +@examples[#:eval the-eval (define-syntax-parameter current-class #f) (define-syntax-parameter yield (make-rename-transformer #'abort)) (define-syntax-parameter define/public @@ -59,7 +58,7 @@ used as a macro that expands to a use of the target identifier, but @racket[syntax-local-value] of @racket[id] does not produce the target's value. -@defexamples[#:eval the-eval +@examples[#:eval the-eval (define-syntax-parameter abort (syntax-rules ())) (define-syntax forever diff --git a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl index b8816f82f5..e8d6832c95 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl @@ -9,7 +9,7 @@ syntax/intdef)) @(define stx-eval (make-base-eval)) -@(interaction-eval #:eval stx-eval (require (for-syntax racket/base))) +@examples[#:hidden #:eval stx-eval (require (for-syntax racket/base))] @(define (transform-time) @t{This procedure must be called during the dynamic extent of a @tech{syntax transformer} application by the @@ -592,7 +592,7 @@ if not @racket[#f]. If @racket[failure-thunk] is @racket[false], the @examples[#:eval stx-eval (define-syntax (transformer-2 stx) (syntax-local-value #'something-else (λ () (error "no binding")))) - (transformer-2) + (eval:error (transformer-2)) ] @examples[#:eval stx-eval (define-syntax nachos #'(printf "nachos~n")) diff --git a/pkgs/racket-doc/scribblings/reference/syntax-model.scrbl b/pkgs/racket-doc/scribblings/reference/syntax-model.scrbl index d3cf4cb2af..0b9fdab175 100644 --- a/pkgs/racket-doc/scribblings/reference/syntax-model.scrbl +++ b/pkgs/racket-doc/scribblings/reference/syntax-model.scrbl @@ -2,7 +2,7 @@ @(require scribble/struct "mz.rkt" (for-syntax mzscheme)) @(define racket-eval (make-base-eval)) -@(interaction-eval #:eval racket-eval (require (for-syntax racket/base))) +@examples[#:hidden #:eval racket-eval (require (for-syntax racket/base))] @;------------------------------------------------------------------------ @title[#:tag "syntax-model"]{Syntax Model} @@ -893,7 +893,7 @@ bucket-2 (define (odd x) (if (zero? x) #f (even (sub1 x)))) (define (even x) (if (zero? x) #t (odd (sub1 x)))) (odd 17))])) -(defs-and-uses/fail) +(eval:error (defs-and-uses/fail)) (define-syntax defs-and-uses (syntax-rules () diff --git a/pkgs/racket-doc/scribblings/reference/syntax-util.scrbl b/pkgs/racket-doc/scribblings/reference/syntax-util.scrbl index d4125b3507..50a482d9e6 100644 --- a/pkgs/racket-doc/scribblings/reference/syntax-util.scrbl +++ b/pkgs/racket-doc/scribblings/reference/syntax-util.scrbl @@ -36,13 +36,13 @@ in the argument list are automatically converted to symbols. [(make-pred name) (format-id #'name "~a?" (syntax-e #'name))])) (make-pred pair) -(make-pred none-such) +(eval:error (make-pred none-such)) (define-syntax (better-make-pred stx) (syntax-case stx () [(better-make-pred name) (format-id #'name #:source #'name "~a?" (syntax-e #'name))])) -(better-make-pred none-such) +(eval:error (better-make-pred none-such)) ] (Scribble doesn't show it, but the DrRacket pinpoints the location of @@ -108,9 +108,10 @@ is prefixed with the special form name as described under @racket[current-syntax-context]. @examples[#:eval the-eval -(wrong-syntax #'here "expected ~s" 'there) -(parameterize ([current-syntax-context #'(look over here)]) - (wrong-syntax #'here "expected ~s" 'there)) +(eval:error (wrong-syntax #'here "expected ~s" 'there)) +(eval:error + (parameterize ([current-syntax-context #'(look over here)]) + (wrong-syntax #'here "expected ~s" 'there))) ] A macro using @racket[wrong-syntax] might set the syntax context at the very diff --git a/pkgs/racket-doc/scribblings/reference/syntax.scrbl b/pkgs/racket-doc/scribblings/reference/syntax.scrbl index 4308848967..9e2a88413b 100644 --- a/pkgs/racket-doc/scribblings/reference/syntax.scrbl +++ b/pkgs/racket-doc/scribblings/reference/syntax.scrbl @@ -282,7 +282,7 @@ form. See also @racket[module-compiled-language-info], See also @secref["module-eval-model"] and @secref["mod-parse"]. -@defexamples[#:eval (syntax-eval) +@examples[#:eval (syntax-eval) #:once (module duck racket/base (provide num-eggs quack) (define num-eggs 2) @@ -510,13 +510,13 @@ bindings of each @racket[require-spec] are visible for expanding later is not in the set that @racket[require-spec] describes, a syntax error is reported. - @defexamples[#:eval (syntax-eval) + @examples[#:eval (syntax-eval) #:once (require (only-in racket/tcp tcp-listen [tcp-accept my-accept])) tcp-listen my-accept - tcp-accept + (eval:error tcp-accept) ]} @defsubform[(except-in require-spec id ...)]{ Like @@ -525,11 +525,11 @@ bindings of each @racket[require-spec] are visible for expanding later in the set that @racket[require-spec] describes, a syntax error is reported. - @defexamples[#:eval (syntax-eval) + @examples[#:eval (syntax-eval) #:once (require (except-in racket/tcp tcp-listen)) tcp-accept - tcp-listen + (eval:error tcp-listen) ]} @defsubform[(prefix-in prefix-id require-spec)]{ Like @@ -538,7 +538,7 @@ bindings of each @racket[require-spec] are visible for expanding later @racket[prefix-id] is ignored, and instead preserved from the identifiers before prefixing. - @defexamples[#:eval (syntax-eval) + @examples[#:eval (syntax-eval) #:once (require (prefix-in tcp: racket/tcp)) tcp:tcp-accept tcp:tcp-listen @@ -550,7 +550,7 @@ bindings of each @racket[require-spec] are visible for expanding later @racket[orig-id] is not in the set that @racket[require-spec] describes, a syntax error is reported. - @defexamples[#:eval (syntax-eval) + @examples[#:eval (syntax-eval) #:once (require (rename-in racket/tcp (tcp-accept accept) (tcp-listen listen))) @@ -563,7 +563,7 @@ bindings of each @racket[require-spec] are visible for expanding later @racket[require-spec]s have the same identifier name but they do not refer to the same original binding, a syntax error is reported. - @defexamples[#:eval (syntax-eval) + @examples[#:eval (syntax-eval) #:once (require (combine-in (only-in racket/tcp tcp-accept) (only-in racket/tcp tcp-listen))) tcp-accept @@ -588,7 +588,7 @@ bindings of each @racket[require-spec] are visible for expanding later The following example imports bindings only at @tech{phase level} 1, the transform phase: - @interaction[#:eval meta-in-eval + @examples[#:label #f #:eval meta-in-eval (module nest racket (provide (for-syntax meta-eggs) (for-meta 1 meta-chicks) @@ -604,13 +604,13 @@ bindings of each @racket[require-spec] are visible for expanding later #'(void)) (desc) - num-eggs + (eval:error num-eggs) ] The following example imports only bindings at @tech{phase level} 0, the normal phase. - @interaction[#:eval meta-in-eval + @examples[#:label #f #:eval meta-in-eval (require (only-meta-in 0 'nest)) num-eggs ]} @@ -622,7 +622,7 @@ bindings of each @racket[require-spec] are visible for expanding later @tech{label phase level} corresponds to @racket[#f], and a shifting combination that involves @racket[#f] produces @racket[#f]. - @defexamples[#:eval (syntax-eval) + @examples[#:eval (syntax-eval) #:once (module nest racket (provide num-eggs) (define num-eggs 2)) @@ -894,7 +894,7 @@ level} 0 are imported. (let () (local-require racket/control) fcontrol) - fcontrol + (eval:error fcontrol) ]} @@ -944,7 +944,7 @@ as follows. identifier must match (otherwise, the external name could be ambiguous). - @defexamples[#:eval (syntax-eval) + @examples[#:eval (syntax-eval) #:once (module nest racket (provide num-eggs) (define num-eggs 2)) @@ -968,7 +968,7 @@ as follows. macro-introduced imports are not re-exported, unless the @racket[(all-defined-out)] form was introduced at the same time. - @defexamples[#:eval (syntax-eval) + @examples[#:eval (syntax-eval) #:once (module nest racket (provide (all-defined-out)) (define num-eggs 2)) @@ -987,7 +987,7 @@ as follows. macro-introduced imports are not re-exported, unless the @racket[module-path] was introduced at the same time. - @defexamples[#:eval (syntax-eval) + @examples[#:eval (syntax-eval) #:once (module nest racket (provide num-eggs) (define num-eggs 2)) @@ -1003,13 +1003,13 @@ as follows. the relevant @tech{phase level}. The symbolic name for each export is @racket[export-id] instead @racket[orig-d]. - @defexamples[#:eval (syntax-eval) + @examples[#:eval (syntax-eval) #:once (module nest racket (provide (rename-out [count num-eggs])) (define count 2)) (require 'nest) num-eggs - count + (eval:error count) ]} @defsubform[(except-out provide-spec provide-spec ...)]{ Like the @@ -1019,7 +1019,7 @@ as follows. reported. The symbolic export name information in the latter @racket[provide-spec]s is ignored; only the bindings are used. - @defexamples[#:eval (syntax-eval) + @examples[#:eval (syntax-eval) #:once (module nest racket (provide (except-out (all-defined-out) num-chicks)) @@ -1027,14 +1027,14 @@ as follows. (define num-chicks 3)) (require 'nest) num-eggs - num-chicks + (eval:error num-chicks) ]} @defsubform[(prefix-out prefix-id provide-spec)]{ Like @racket[provide-spec], but with each symbolic export name from @racket[provide-spec] prefixed with @racket[prefix-id]. - @defexamples[#:eval (syntax-eval) + @examples[#:eval (syntax-eval) #:once (module nest racket (provide (prefix-out chicken: num-eggs)) (define num-eggs 2)) @@ -1055,7 +1055,7 @@ as follows. accessor and mutator bindings of the super-type are @italic{not} included by @racket[struct-out] for export. - @defexamples[#:eval (syntax-eval) + @examples[#:eval (syntax-eval) #:once (module nest racket (provide (struct-out egg)) (struct egg (color wt))) @@ -1066,7 +1066,7 @@ as follows. @defsubform[(combine-out provide-spec ...)]{ The union of the @racket[provide-spec]s. - @defexamples[#:eval (syntax-eval) + @examples[#:eval (syntax-eval) #:once (module nest racket (provide (combine-out num-eggs num-chicks)) (define num-eggs 2) @@ -1084,7 +1084,7 @@ as follows. For more details, see @secref["modprotect"]. The @racket[provide-spec] must specify only bindings that are defined within the exporting module. - @examples[#:eval (syntax-eval) + @examples[#:eval (syntax-eval) #:once (module nest racket (provide num-eggs (protect-out num-chicks)) (define num-eggs 2) @@ -1102,7 +1102,7 @@ as follows. (require 'nest) (list num-eggs num-chicks) (weak-eval 'num-eggs) - (weak-eval 'num-chicks) + (eval:error (weak-eval 'num-chicks)) ]} @specsubform[#:literals (for-meta) @@ -1118,7 +1118,7 @@ as follows. @racket[all-from-out] exports bindings imported with a shift by @racket[phase-level]. - @examples[#:eval (syntax-eval) + @examples[#:eval (syntax-eval) #:once (module nest racket (begin-for-syntax (define eggs 2)) @@ -1132,11 +1132,12 @@ as follows. (test-eggs) chickens - (module broken-nest racket - (define eggs 2) - (define chickens 3) - (provide (for-syntax eggs) - chickens)) + (eval:error + (module broken-nest racket + (define eggs 2) + (define chickens 3) + (provide (for-syntax eggs) + chickens))) (module nest2 racket (begin-for-syntax @@ -1309,7 +1310,7 @@ Like @racket[require-spec], but including only imports whose names match @racket[regexp]. The @racket[regexp] must be a literal regular expression (see @secref["regexp"]). -@defexamples[#:eval (syntax-eval) +@examples[#:eval (syntax-eval) #:once (module zoo racket/base (provide tunafish swordfish blowfish monkey lizard ant) @@ -1324,7 +1325,7 @@ Like @racket[require-spec], but including only imports whose names tunafish swordfish blowfish -monkey +(eval:error monkey) ]} @defform[(subtract-in require-spec subtracted-spec ...)]{ @@ -1332,7 +1333,7 @@ monkey Like @racket[require-spec], but omitting those imports that would be imported by one of the @racket[subtracted-spec]s. -@defexamples[#:eval (syntax-eval) +@examples[#:eval (syntax-eval) #:once (module earth racket (provide land sea air) (define land 1) @@ -1350,7 +1351,7 @@ Like @racket[require-spec], but omitting those imports that would be (require racket/require) (require (subtract-in 'solar-system 'earth)) -land +(eval:error land) aliens ]} @@ -1517,7 +1518,7 @@ introduces @racketidfont{#%datum} identifiers. @mz-examples[ (#%datum . 10) (#%datum . x) -(#%datum . #:x) +(eval:error (#%datum . #:x)) ] } @@ -1532,14 +1533,14 @@ expression. @mz-examples[ (#%expression (+ 1 2)) -(#%expression (define x 10)) +(eval:error (#%expression (define x 10))) ] The @racket[#%expression] form is helpful in recursive definition contexts where expanding a subsequent definition can provide compile-time information for the current expression. For example, consider a @racket[define-sym-case] macro that simply records some symbols at compile-time in a given identifier. -@interaction/no-prompt[#:eval meta-in-eval +@examples[#:label #f #:no-prompt #:eval meta-in-eval (define-syntax (define-sym-case stx) (syntax-case stx () [(_ id sym ...) @@ -1548,7 +1549,7 @@ macro that simply records some symbols at compile-time in a given identifier. '(sym ...))]))] and then a variant of @racket[case] that checks to make sure the symbols used in the expression match those given in the earlier definition: -@interaction/no-prompt[#:eval meta-in-eval +@examples[#:label #f #:no-prompt #:eval meta-in-eval (define-syntax (sym-case stx) (syntax-case stx () [(_ id val-expr [(sym) expr] ...) @@ -1575,18 +1576,19 @@ If the definition follows the use like this, then the @racket[define-sym-case] macro does not have a chance to bind @racket[id] and the @racket[sym-case] macro signals an error: -@interaction[#:eval meta-in-eval -(let () - (sym-case land-creatures 'bear - [(bear) 1] - [(fox) 2]) - (define-sym-case land-creatures bear fox)) +@examples[#:label #f #:eval meta-in-eval +(eval:error + (let () + (sym-case land-creatures 'bear + [(bear) 1] + [(fox) 2]) + (define-sym-case land-creatures bear fox))) ] But if the @racket[sym-case] is wrapped in an @racket[#%expression], then the expander does not need to expand it to know it is an expression and it moves on to the @racket[define-sym-case] expression. -@interaction[#:eval meta-in-eval +@examples[#:label #f #:eval meta-in-eval (let () (#%expression (sym-case sea-creatures 'whale [(whale) 1] @@ -1740,7 +1742,7 @@ expander introduces @racketidfont{#%app} identifiers. @mz-examples[ (#%app + 1 2) (#%app (lambda (x #:arg y) (list y x)) #:arg 2 1) -(#%app cons) +(eval:error (#%app cons)) ]} @defform*[[(#%plain-app proc-expr arg-expr ...) @@ -2342,13 +2344,14 @@ in @math{O(log N)} time for @math{N} @racket[datum]s. (case (list 'quote 'x) [(x) "ex"] [('x) "quoted ex"]) -] -@def+int[ -(define (classify c) - (case (char-general-category c) - [(ll lu lt ln lo) "letter"] - [(nd nl no) "number"] - [else "other"])) + +(eval:no-prompt + (define (classify c) + (case (char-general-category c) + [(ll lu lt ln lo) "letter"] + [(nd nl no) "number"] + [else "other"]))) + (classify #\A) (classify #\1) (classify #\!) @@ -2394,19 +2397,20 @@ In a context that allows @tech{liberal expansion} of @racket[define], @racket[lambda] form with keyword arguments or @racket[args] include keyword arguments. -@defexamples[ -(define x 10) +@examples[ +(eval:no-prompt (define x 10)) x -] -@def+int[ -(define (f x) - (+ x 1)) -(f 10) -] -@def+int[ -(define ((f x) [y 20]) - (+ x y)) +(eval:no-prompt + (define (f x) + (+ x 1))) + +(f 10) + +(eval:no-prompt + (define ((f x) [y 20]) + (+ x y))) + ((f 10) 30) ((f 10)) ] @@ -2427,7 +2431,7 @@ and the top-level mapping of each @racket[id] (in the @techlink{namespace} linked with the compiled definition) is set to the binding at the same time. -@defexamples[ +@examples[ (define-values () (values)) (define-values (x y z) (values 1 2 3)) z @@ -2459,7 +2463,7 @@ expands to a definition of the first form where the @racket[expr] is a In an @tech{internal-definition context} (see @secref["intdef-body"]), a @racket[define-syntax] form introduces a local binding. -@defexamples[#:eval (syntax-eval) +@examples[#:eval (syntax-eval) #:once (define-syntax foo (syntax-rules () ((_ a ...) @@ -2490,7 +2494,7 @@ binding; see @secref["macro-introduced-bindings"]. In an @tech{internal-definition context} (see @secref["intdef-body"]), a @racket[define-syntaxes] form introduces local bindings. -@defexamples[#:eval (syntax-eval) +@examples[#:eval (syntax-eval) #:once (define-syntaxes (foo1 foo2 foo3) (let ([transformer1 (lambda (syntax-object) (syntax-case syntax-object () @@ -2526,14 +2530,14 @@ form must be expanded before the use is expanded). In particular, mutually recursive functions bound by @racket[define-for-syntax] must be defined by the same @racket[define-for-syntax] form. -@defexamples[#:eval (syntax-eval) +@examples[#:eval (syntax-eval) #:once (define-for-syntax helper 2) (define-syntax (make-two syntax-object) (printf "helper is ~a\n" helper) #'2) (make-two) (code:comment @#,t{`helper' is not bound in the runtime phase}) -helper +(eval:error helper) (define-for-syntax (filter-ids ids) (filter identifier? ids)) @@ -2552,7 +2556,7 @@ Like @racket[define-for-syntax], but @racket[expr] must produce as many values as supplied @racket[id]s, and all of the @racket[id]s are bound (at @tech{phase level} 1).} -@defexamples[#:eval (syntax-eval) +@examples[#:eval (syntax-eval) #:once (define-values-for-syntax (foo1 foo2) (values 1 2)) (define-syntax (bar syntax-object) (printf "foo1 is ~a foo2 is ~a\n" foo1 foo2) @@ -2768,14 +2772,14 @@ variable} that has not been defined, the @exnraise[exn:fail:contract]. See also @racket[compile-allow-set!-undefined]. -@defexamples[ +@examples[ (define x 12) (set! x (add1 x)) x (let ([x 5]) (set! x (add1 x)) x) -(set! i-am-not-defined 10) +(eval:error (set! i-am-not-defined 10)) ]} @defform[(set!-values (id ...) expr)]{ @@ -2859,7 +2863,7 @@ other way than as @racket[(#,unquote-id _expr)] or (eval:alts (#,(racket quasiquote) (0 1 2)) `(0 1 2)) (eval:alts (#,(racket quasiquote) (0 (#,unquote-id (+ 1 2)) 4)) `(0 ,(+ 1 2) 4)) (eval:alts (#,(racket quasiquote) (0 (#,unquote-splicing-id (list 1 2)) 4)) `(0 ,@(list 1 2) 4)) -(eval:alts (#,(racket quasiquote) (0 (#,unquote-splicing-id 1) 4)) `(0 ,@1 4)) +(eval:error (eval:alts (#,(racket quasiquote) (0 (#,unquote-splicing-id 1) 4)) `(0 ,@1 4))) (eval:alts (#,(racket quasiquote) (0 (#,unquote-splicing-id 1))) `(0 ,@1)) ] diff --git a/pkgs/racket-doc/scribblings/reference/trace.scrbl b/pkgs/racket-doc/scribblings/reference/trace.scrbl index e0f83fc39e..f5eeb393f4 100644 --- a/pkgs/racket-doc/scribblings/reference/trace.scrbl +++ b/pkgs/racket-doc/scribblings/reference/trace.scrbl @@ -1,6 +1,5 @@ #lang scribble/doc -@(require "mz.rkt" (for-label racket/trace) - scribble/eval) +@(require "mz.rkt" (for-label racket/trace)) @(begin (define ev (make-base-eval)) (ev '(require racket/trace)) diff --git a/pkgs/racket-doc/scribblings/reference/values.scrbl b/pkgs/racket-doc/scribblings/reference/values.scrbl index fb7f3d678f..614a0a42bc 100644 --- a/pkgs/racket-doc/scribblings/reference/values.scrbl +++ b/pkgs/racket-doc/scribblings/reference/values.scrbl @@ -31,5 +31,5 @@ the @racket[call-with-values] call. @examples[ (call-with-values (lambda () (values 1 2)) +) -(call-with-values (lambda () 1) (lambda (x y) (+ x y))) +(eval:error (call-with-values (lambda () 1) (lambda (x y) (+ x y)))) ]} diff --git a/pkgs/racket-doc/scribblings/reference/vectors.scrbl b/pkgs/racket-doc/scribblings/reference/vectors.scrbl index 8f8141aa44..9ff98f7df7 100644 --- a/pkgs/racket-doc/scribblings/reference/vectors.scrbl +++ b/pkgs/racket-doc/scribblings/reference/vectors.scrbl @@ -151,8 +151,8 @@ _i)] is the value produced by @racket[(proc _i)]. @note-lib[racket/vector] @(define vec-eval (make-base-eval)) -@(interaction-eval #:eval vec-eval - (require racket/vector)) +@examples[#:hidden #:eval vec-eval + (require racket/vector)] @defproc[(vector-set*! [vec (and/c vector? (not/c immutable?))] [pos exact-nonnegative-integer?] From 39c2a08d316d42d3e49ca4769837892344c14de5 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 11 Dec 2015 19:27:57 -0700 Subject: [PATCH 161/369] make tests/zo-path inspect all installation-scope packages --- pkgs/racket-test/tests/zo-path.rkt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-test/tests/zo-path.rkt b/pkgs/racket-test/tests/zo-path.rkt index e211ea2600..4c62b3ae75 100644 --- a/pkgs/racket-test/tests/zo-path.rkt +++ b/pkgs/racket-test/tests/zo-path.rkt @@ -28,9 +28,19 @@ (check-one name))) (module+ main - (fold-files (check-content #rx"[.](?:zo|dep)$") + (require pkg/lib) + + (define zo/dep-content (check-content #rx"[.](?:zo|dep)$")) + + (fold-files zo/dep-content (void) - (find-pkgs-dir)) + (find-collects-dir)) + + (define cache (make-hash)) + (for ([pkg (in-list (installed-pkg-names #:scope 'installation))]) + (fold-files zo/dep-content + (void) + (pkg-directory pkg #:cache cache))) ;; Check rendered docs, too: (fold-files (check-content #rx"[.](?:html)$") From d66af86a58fe08a4f2202ceb1fde8738b5626f8b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 12 Dec 2015 07:39:17 -0700 Subject: [PATCH 162/369] JIT on ARM: add assertion to check long-jump mode The same assertion is present already in Thumb mode, but add it to non-Thumb mode. --- racket/src/racket/src/lightning/arm/core.h | 1 + 1 file changed, 1 insertion(+) diff --git a/racket/src/racket/src/lightning/arm/core.h b/racket/src/racket/src/lightning/arm/core.h index af5e793796..c6783cac6e 100644 --- a/racket/src/racket/src/lightning/arm/core.h +++ b/racket/src/racket/src/lightning/arm/core.h @@ -1329,6 +1329,7 @@ arm_branch(jit_state_t _jitp, int cc, jit_insn *i0) _CC_B(cc, d & 0x00ffffff); } else { int im = (int)i0; + jit_assert(_jitl.long_jumps); if (jit_armv6t_p()) { _CC_MOVWI(cc, JIT_TMP, _jit_US(im)); _CC_MOVTI(cc, JIT_TMP, _jit_US((unsigned)im >> 16)); From c6b8ba7c4a40e9a0933df2661332167d55c8bf80 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 12 Dec 2015 08:13:34 -0700 Subject: [PATCH 163/369] JIT: add missing checks for buffer space --- racket/src/racket/src/jitcommon.c | 1 + racket/src/racket/src/jitinline.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/racket/src/racket/src/jitcommon.c b/racket/src/racket/src/jitcommon.c index e58e30ec06..7c271f64b3 100644 --- a/racket/src/racket/src/jitcommon.c +++ b/racket/src/racket/src/jitcommon.c @@ -3967,6 +3967,7 @@ static int more_common1(mz_jit_state *jitter, void *_data) /* -3 here means "don't pop the arguments"; need regular argument handling via `reftop` for tail calls */ scheme_generate_non_tail_call(jitter, -3, 0, 1, multi_ok, 0, 0, 1, 0, 0, reftop); + CHECK_LIMIT(); scheme_jit_register_sub_func(jitter, code, scheme_false); } diff --git a/racket/src/racket/src/jitinline.c b/racket/src/racket/src/jitinline.c index f22d78a755..2e6e6b0a7b 100644 --- a/racket/src/racket/src/jitinline.c +++ b/racket/src/racket/src/jitinline.c @@ -2166,6 +2166,7 @@ int scheme_generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_ if (simple2 && !order_matters && already_in_register(rand1, jitter)) { scheme_generate(rand1, jitter, 0, 0, 0, JIT_R1, NULL, NULL); /* no sync... */ + CHECK_LIMIT(); scheme_generate(rand2, jitter, 0, 0, 0, JIT_R0, NULL, NULL); /* no sync... */ direction = -1; } else { @@ -3426,6 +3427,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i scheme_mz_unbox_save(jitter, &ubs); /* no unboxing of vector and index arguments */ scheme_generate_two_args(app->rand1, app->rand2, jitter, 1, 2); + CHECK_LIMIT(); scheme_mz_unbox_restore(jitter, &ubs); CHECK_LIMIT(); @@ -3468,6 +3470,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i is_u = IS_NAMED_PRIM(rator, "unsafe-u16vector-ref"); scheme_generate_two_args(app->rand1, app->rand2, jitter, 1, 2); + CHECK_LIMIT(); jit_ldxi_p(JIT_R0, JIT_R0, (intptr_t)&(((Scheme_Structure *)0x0)->slots[0])); jit_ldxi_p(JIT_R0, JIT_R0, (intptr_t)&SCHEME_CPTR_VAL(0x0)); @@ -3484,6 +3487,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i } else if (IS_NAMED_PRIM(rator, "list-ref") || IS_NAMED_PRIM(rator, "list-tail")) { scheme_generate_two_args(app->rand1, app->rand2, jitter, 1, 2); + CHECK_LIMIT(); mz_rs_sync(); if (IS_NAMED_PRIM(rator, "list-ref")) @@ -3518,6 +3522,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 (IS_NAMED_PRIM(rator, "unsafe-list-ref")) (void)jit_calli(sjc.list_ref_code); @@ -4255,6 +4260,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int 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 */ + CHECK_LIMIT(); jit_movr_p(JIT_R2, JIT_R0); } } @@ -4451,6 +4457,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int got_two = 1; mz_runstack_skipped(jitter, 1); scheme_generate_app(app, NULL, 2, jitter, 0, 0, 0, 2); + CHECK_LIMIT(); } if (scheme_can_unbox_inline(app->args[3], 5, JIT_FPUSEL_FPR_NUM(extfl)-1, 1, extfl)) From d01aec1b32baa0f16837a8c22dd1e694ac2d1e98 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 12 Dec 2015 14:11:17 -0700 Subject: [PATCH 164/369] JIT: always use buffer padding of 200 The main intent of this change is to raise the buffer size for ARM, but that would leave only 32-bit x86 at size 100, so just make it size large for all machines. --- racket/src/racket/src/jit.h | 6 +----- racket/src/racket/src/jitcall.c | 1 + 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/racket/src/racket/src/jit.h b/racket/src/racket/src/jit.h index 694c8823aa..16901f34bd 100644 --- a/racket/src/racket/src/jit.h +++ b/racket/src/racket/src/jit.h @@ -1315,11 +1315,7 @@ static void emit_indentation(mz_jit_state *jitter) /* jitstate */ /**********************************************************************/ -#if defined(SIXTY_FOUR_BIT_INTEGERS) || defined(MZ_USE_JIT_PPC) -# define JIT_BUFFER_PAD_SIZE 200 -#else -# define JIT_BUFFER_PAD_SIZE 100 -#endif +#define JIT_BUFFER_PAD_SIZE 200 #define PAST_LIMIT() ((uintptr_t)jit_get_raw_ip() > (uintptr_t)jitter->limit) #define CHECK_LIMIT() if (PAST_LIMIT()) return past_limit(jitter, __FILE__, __LINE__); diff --git a/racket/src/racket/src/jitcall.c b/racket/src/racket/src/jitcall.c index 6276c1f76d..2951c232b7 100644 --- a/racket/src/racket/src/jitcall.c +++ b/racket/src/racket/src/jitcall.c @@ -1709,6 +1709,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, NULL); + CHECK_LIMIT(); mz_rs_sync(); return 1; From f7c67f5c450d30c439b671667baf7dce0a5eb271 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 13 Dec 2015 16:37:56 -0700 Subject: [PATCH 165/369] incremental GC: always use generation 1/2 in incremental mode Also, make nursery 1/4 as big in incremental mode, and correspondingly tune the amount of work to perform per collection by 1/4 its old value. Using generation 1/2 reduces fragmentation that would otherwise be increase by a smaller nursery. --- racket/src/racket/gc2/newgc.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 7b4aad3149..4ccbeed7c8 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -254,13 +254,22 @@ MAYBE_UNUSED static void GCVERBOSEprintf(NewGC *gc, const char *fmt, ...) { /* 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)) +#define AGE_GEN_0_TO_GEN_HALF(gc) (((gc)->memory_in_use > (GEN0_MAX_SIZE * 8)) \ + || (gc)->started_incremental) /* Incremental mode */ static int always_collect_incremental_on_minor = 0; -#define INCREMENTAL_COLLECT_FUEL_PER_100M (16 * 1024) -#define INCREMENTAL_REPAIR_FUEL_PER_100M 128 -#define INCREMENTAL_MINOR_REQUEST_DIVISOR 4 +#define INCREMENTAL_COLLECT_FUEL_PER_100M (4 * 1024) +#define INCREMENTAL_REPAIR_FUEL_PER_100M 32 + +/* Shrink the nursery in incremental mode, so that we more frequently + work on a major collection. Tune this parameter in combination with + the fuel parameters above. */ +#define GEN0_INCREMENTAL_MAX_DIVISOR 4 + +/* Factor to shrink incremental-mode fuel when a GC is triggered by + (collect-garbage 'minor): */ +#define INCREMENTAL_MINOR_REQUEST_DIVISOR 1 /* Conservatively force a major GC after a certain number of minor GCs. It should be ok to set this value @@ -2022,6 +2031,10 @@ inline static void reset_nursery(NewGC *gc) || (gc->memory_in_use > GEN0_MAX_SIZE)) /* => overflow */ new_gen0_size = GEN0_MAX_SIZE; + if (gc->started_incremental + && (new_gen0_size > (GEN0_MAX_SIZE / GEN0_INCREMENTAL_MAX_DIVISOR))) + new_gen0_size = GEN0_MAX_SIZE / GEN0_INCREMENTAL_MAX_DIVISOR; + resize_gen0(gc, new_gen0_size); } From 8bd47f3f8a562965514c6d5040cc0a2c381fc5f3 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 14 Dec 2015 10:52:23 -0600 Subject: [PATCH 166/369] Fix instrumentation of struct/dc. Unbreaks the contract profiler. --- .../racket/contract/private/struct-dc.rkt | 48 ++++++++++++------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/racket/collects/racket/contract/private/struct-dc.rkt b/racket/collects/racket/contract/private/struct-dc.rkt index 0a893c8f32..94063ad1cf 100644 --- a/racket/collects/racket/contract/private/struct-dc.rkt +++ b/racket/collects/racket/contract/private/struct-dc.rkt @@ -343,7 +343,8 @@ (define-values (new-chaperone-args new-impersonate-args) (cond [(invariant? subcontract) - (unless (with-continuation-mark contract-continuation-mark-key blame + (unless (with-continuation-mark contract-continuation-mark-key + (cons blame neg-party) (apply (invariant-dep-proc subcontract) dep-args)) (raise-invariant-blame-failure blame neg-party v (reverse dep-args) @@ -351,7 +352,8 @@ (values chaperone-args impersonate-args)] [(immutable? subcontract) (define (chk fld v) (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key + (cons blame neg-party) (proj v neg-party))) (chk #f (sel v)) ;; check the field contract immediately (values (if (flat-contract? (indep-ctc subcontract)) @@ -362,7 +364,8 @@ (values (list* sel (cache-λ (fld v) (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key + (cons blame neg-party) (proj v neg-party))) chaperone-args) impersonate-args)] @@ -372,23 +375,27 @@ (list* sel (λ (fld v) (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key + (cons blame neg-party) (proj v neg-party))) (mutable-set subcontract) (λ (fld v) (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key + (cons blame neg-party) (mut-proj v neg-party))) impersonate-args)) (values (list* sel (λ (fld v) (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key + (cons blame neg-party) (proj v neg-party))) (mutable-set subcontract) (λ (fld v) (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key + (cons blame neg-party) (mut-proj v neg-party))) chaperone-args) impersonate-args))] @@ -397,7 +404,8 @@ (cond [(dep-immutable? subcontract) (define (chk fld v) (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key + (cons blame neg-party) (proj v neg-party))) (chk #f (sel v)) ;; check the field contract immediately (values (if (flat-contract? dep-ctc) @@ -408,7 +416,8 @@ (values (list* sel (cache-λ (fld v) (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key + (cons blame neg-party) (proj v neg-party))) chaperone-args) impersonate-args)] @@ -418,12 +427,14 @@ (values (list* sel (λ (fld v) (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key + (cons blame neg-party) (proj v neg-party))) (dep-mutable-set subcontract) (λ (fld v) (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key + (cons blame neg-party) (mut-proj v neg-party))) chaperone-args) impersonate-args) @@ -431,12 +442,14 @@ (list* sel (λ (fld v) (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key + (cons blame neg-party) (proj v neg-party))) (dep-mutable-set subcontract) (λ (fld v) (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key + (cons blame neg-party) (mut-proj v neg-party))) impersonate-args)))] [(dep-on-state-immutable? subcontract) @@ -444,7 +457,8 @@ (values (list* sel (λ (strct val) (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key + (cons blame neg-party) (build-dep-on-state-proj (base-struct/dc-subcontracts ctc) subcontract strct orig-indy-projs orig-indy-blames blame neg-party val))) @@ -454,12 +468,14 @@ (proj (sel v) neg-party) (define (get-chap-proc strct val) (with-continuation-mark - contract-continuation-mark-key blame + contract-continuation-mark-key + (cons blame neg-party) (build-dep-on-state-proj (base-struct/dc-subcontracts ctc) subcontract strct orig-indy-projs orig-indy-blames blame neg-party val))) (define (set-chap-proc strct val) - (with-continuation-mark contract-continuation-mark-key blame + (with-continuation-mark contract-continuation-mark-key + (cons blame neg-party) (build-dep-on-state-proj (base-struct/dc-subcontracts ctc) subcontract strct orig-mut-indy-projs orig-mut-indy-blames mut-blame neg-party val))) From bd77a0102c7a92d4766e9fce4938fff2821f1209 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 14 Dec 2015 12:53:21 -0600 Subject: [PATCH 167/369] add blame-missing-party? and document it and blame-add-missing-party --- .../scribblings/reference/contracts.scrbl | 74 +++++++++++-------- .../racket/contract/private/blame.rkt | 1 + 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index 93888ce6c7..3497b3662e 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -2140,6 +2140,39 @@ contracts. The error messages assume that the function named by This predicate recognizes @|blame-objects|. } +@defproc[(raise-blame-error [b blame?] + [x any/c] + [fmt (or/c string? + (listof (or/c string? + 'given 'given: + 'expected 'expected:)))] + [v any/c] ...) + none/c]{ + +Signals a contract violation. The first argument, @racket[b], records the +current blame information, including positive and negative parties, the name of +the contract, the name of the value, and the source location of the contract +application. The second argument, @racket[x], is the value that failed to +satisfy the contract. + +The remaining arguments are a format string, +@racket[fmt], and its arguments, @racket[v ...], specifying an error message +specific to the precise violation. + +If @racket[fmt] is a list, then the elements are concatenated together +(with spaces added, unless there are already spaces at the ends of the strings), +after first replacing symbols with either their string counterparts, or +replacing @racket['given] with @racket["produced"] and +@racket['expected] with @racket["promised"], depending on whether or not +the @racket[b] argument has been swapped or not (see @racket[blame-swap]). + +If @racket[fmt] contains the symbols @racket['given:] or @racket['expected:], +they are replaced like @racket['given:] and @racket['expected:] are, but +the replacements are prefixed with the string @racket["\n "] to conform +to the error message guidelines in @secref["err-msg-conventions"]. + +} + @defproc[(blame-add-context [blame blame?] [context (or/c string? #f)] [#:important important (or/c string? #f) #f] @@ -2240,39 +2273,18 @@ the other; both are provided for convenience and clarity. and negative parties of @racket[b] respectively. } -@defproc[(raise-blame-error [b blame?] - [x any/c] - [fmt (or/c string? - (listof (or/c string? - 'given 'given: - 'expected 'expected:)))] - [v any/c] ...) - none/c]{ - -Signals a contract violation. The first argument, @racket[b], records the -current blame information, including positive and negative parties, the name of -the contract, the name of the value, and the source location of the contract -application. The second argument, @racket[x], is the value that failed to -satisfy the contract. - -The remaining arguments are a format string, -@racket[fmt], and its arguments, @racket[v ...], specifying an error message -specific to the precise violation. - -If @racket[fmt] is a list, then the elements are concatenated together -(with spaces added, unless there are already spaces at the ends of the strings), -after first replacing symbols with either their string counterparts, or -replacing @racket['given] with @racket["produced"] and -@racket['expected] with @racket["promised"], depending on whether or not -the @racket[b] argument has been swapped or not (see @racket[blame-swap]). - -If @racket[fmt] contains the symbols @racket['given:] or @racket['expected:], -they are replaced like @racket['given:] and @racket['expected:] are, but -the replacements are prefixed with the string @racket["\n "] to conform -to the error message guidelines in @secref["err-msg-conventions"]. - +@defproc[(blame-missing-party? [b blame?]) boolean?]{ + Returns @racket[#t] when @racket[b] does not have both parties. } +@defproc[(blame-add-missing-party? [b (and/c blame? blame-missing-party?)] + [missing-party any/c]) + (and/c blame? (not/c blame-missing-party?))]{ + Produces a new blame object like @racket[b], except that the missing + party is replaced with @racket[missing-party]. +} + + @defstruct[(exn:fail:contract:blame exn:fail:contract) ([object blame?])]{ This exception is raised to signal a contract error. The @racket[object] field contains a @|blame-object| associated with a contract violation. diff --git a/racket/collects/racket/contract/private/blame.rkt b/racket/collects/racket/contract/private/blame.rkt index 4779984e22..da3b3b925c 100644 --- a/racket/collects/racket/contract/private/blame.rkt +++ b/racket/collects/racket/contract/private/blame.rkt @@ -18,6 +18,7 @@ blame-context blame-add-missing-party + blame-missing-party? raise-blame-error current-blame-format From bf1ba809ae1364fedf566e30f97265e1b6dbf414 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 14 Dec 2015 13:08:06 -0600 Subject: [PATCH 168/369] Test that contract profiler instrumentation always has complete blame info. --- pkgs/racket-test/tests/racket/contract/prof.rkt | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-test/tests/racket/contract/prof.rkt b/pkgs/racket-test/tests/racket/contract/prof.rkt index c6ff702575..9b1676d944 100644 --- a/pkgs/racket-test/tests/racket/contract/prof.rkt +++ b/pkgs/racket-test/tests/racket/contract/prof.rkt @@ -12,18 +12,27 @@ (only-in racket/contract/private/blame blame-positive blame-negative - blame?)) + blame?) + (only-in racket/contract/combinator + blame-missing-party?)) (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 complete-blame + (or (not mark-info) + (pair? mark-info) ; missing party is provided + (not (blame-missing-party? mark-info)))) ; no missing party (define (get-party selector) (and mark-info - (or (selector (car mark-info)) - (cdr mark-info)))) + (if (pair? mark-info) + (or (selector (car mark-info)) + (cdr mark-info)) + (selector mark-info)))) (and mark-info + complete-blame (let ([pos (get-party blame-positive)] [neg (get-party blame-negative)]) (or (equal? pos who) @@ -100,3 +109,5 @@ (eval '(require 'prof3)) (eval '(f #:x 11))) 11)) + +;; TODO add struct/dc tests From b8df0a38a2a09453f3711177bd01fb3a2f9863e9 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 14 Dec 2015 13:57:03 -0600 Subject: [PATCH 169/369] Add instrumentation for optimized struct/dc. --- .../racket/contract/private/struct-dc.rkt | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/racket/collects/racket/contract/private/struct-dc.rkt b/racket/collects/racket/contract/private/struct-dc.rkt index 94063ad1cf..4d037705a8 100644 --- a/racket/collects/racket/contract/private/struct-dc.rkt +++ b/racket/collects/racket/contract/private/struct-dc.rkt @@ -1432,24 +1432,28 @@ #:exp ;; if this is #t, when we have to avoid putting the property on here. (if (null? s-chap-code) - #`(if (pred? #,(opt/info-val opt/info)) - (begin - #,@s-fo-code - #,(opt/info-val opt/info)) - (struct/dc-error blame #,(opt/info-val opt/info) 'struct-name)) - #`(if (and (stronger-prop-pred? #,(opt/info-val opt/info)) - (let ([v (stronger-prop-get #,(opt/info-val opt/info))]) - (and (eq? (vector-ref v index) free-var) ...))) - #,(opt/info-val opt/info) - (if (pred? #,(opt/info-val opt/info)) - (begin - #,@s-fo-code - (chaperone-struct - #,(opt/info-val opt/info) - #,@(reverse s-chap-code) ;; built the last backwards, so reverse it here - stronger-prop-desc - (vector free-var ...))) - (struct/dc-error #,(opt/info-blame opt/info) #,(opt/info-val opt/info) 'struct-name)))) + #`(with-continuation-mark + contract-continuation-mark-key #,(opt/info-blame opt/info) + (if (pred? #,(opt/info-val opt/info)) + (begin + #,@s-fo-code + #,(opt/info-val opt/info)) + (struct/dc-error blame #,(opt/info-val opt/info) 'struct-name))) + #`(with-continuation-mark + contract-continuation-mark-key #,(opt/info-blame opt/info) + (if (and (stronger-prop-pred? #,(opt/info-val opt/info)) + (let ([v (stronger-prop-get #,(opt/info-val opt/info))]) + (and (eq? (vector-ref v index) free-var) ...))) + #,(opt/info-val opt/info) + (if (pred? #,(opt/info-val opt/info)) + (begin + #,@s-fo-code + (chaperone-struct + #,(opt/info-val opt/info) + #,@(reverse s-chap-code) ;; built the last backwards, so reverse it here + stronger-prop-desc + (vector free-var ...))) + (struct/dc-error #,(opt/info-blame opt/info) #,(opt/info-val opt/info) 'struct-name))))) #:lifts s-lifts #:superlifts From b84233bca78e9c7121745ff637365ad57905ddc0 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 14 Dec 2015 16:30:30 -0600 Subject: [PATCH 170/369] Tests for struct/dc instrumentation. --- .../tests/racket/contract/prof.rkt | 90 ++++++++++++++++++- 1 file changed, 88 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-test/tests/racket/contract/prof.rkt b/pkgs/racket-test/tests/racket/contract/prof.rkt index 9b1676d944..02cf961033 100644 --- a/pkgs/racket-test/tests/racket/contract/prof.rkt +++ b/pkgs/racket-test/tests/racket/contract/prof.rkt @@ -108,6 +108,92 @@ [f (-> #:x (λ _ (named-blame? 'prof3)) any/c)])))) (eval '(require 'prof3)) (eval '(f #:x 11))) - 11)) + 11) -;; TODO add struct/dc tests + (test/spec-passed + 'provide/contract11 + '(let () + (struct posn (x y)) + ((contract (-> (struct/dc posn [x neg-blame?]) any/c) (λ (x) x) 'pos 'neg) + (posn 1 2)))) + + (test/spec-passed + 'provide/contract12 + '(let () + (struct posn (x y)) + ((contract (-> any/c (struct/dc posn [x pos-blame?])) (λ (x) x) 'pos 'neg) + (posn 1 2)))) + + (test/spec-passed + 'provide/contract13 + '(let () + (struct posn (x y)) + ((contract (-> any/c (struct/dc posn [x pos-blame?] #:inv (x) pos-blame?)) + (λ (x) x) 'pos 'neg) + (posn 1 2)))) + + (test/spec-passed + 'provide/contract14 + '(let () + (struct posn (x y) #:mutable) + ((contract (-> any/c (struct/dc posn [x pos-blame?])) + (λ (x) x) 'pos 'neg) + (posn 1 2)))) + + (test/spec-passed + 'provide/contract15 + '(let () + (struct posn (x y)) + ((contract (-> any/c (struct/dc posn [x #:lazy pos-blame?])) + (λ (x) x) 'pos 'neg) + (posn 1 2)))) + + (test/spec-passed + 'provide/contract16 + '(let () + (struct posn (x y)) + ((contract (-> any/c (struct/dc posn + [x pos-blame?] + [y (x) pos-blame?])) + (λ (x) x) 'pos 'neg) + (posn 1 2)))) + + (test/spec-passed + 'provide/contract17 + '(let () + (struct posn (x y)) + ((contract (-> any/c (struct/dc posn + [x pos-blame?] + [y (x) #:lazy pos-blame?])) + (λ (x) x) 'pos 'neg) + (posn 1 2)))) + + (test/spec-passed + 'provide/contract18 + '(let () + (struct posn (x y) #:mutable) + ((contract (-> any/c (struct/dc posn + [x pos-blame?] + [y (x) pos-blame?])) + (λ (x) x) 'pos 'neg) + (posn 1 2)))) + + (test/spec-passed + 'provide/contract19 + '(let () + (struct posn (x y)) + ((contract (-> any/c (struct/dc posn + [x pos-blame?] + [y (x) #:depends-on-state pos-blame?])) + (λ (x) x) 'pos 'neg) + (posn 1 2)))) + + (test/spec-passed + 'provide/contract20 + '(let () + (struct posn (x y) #:mutable) + ((contract (-> any/c (struct/dc posn + [x pos-blame?] + [y (x) #:depends-on-state pos-blame?])) + (λ (x) x) 'pos 'neg) + (posn 1 2))))) From 6985150e0b61be4a32e5746e893609323c95d7e7 Mon Sep 17 00:00:00 2001 From: Gustavo Massaccesi Date: Mon, 14 Dec 2015 17:46:44 -0300 Subject: [PATCH 171/369] Don't drop expressions with side effects in eq? reduction The expression (eq? x y) is reduced to #f when the types of x and y are known. Reduce this to (begin x y #f) when they have side effects. --- pkgs/racket-test-core/tests/racket/optimize.rktl | 6 ++++++ racket/src/racket/src/optimize.c | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index 72366f37f0..f1eb1b85a4 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -1494,6 +1494,12 @@ '(lambda (x y) (car x) (unbox y) (eq? x y))) (test-comp '(lambda (x) (car x) #f) '(lambda (x) (car x) (eq? x (box 0)))) +(test-comp '(lambda (x) (car x) #f) + '(lambda (x) (car x) (eq? (begin (newline) x) (box 0))) + #f) +(test-comp '(lambda (x) (car x) #f) + '(lambda (x) (car x) (eq? x (begin (newline) (box 0)))) + #f) (test-comp '(lambda (w) (car w) (mcar w)) '(lambda (w) (car w) (mcar w) (random))) diff --git a/racket/src/racket/src/optimize.c b/racket/src/racket/src/optimize.c index c3fdc6493a..8040c496e5 100644 --- a/racket/src/racket/src/optimize.c +++ b/racket/src/racket/src/optimize.c @@ -3698,7 +3698,13 @@ static Scheme_Object *finish_optimize_application3(Scheme_App3_Rec *app, Optimiz if (!SAME_OBJ(pred1, pred2)) { info->preserves_marks = 1; info->single_result = 1; - return scheme_false; + return do_make_discarding_sequence(app->rand1, + do_make_discarding_sequence(app->rand2, + scheme_false, + info, 0, + 1, 0), + info, 0, + 1, 0); } } } From b4afecab97d753da1b06370ddd60c0a7f2d5c666 Mon Sep 17 00:00:00 2001 From: Andrew Kent Date: Tue, 15 Dec 2015 11:17:50 -0500 Subject: [PATCH 172/369] slightly more explicit error msg --- racket/collects/racket/private/generic.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/racket/collects/racket/private/generic.rkt b/racket/collects/racket/private/generic.rkt index 340c4a6bd2..d3fb990084 100644 --- a/racket/collects/racket/private/generic.rkt +++ b/racket/collects/racket/private/generic.rkt @@ -231,8 +231,8 @@ id)) (unless (pair? matches) (wrong-syntax sig-stx - "did not find ~a among ~a to ~s" - "the generic name" + "did not find ~a \"~a\" among ~a to ~s" + "the generic name" (syntax-e self-id) "the required, by-position arguments" (syntax-e name-stx))) (when (pair? (cdr matches)) From d0d6d719afeceacefff2666a9a6d76a47d56ede5 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 15 Dec 2015 13:37:44 -0600 Subject: [PATCH 173/369] Abstract contract instrumentation. --- .../racket/contract/private/arr-i.rkt | 14 ++-- .../contract/private/arrow-higher-order.rkt | 33 ++++----- .../contract/private/arrow-val-first.rkt | 8 +- .../racket/contract/private/arrow.rkt | 52 ++++++------- .../racket/contract/private/case-arrow.rkt | 8 +- .../collects/racket/contract/private/guts.rkt | 7 ++ .../collects/racket/contract/private/misc.rkt | 11 +-- .../racket/contract/private/struct-dc.rkt | 74 ++++++++----------- .../racket/contract/private/vector.rkt | 28 +++---- 9 files changed, 107 insertions(+), 128 deletions(-) diff --git a/racket/collects/racket/contract/private/arr-i.rkt b/racket/collects/racket/contract/private/arr-i.rkt index d2bf3b4715..5c4c7a547f 100644 --- a/racket/collects/racket/contract/private/arr-i.rkt +++ b/racket/collects/racket/contract/private/arr-i.rkt @@ -784,8 +784,8 @@ evaluted left-to-right.) (list #`(case-lambda [#,(vector->list wrapper-ress) - (with-continuation-mark - contract-continuation-mark-key blame + (with-contract-continuation-mark + blame #,(add-wrapper-let (add-post-cond an-istx indy-arg-vars ordered-args indy-res-vars ordered-ress #`(values #,@(vector->list wrapper-ress))) @@ -886,13 +886,11 @@ evaluted left-to-right.) #,wrapper-body)]) (make-keyword-procedure (λ (kwds kwd-args . args) - (with-continuation-mark - contract-continuation-mark-key blame - (keyword-apply arg-checker kwds kwd-args args))) + (with-contract-continuation-mark + blame (keyword-apply arg-checker kwds kwd-args args))) (λ args - (with-continuation-mark - contract-continuation-mark-key blame - (apply arg-checker args))))) + (with-contract-continuation-mark + blame (apply arg-checker args))))) impersonator-prop:contracted ctc impersonator-prop:blame blame)))))) diff --git a/racket/collects/racket/contract/private/arrow-higher-order.rkt b/racket/collects/racket/contract/private/arrow-higher-order.rkt index 8015f6c108..071b0667c9 100644 --- a/racket/collects/racket/contract/private/arrow-higher-order.rkt +++ b/racket/collects/racket/contract/private/arrow-higher-order.rkt @@ -59,20 +59,20 @@ (define (check-pre-cond pre blame neg-party val) - (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")))) + (with-contract-continuation-mark + (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) - (with-continuation-mark contract-continuation-mark-key - (cons blame neg-party) - (unless (post) - (raise-blame-error blame - #:missing-party neg-party - val "#:post condition")))) + (with-contract-continuation-mark + (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)) @@ -167,8 +167,7 @@ ...)]) #'(case-lambda [(rng-x ...) - (with-continuation-mark - contract-continuation-mark-key + (with-contract-continuation-mark (cons blame neg-party) (let () post ... @@ -290,15 +289,13 @@ ;; Overhead of double-wrapping has not been ;; noticeable in my measurements so far. ;; - stamourv - (with-continuation-mark - contract-continuation-mark-key + (with-contract-continuation-mark (cons blame neg-party) (let () pre ... basic-return)))] [kwd-lambda-name (gen-id 'kwd-lambda)] [kwd-lambda #`(λ kwd-lam-params - (with-continuation-mark - contract-continuation-mark-key + (with-contract-continuation-mark (cons blame neg-party) (let () pre ... kwd-return)))]) diff --git a/racket/collects/racket/contract/private/arrow-val-first.rkt b/racket/collects/racket/contract/private/arrow-val-first.rkt index 1345678b5d..046750d58b 100644 --- a/racket/collects/racket/contract/private/arrow-val-first.rkt +++ b/racket/collects/racket/contract/private/arrow-val-first.rkt @@ -251,9 +251,9 @@ '()))) (define let-values-clause #`[#,(reverse args-vars) - (with-continuation-mark contract-continuation-mark-key - blame+neg-party - (values #,@(reverse args-expressions)))]) + (with-contract-continuation-mark + blame+neg-party + (values #,@(reverse args-expressions)))]) (define the-clause (if rngs @@ -270,7 +270,7 @@ [args (values args #,@(map (λ (x) #'#f) (syntax->list #'(res-x ...))))]))) - (with-continuation-mark contract-continuation-mark-key + (with-contract-continuation-mark blame+neg-party (cond [failed diff --git a/racket/collects/racket/contract/private/arrow.rkt b/racket/collects/racket/contract/private/arrow.rkt index ba27288f4e..38215e750f 100644 --- a/racket/collects/racket/contract/private/arrow.rkt +++ b/racket/collects/racket/contract/private/arrow.rkt @@ -100,19 +100,19 @@ val (make-keyword-procedure (λ (kwds kwd-vals . args) - (with-continuation-mark - contract-continuation-mark-key (cons orig-blame neg-party) - #,(check-tail-contract - #'(p-app-x ...) - (list #'res-checker) - (λ (s) #`(apply values #,@s kwd-vals args))))) + (with-contract-continuation-mark + (cons orig-blame neg-party) + #,(check-tail-contract + #'(p-app-x ...) + (list #'res-checker) + (λ (s) #`(apply values #,@s kwd-vals args))))) (λ args - (with-continuation-mark - contract-continuation-mark-key (cons orig-blame neg-party) - #,(check-tail-contract - #'(p-app-x ...) - (list #'res-checker) - (λ (s) #`(apply values #,@s args)))))) + (with-contract-continuation-mark + (cons orig-blame neg-party) + #,(check-tail-contract + #'(p-app-x ...) + (list #'res-checker) + (λ (s) #`(apply values #,@s args)))))) impersonator-prop:contracted ctc impersonator-prop:application-mark (cons contract-key (list p-app-x ...)))))))) @@ -251,8 +251,8 @@ #'(values/drop (rng-ctc rng-x neg-party) ...))]) #'(case-lambda [(rng-x ...) - (with-continuation-mark - contract-continuation-mark-key (cons blame neg-party) + (with-contract-continuation-mark + (cons blame neg-party) (let () post ... rng-results))] @@ -353,14 +353,14 @@ ;; Overhead of double-wrapping has not been ;; noticeable in my measurements so far. ;; - stamourv - (with-continuation-mark - contract-continuation-mark-key (cons blame neg-party) + (with-contract-continuation-mark + (cons blame neg-party) (let () pre ... basic-return)))] [kwd-lambda-name (gen-id 'kwd-lambda)] [kwd-lambda #`(λ kwd-lam-params - (with-continuation-mark - contract-continuation-mark-key (cons blame neg-party) + (with-contract-continuation-mark + (cons blame neg-party) (let () pre ... kwd-return)))]) (with-syntax ([(basic-checker-name) (generate-temporaries '(basic-checker))]) @@ -425,8 +425,8 @@ (λ (kwds kwd-args . args) (raise-no-keywords-arg blame #:missing-party neg-party val kwds)) (λ (kwds kwd-args . args) - (with-continuation-mark - contract-continuation-mark-key (cons blame neg-party) + (with-contract-continuation-mark + (cons blame neg-party) (let () (define args-len (length args)) (unless (valid-number-of-args? args) @@ -451,8 +451,8 @@ (define basic-checker-name (if (null? req-kwd) (λ args - (with-continuation-mark - contract-continuation-mark-key (cons blame neg-party) + (with-contract-continuation-mark + (cons blame neg-party) (let () (unless (valid-number-of-args? args) (define args-len (length args)) @@ -1309,8 +1309,8 @@ val (make-keyword-procedure (λ (kwd-args kwd-arg-vals . raw-orig-args) - (with-continuation-mark - contract-continuation-mark-key (cons blame neg-party) + (with-contract-continuation-mark + (cons blame neg-party) (let* ([orig-args (if (base-->d-mtd? ->d-stct) (cdr raw-orig-args) raw-orig-args)] @@ -1339,8 +1339,8 @@ [rng-underscore? (box? (base-->d-range ->d-stct))]) (if rng (list (λ orig-results - (with-continuation-mark - contract-continuation-mark-key (cons blame neg-party) + (with-contract-continuation-mark + (cons blame neg-party) (let* ([range-count (length rng)] [post-args (append orig-results raw-orig-args)] [post-non-kwd-arg-count (+ non-kwd-ctc-count range-count)] diff --git a/racket/collects/racket/contract/private/case-arrow.rkt b/racket/collects/racket/contract/private/case-arrow.rkt index 0097eb0305..0ba780525a 100644 --- a/racket/collects/racket/contract/private/case-arrow.rkt +++ b/racket/collects/racket/contract/private/case-arrow.rkt @@ -148,8 +148,7 @@ (make-keyword-procedure (raise-no-keywords-error f blame neg-party) (λ args - (with-continuation-mark contract-continuation-mark-key blame - (apply the-case-lam args))))) + (with-contract-continuation-mark blame (apply the-case-lam args))))) (define same-rngs (same-range-projections range-projections)) (if same-rngs (wrapper @@ -206,9 +205,8 @@ (cdr target) (let* ([p (f rng-blame)] [new (lambda args - (with-continuation-mark - contract-continuation-mark-key blame - (apply p args)))]) + (with-contract-continuation-mark + blame (apply p args)))]) (set! memo (cons (cons f new) memo)) new)))) rng-late-neg-ctcs))) diff --git a/racket/collects/racket/contract/private/guts.rkt b/racket/collects/racket/contract/private/guts.rkt index b98a86a782..cb2da0f3c7 100644 --- a/racket/collects/racket/contract/private/guts.rkt +++ b/racket/collects/racket/contract/private/guts.rkt @@ -49,6 +49,7 @@ char-in/c contract-continuation-mark-key + with-contract-continuation-mark (struct-out wrapped-extra-arg-arrow) contract-custom-write-property-proc @@ -603,3 +604,9 @@ ;; That information is consumed by the contract profiler. (define contract-continuation-mark-key (make-continuation-mark-key 'contract)) + +(define-syntax-rule (with-contract-continuation-mark payload code) + (begin + ;; (unless (or (pair? payload) (not (blame-missing-party? payload))) + ;; (error "internal error: missing blame party" payload)) + (with-continuation-mark contract-continuation-mark-key payload code))) diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index 0e48a68791..5d6bdc6726 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -1482,10 +1482,7 @@ (λ (blame) (define blame/c (blame-add-context blame "the parameter of")) (define (add-profiling f) - (λ (x) - (with-continuation-mark contract-continuation-mark-key - (cons blame #f) - (f x)))) + (λ (x) (with-contract-continuation-mark (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) @@ -1510,9 +1507,9 @@ [(parameter? val) (define (add-profiling f) (λ (x) - (with-continuation-mark contract-continuation-mark-key - (cons blame/c neg-party) - (f x neg-party)))) + (with-contract-continuation-mark + (cons blame/c neg-party) + (f x neg-party)))) (make-derived-parameter val (add-profiling in-proj) diff --git a/racket/collects/racket/contract/private/struct-dc.rkt b/racket/collects/racket/contract/private/struct-dc.rkt index 4d037705a8..6c13d96a31 100644 --- a/racket/collects/racket/contract/private/struct-dc.rkt +++ b/racket/collects/racket/contract/private/struct-dc.rkt @@ -343,18 +343,17 @@ (define-values (new-chaperone-args new-impersonate-args) (cond [(invariant? subcontract) - (unless (with-continuation-mark contract-continuation-mark-key - (cons blame neg-party) - (apply (invariant-dep-proc subcontract) dep-args)) + (unless (with-contract-continuation-mark + (cons blame neg-party) + (apply (invariant-dep-proc subcontract) dep-args)) (raise-invariant-blame-failure blame neg-party v (reverse dep-args) (reverse (invariant-fields subcontract)))) (values chaperone-args impersonate-args)] [(immutable? subcontract) - (define (chk fld v) (with-continuation-mark - contract-continuation-mark-key - (cons blame neg-party) - (proj v neg-party))) + (define (chk fld v) (with-contract-continuation-mark + (cons blame neg-party) + (proj v neg-party))) (chk #f (sel v)) ;; check the field contract immediately (values (if (flat-contract? (indep-ctc subcontract)) chaperone-args @@ -363,8 +362,7 @@ [(lazy-immutable? subcontract) (values (list* sel (cache-λ (fld v) - (with-continuation-mark - contract-continuation-mark-key + (with-contract-continuation-mark (cons blame neg-party) (proj v neg-party))) chaperone-args) @@ -374,27 +372,23 @@ (values chaperone-args (list* sel (λ (fld v) - (with-continuation-mark - contract-continuation-mark-key + (with-contract-continuation-mark (cons blame neg-party) (proj v neg-party))) (mutable-set subcontract) (λ (fld v) - (with-continuation-mark - contract-continuation-mark-key + (with-contract-continuation-mark (cons blame neg-party) (mut-proj v neg-party))) impersonate-args)) (values (list* sel (λ (fld v) - (with-continuation-mark - contract-continuation-mark-key + (with-contract-continuation-mark (cons blame neg-party) (proj v neg-party))) (mutable-set subcontract) (λ (fld v) - (with-continuation-mark - contract-continuation-mark-key + (with-contract-continuation-mark (cons blame neg-party) (mut-proj v neg-party))) chaperone-args) @@ -403,10 +397,9 @@ (define proj (dep-ctc-blame-proj blame)) (cond [(dep-immutable? subcontract) - (define (chk fld v) (with-continuation-mark - contract-continuation-mark-key - (cons blame neg-party) - (proj v neg-party))) + (define (chk fld v) (with-contract-continuation-mark + (cons blame neg-party) + (proj v neg-party))) (chk #f (sel v)) ;; check the field contract immediately (values (if (flat-contract? dep-ctc) chaperone-args @@ -415,8 +408,7 @@ [(dep-lazy-immutable? subcontract) (values (list* sel (cache-λ (fld v) - (with-continuation-mark - contract-continuation-mark-key + (with-contract-continuation-mark (cons blame neg-party) (proj v neg-party))) chaperone-args) @@ -426,14 +418,12 @@ (if (equal? (dep-type subcontract) '#:impersonator) (values (list* sel (λ (fld v) - (with-continuation-mark - contract-continuation-mark-key + (with-contract-continuation-mark (cons blame neg-party) (proj v neg-party))) (dep-mutable-set subcontract) (λ (fld v) - (with-continuation-mark - contract-continuation-mark-key + (with-contract-continuation-mark (cons blame neg-party) (mut-proj v neg-party))) chaperone-args) @@ -441,14 +431,12 @@ (values chaperone-args (list* sel (λ (fld v) - (with-continuation-mark - contract-continuation-mark-key + (with-contract-continuation-mark (cons blame neg-party) (proj v neg-party))) (dep-mutable-set subcontract) (λ (fld v) - (with-continuation-mark - contract-continuation-mark-key + (with-contract-continuation-mark (cons blame neg-party) (mut-proj v neg-party))) impersonate-args)))] @@ -456,8 +444,7 @@ (proj (sel v) neg-party) (values (list* sel (λ (strct val) - (with-continuation-mark - contract-continuation-mark-key + (with-contract-continuation-mark (cons blame neg-party) (build-dep-on-state-proj (base-struct/dc-subcontracts ctc) subcontract strct @@ -467,18 +454,17 @@ [(dep-on-state-mutable? subcontract) (proj (sel v) neg-party) (define (get-chap-proc strct val) - (with-continuation-mark - contract-continuation-mark-key + (with-contract-continuation-mark (cons blame neg-party) (build-dep-on-state-proj (base-struct/dc-subcontracts ctc) subcontract strct orig-indy-projs orig-indy-blames blame neg-party val))) (define (set-chap-proc strct val) - (with-continuation-mark contract-continuation-mark-key - (cons blame neg-party) - (build-dep-on-state-proj - (base-struct/dc-subcontracts ctc) subcontract strct - orig-mut-indy-projs orig-mut-indy-blames mut-blame neg-party val))) + (with-contract-continuation-mark + (cons blame neg-party) + (build-dep-on-state-proj + (base-struct/dc-subcontracts ctc) subcontract strct + orig-mut-indy-projs orig-mut-indy-blames mut-blame neg-party val))) (if (eq? (dep-type subcontract) '#:impersonator) (values chaperone-args (list* sel @@ -1432,15 +1418,15 @@ #:exp ;; if this is #t, when we have to avoid putting the property on here. (if (null? s-chap-code) - #`(with-continuation-mark - contract-continuation-mark-key #,(opt/info-blame opt/info) + #`(with-contract-continuation-mark + #,(opt/info-blame opt/info) (if (pred? #,(opt/info-val opt/info)) (begin #,@s-fo-code #,(opt/info-val opt/info)) (struct/dc-error blame #,(opt/info-val opt/info) 'struct-name))) - #`(with-continuation-mark - contract-continuation-mark-key #,(opt/info-blame opt/info) + #`(with-contract-continuation-mark + #,(opt/info-blame opt/info) (if (and (stronger-prop-pred? #,(opt/info-val opt/info)) (let ([v (stronger-prop-get #,(opt/info-val opt/info))]) (and (eq? (vector-ref v index) free-var) ...))) diff --git a/racket/collects/racket/contract/private/vector.rkt b/racket/collects/racket/contract/private/vector.rkt index 4adadcab78..264775c635 100644 --- a/racket/collects/racket/contract/private/vector.rkt +++ b/racket/collects/racket/contract/private/vector.rkt @@ -165,12 +165,12 @@ (define elem-neg-proj (vfp neg-blame)) (define checked-ref (λ (neg-party) (λ (vec i val) - (with-continuation-mark contract-continuation-mark-key + (with-contract-continuation-mark (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 + (with-contract-continuation-mark (cons neg-blame neg-party) (elem-neg-proj val neg-party))))) (cond @@ -221,13 +221,11 @@ [elem-neg-proj ((contract-projection elem-ctc) (blame-add-element-of-context blame #:swap? #t))]) (define checked-ref (λ (vec i val) - (with-continuation-mark - contract-continuation-mark-key blame - (elem-pos-proj val)))) + (with-contract-continuation-mark + blame (elem-pos-proj val)))) (define checked-set (λ (vec i val) - (with-continuation-mark - contract-continuation-mark-key blame - (elem-neg-proj val)))) + (with-contract-continuation-mark + blame (elem-neg-proj val)))) (define raise-blame (λ (val . args) (apply raise-blame-error blame val args))) (λ (val) @@ -403,8 +401,8 @@ (λ (blame) (define blame+ctxt (blame-add-element-of-context blame)) (λ (val) - (with-continuation-mark - contract-continuation-mark-key blame + (with-contract-continuation-mark + blame (begin (check-vector/c ctc val blame) (for ([e (in-vector val)] @@ -438,13 +436,11 @@ (vector-wrapper val (λ (vec i val) - (with-continuation-mark - contract-continuation-mark-key blame - ((vector-ref elem-pos-projs i) val))) + (with-contract-continuation-mark + blame ((vector-ref elem-pos-projs i) val))) (λ (vec i val) - (with-continuation-mark - contract-continuation-mark-key blame - ((vector-ref elem-neg-projs i) val))) + (with-contract-continuation-mark + blame ((vector-ref elem-neg-projs i) val))) impersonator-prop:contracted ctc impersonator-prop:blame blame)))))))) From 3dc49139cfe8a31fba79b429d07c1b13b05afdac Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 15 Dec 2015 14:31:38 -0600 Subject: [PATCH 174/369] Fix more missing parties in contract instrumentation. --- pkgs/racket-test/tests/racket/contract/prof.rkt | 16 +++++++++++++++- .../racket/contract/private/case-arrow.rkt | 9 +++++++-- racket/collects/racket/contract/private/guts.rkt | 2 ++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-test/tests/racket/contract/prof.rkt b/pkgs/racket-test/tests/racket/contract/prof.rkt index 02cf961033..7e19329674 100644 --- a/pkgs/racket-test/tests/racket/contract/prof.rkt +++ b/pkgs/racket-test/tests/racket/contract/prof.rkt @@ -196,4 +196,18 @@ [x pos-blame?] [y (x) #:depends-on-state pos-blame?])) (λ (x) x) 'pos 'neg) - (posn 1 2))))) + (posn 1 2)))) + + (test/spec-passed + 'provide/contract21 + '(let () + ((contract (case-> (-> any/c any/c pos-blame?)) + (λ (x y) x) 'pos 'neg) + 1 2))) + + (test/spec-passed + 'provide/contract22 + '(let () + ((contract (case-> (-> neg-blame? any/c)) + (λ (x) x) 'pos 'neg) + 1)))) diff --git a/racket/collects/racket/contract/private/case-arrow.rkt b/racket/collects/racket/contract/private/case-arrow.rkt index 0ba780525a..f96510c608 100644 --- a/racket/collects/racket/contract/private/case-arrow.rkt +++ b/racket/collects/racket/contract/private/case-arrow.rkt @@ -2,6 +2,7 @@ (require (for-syntax racket/base syntax/name) + (only-in racket/list last) racket/stxparam "guts.rkt" "blame.rkt" @@ -148,7 +149,9 @@ (make-keyword-procedure (raise-no-keywords-error f blame neg-party) (λ args - (with-contract-continuation-mark blame (apply the-case-lam args))))) + (with-contract-continuation-mark + (cons blame neg-party) + (apply the-case-lam args))))) (define same-rngs (same-range-projections range-projections)) (if same-rngs (wrapper @@ -206,7 +209,9 @@ (let* ([p (f rng-blame)] [new (lambda args (with-contract-continuation-mark - blame (apply p args)))]) + ;; last arg is missing party + (cons blame (last args)) + (apply p args)))]) (set! memo (cons (cons f new) memo)) new)))) rng-late-neg-ctcs))) diff --git a/racket/collects/racket/contract/private/guts.rkt b/racket/collects/racket/contract/private/guts.rkt index cb2da0f3c7..df3f78f627 100644 --- a/racket/collects/racket/contract/private/guts.rkt +++ b/racket/collects/racket/contract/private/guts.rkt @@ -607,6 +607,8 @@ (define-syntax-rule (with-contract-continuation-mark payload code) (begin + ;; ;; When debugging a missing blame party error, turn this on, then run + ;; ;; the contract test suite. It should find the problematic combinator. ;; (unless (or (pair? payload) (not (blame-missing-party? payload))) ;; (error "internal error: missing blame party" payload)) (with-continuation-mark contract-continuation-mark-key payload code))) From 11f76cbebfb5b6fa26b5db5146597c290ce1abeb Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 15 Dec 2015 12:26:19 -0700 Subject: [PATCH 175/369] fix Burroughs's name --- pkgs/racket-doc/scribblings/guide/let.scrbl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-doc/scribblings/guide/let.scrbl b/pkgs/racket-doc/scribblings/guide/let.scrbl index 6611e653f9..b09855a43d 100644 --- a/pkgs/racket-doc/scribblings/guide/let.scrbl +++ b/pkgs/racket-doc/scribblings/guide/let.scrbl @@ -79,11 +79,11 @@ The difference is that each @racket[_id] is available for use in later visible one. @examples[ -(let* ([x (list "Borroughs")] +(let* ([x (list "Burroughs")] [y (cons "Rice" x)] [z (cons "Edgar" y)]) (list x y z)) -(let* ([name (list "Borroughs")] +(let* ([name (list "Burroughs")] [name (cons "Rice" name)] [name (cons "Edgar" name)]) name) @@ -93,7 +93,7 @@ In other words, a @racket[let*] form is equivalent to nested @racket[let] forms, each with a single binding: @interaction[ -(let ([name (list "Borroughs")]) +(let ([name (list "Burroughs")]) (let ([name (cons "Rice" name)]) (let ([name (cons "Edgar" name)]) name))) From ca237910b3a1f8ffd24f0742e1758ce8186796d5 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 15 Dec 2015 17:06:48 -0700 Subject: [PATCH 176/369] fix `make-syntax-delta-introducer` with a #f argument Closes PR 15202 --- pkgs/racket-doc/scribblings/reference/stx-trans.scrbl | 2 ++ pkgs/racket-test-core/tests/racket/stx.rktl | 11 +++++++++++ racket/src/racket/src/syntax.c | 4 +--- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl index e8d6832c95..3eca603e50 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl @@ -947,6 +947,8 @@ and different result procedures use distinct scopes. Produces a procedure that behaves like the result of @racket[make-syntax-introducer], but using the @tech{scopes} of @racket[ext-stx] that are not shared with @racket[base-stx]. +A @racket[#f] value for @racket[base-stx] is equivalent to a syntax +object with no @tech{scopes}. This procedure is potentially useful when some @racket[_m-id] has a transformer binding that records some @racket[_orig-id], and a use of diff --git a/pkgs/racket-test-core/tests/racket/stx.rktl b/pkgs/racket-test-core/tests/racket/stx.rktl index 4b1e343f6d..13da53dbbf 100644 --- a/pkgs/racket-test-core/tests/racket/stx.rktl +++ b/pkgs/racket-test-core/tests/racket/stx.rktl @@ -148,6 +148,17 @@ (test #f syntax-original? ((make-syntax-introducer) #'here)) (test #t syntax-original? ((make-syntax-introducer #t) #'here)) +(let* ([a (datum->syntax #f 'a)] + [a1 ((make-syntax-introducer) a)] + [a2 ((make-syntax-introducer) a)]) + (test #f bound-identifier=? a1 a2) + (test #t bound-identifier=? a1 ((make-syntax-delta-introducer a1 a2) a)) + (test #t bound-identifier=? a2 ((make-syntax-delta-introducer a2 a1) a)) + (test #t bound-identifier=? a2 ((make-syntax-delta-introducer a2 #f) a)) + (test #t bound-identifier=? + ((make-syntax-delta-introducer a1 a2) a2) + ((make-syntax-delta-introducer a2 a1) a1))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Test basic expansion and property propagation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index 0ef0a6d685..de2cc3ae1b 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -8006,12 +8006,10 @@ Scheme_Object *scheme_syntax_make_transfer_intro(int argc, Scheme_Object **argv) } else m2 = NULL; - if (!m2) { + if (!m2 && !SCHEME_FALSEP(src)) { src = scheme_stx_lookup_w_nominal(argv[1], phase, 1, NULL, NULL, &m2, NULL, NULL, NULL, NULL, NULL); - if (SCHEME_FALSEP(src)) - m2 = NULL; } if (m2) { From 33ba7683b209320608a10afb19ca7c1b785bae73 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 15 Dec 2015 20:35:28 -0600 Subject: [PATCH 177/369] specify default for stronger --- pkgs/racket-doc/scribblings/reference/contracts.scrbl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index 3497b3662e..d821401051 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -2012,7 +2012,9 @@ flat contracts do not need to supply an explicit projection. The @racket[stronger] argument is used to implement @racket[contract-stronger?]. The first argument is always the contract itself and the second argument is whatever -was passed as the second argument to @racket[contract-stronger?]. +was passed as the second argument to @racket[contract-stronger?]. If no +@racket[stronger] argument is supplied, then a default that always returns +@racket[#f] is used. The @racket[is-list-contract?] argument is used by the @racket[list-contract?] predicate to determine if this is a contract that accepts only @racket[list?] values. @@ -2556,7 +2558,8 @@ which produces a description to @racket[write] as part of a contract violation; produces a blame-tracking projection defining the behavior of the contract; @racket[stronger], which is a predicate that determines whether this contract (passed in the first argument) is stronger than some other contract (passed -in the second argument); @racket[generate], which returns a thunk +in the second argument) and whose default always returns @racket[#f]; + @racket[generate], which returns a thunk that generates random values matching the contract (using @racket[contract-random-generate-fail]) to indicate failure) or @racket[#f] to indicate that random generation for this contract isn't supported; @racket[exercise], From 0d633fefd3ba657f85e166bd5517611aa59bff95 Mon Sep 17 00:00:00 2001 From: ben Date: Sat, 10 Oct 2015 01:39:19 -0400 Subject: [PATCH 178/369] typo: string-contains precondition --- racket/collects/racket/string.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/racket/string.rkt b/racket/collects/racket/string.rkt index d4f51511f6..33df306f0f 100644 --- a/racket/collects/racket/string.rkt +++ b/racket/collects/racket/string.rkt @@ -173,7 +173,7 @@ (unless (string? str) (raise-argument-error 'string-contains? "string?" str)) (unless (string? sub) - (raise-argument-error 'string-prefix? "string?" sub)) + (raise-argument-error 'string-contains? "string?" sub)) (define L1 (string-length str)) (define L2 (string-length sub)) (define d (- L1 L2)) From d7184227e191152d02559ab067afc33cc298b247 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 17 Dec 2015 06:09:33 -0700 Subject: [PATCH 179/369] fix mutation of shared "self" module path index for submodules --- pkgs/racket-test-core/tests/racket/stx.rktl | 25 +++++++++++ racket/src/racket/src/module.c | 50 ++++++++++++++------- racket/src/racket/src/read.c | 2 +- racket/src/racket/src/schpriv.h | 2 +- 4 files changed, 61 insertions(+), 18 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/stx.rktl b/pkgs/racket-test-core/tests/racket/stx.rktl index 13da53dbbf..01813acefc 100644 --- a/pkgs/racket-test-core/tests/racket/stx.rktl +++ b/pkgs/racket-test-core/tests/racket/stx.rktl @@ -2269,6 +2269,31 @@ (namespace-syntax-introduce (datum->syntax #f 'car))))) (open-output-bytes))) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check that reading a compiled module doesn't mutate the +;; shared "self" modix for a submodule: + +(parameterize ([current-namespace (make-base-namespace)]) + (define o (open-output-bytes)) + (write (compile `(module name-1 racket/base (module+ inside))) o) + (define m + (parameterize ([read-accept-compiled #t]) + (read (open-input-bytes (get-output-bytes o))))) + (define s (expand `(module name-2 racket/base (module+ inside (define check-me 1))))) + (test "(|expanded module| inside)" + format + "~s" + (resolved-module-path-name + (let loop ([s s]) + (cond + [(identifier? s) + (and (equal? 'check-me (syntax-e s)) + (module-path-index-resolve (car (identifier-binding s))))] + [(syntax? s) (loop (syntax-e s))] + [(pair? s) + (or (loop (car s)) (loop (cdr s)))] + [else #f]))))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index 238f0d266d..33ebc783a0 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -3716,7 +3716,7 @@ static Scheme_Object *module_path_index_join(int argc, Scheme_Object *argv[]) "second argument", 1, argv[1], "third argument", 1, argv[2], NULL); - return scheme_get_submodule_empty_self_modidx(argv[2]); + return scheme_get_submodule_empty_self_modidx(argv[2], 0); } } @@ -4024,31 +4024,49 @@ static Scheme_Object *resolved_module_path_to_modidx(Scheme_Object *rmp) return scheme_make_modidx(path, scheme_false, rmp); } -Scheme_Object *scheme_get_submodule_empty_self_modidx(Scheme_Object *submodule_path) +Scheme_Object *scheme_get_submodule_empty_self_modidx(Scheme_Object *submodule_path, int can_cache) { Scheme_Bucket *b; + Scheme_Object *modidx; - if (SCHEME_NULLP(submodule_path)) - return empty_self_modidx; + if (SCHEME_NULLP(submodule_path)) { + if (can_cache) + return empty_self_modidx; + return scheme_make_modidx(scheme_false, scheme_false, empty_self_modname); + } if (!submodule_empty_modidx_table) { REGISTER_SO(submodule_empty_modidx_table); submodule_empty_modidx_table = scheme_make_weak_equal_table(); } - scheme_start_atomic(); - b = scheme_bucket_from_table(submodule_empty_modidx_table, (const char *)submodule_path); - if (!b->val) { - submodule_path = make_resolved_module_path_obj(scheme_make_pair(scheme_resolved_module_path_value(empty_self_modname), - submodule_path)); - submodule_path = scheme_make_modidx(scheme_false, - scheme_false, - submodule_path); - b->val = submodule_path; + if (can_cache) { + scheme_start_atomic(); + b = scheme_bucket_from_table(submodule_empty_modidx_table, (const char *)submodule_path); + if (b->val) + modidx = scheme_ephemeron_value(b->val); + else + modidx = NULL; + } else { + b = NULL; + modidx = NULL; } - scheme_end_atomic_no_swap(); - return b->val; + if (!modidx) { + modidx = make_resolved_module_path_obj(scheme_make_pair(scheme_resolved_module_path_value(empty_self_modname), + submodule_path)); + modidx = scheme_make_modidx(scheme_false, scheme_false, modidx); + if (b) { + modidx = scheme_make_ephemeron(submodule_path, modidx); + b->val = modidx; + modidx = scheme_ephemeron_value(modidx); + } + } + + if (can_cache) + scheme_end_atomic_no_swap(); + + return modidx; } static Scheme_Object *_module_resolve_k(void); @@ -7325,7 +7343,7 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, fm = scheme_stx_property(fm, module_name_symbol, scheme_resolved_module_path_value(rmp)); - this_empty_self_modidx = scheme_get_submodule_empty_self_modidx(submodule_path); + this_empty_self_modidx = scheme_get_submodule_empty_self_modidx(submodule_path, 1); /* phase shift to replace self_modidx of previous expansion: */ fm = scheme_stx_shift(fm, NULL, this_empty_self_modidx, self_modidx, NULL, diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index fb354cd3f2..26b55dd703 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -5168,7 +5168,7 @@ static Scheme_Object *read_compact(CPort *port, int use_stack) if (SCHEME_FALSEP(path)) return scheme_make_modidx(scheme_false, scheme_false, scheme_false); else - return scheme_get_submodule_empty_self_modidx(path); + return scheme_get_submodule_empty_self_modidx(path, 0); } else return scheme_make_modidx(path, base, scheme_false); } diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index a06b2eca72..1f26f0b3f5 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -3719,7 +3719,7 @@ Scheme_Object *scheme_modidx_shift(Scheme_Object *modidx, Scheme_Object *shift_to_modidx); Scheme_Object *scheme_modidx_submodule(Scheme_Object *modidx); -Scheme_Object *scheme_get_submodule_empty_self_modidx(Scheme_Object *submodule_path); +Scheme_Object *scheme_get_submodule_empty_self_modidx(Scheme_Object *submodule_path, int can_cache); #define SCHEME_RMPP(o) (SAME_TYPE(SCHEME_TYPE((o)), scheme_resolved_module_path_type)) #define SCHEME_MODNAMEP(obj) (SAME_TYPE(SCHEME_TYPE(obj), scheme_resolved_module_path_type)) From ad1fe0c529af9d2a5d9fb8669c58455792351d49 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 17 Dec 2015 07:50:20 -0700 Subject: [PATCH 180/369] raco setup: make "nothing to do" count as success --- racket/collects/setup/setup-core.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/setup/setup-core.rkt b/racket/collects/setup/setup-core.rkt index ac28c34d29..f0d4c889df 100644 --- a/racket/collects/setup/setup-core.rkt +++ b/racket/collects/setup/setup-core.rkt @@ -589,7 +589,7 @@ nothing-else-to-do? (not (make-tidy))) (setup-printf #f "nothing to do") - (exit 1)) + (exit 0)) (define (cc->name cc) (string-join (map path->string (cc-collection cc)) "/")) (define (cc->cc+name+id cc) From 074202bdd209be8964ddf35e2051f7e110e2d4ee Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 17 Dec 2015 07:55:39 -0700 Subject: [PATCH 181/369] raco setup: don't completely ignore a collection without compilation A collection's "info.rkt" might have `(define compile-omit-paths 'all)` but also other setup actions, so don't completely ignore a collection directory just because there's nothing to compile. --- racket/collects/setup/setup-core.rkt | 52 +++++++++++++++------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/racket/collects/setup/setup-core.rkt b/racket/collects/setup/setup-core.rkt index f0d4c889df..5041272932 100644 --- a/racket/collects/setup/setup-core.rkt +++ b/racket/collects/setup/setup-core.rkt @@ -293,18 +293,16 @@ (setup-printf "WARNING" "ignoring `compile-subcollections' entry in info ~a" path-name)) - ;; this check is also done in compiler/compiler, in compile-directory - (and (not (eq? 'all (omitted-paths path getinfo omit-root))) - (make-cc collection path - (if name - (format "~a (~a)" path-name name) - path-name) - info - parent - omit-root - info-root info-path info-path-mode - shadowing-policy - main?))) + (make-cc collection path + (if name + (format "~a (~a)" path-name name) + path-name) + info + parent + omit-root + info-root info-path info-path-mode + shadowing-policy + main?)) (define ((warning-handler v) exn) (setup-printf "WARNING" "~a" (exn->string exn)) @@ -525,11 +523,14 @@ ;; note: omit can be 'all, if this happens then this collection ;; should not have been included, but we might jump in if a ;; command-line argument specified a coll/subcoll - (define omit (append - (if make-docs? - null - (list (string->path "scribblings"))) - (omitted-paths ccp getinfo (cc-omit-root cc)))) + (define omit (let ([omit (omitted-paths ccp getinfo (cc-omit-root cc))]) + (if (eq? omit 'all) + 'all + (append + (if make-docs? + null + (list (string->path "scribblings"))) + omit)))) (define-values [dirs files] (if (eq? 'all omit) (values null null) @@ -542,12 +543,13 @@ (define srcs (append (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)) - (map car (call-info info 'scribblings - (lambda () null) (lambda (x) #f))))) - null) + (if (and make-docs? + (not (eq? omit 'all))) + (filter (lambda (p) (not (member p omit))) + (map (lambda (s) (if (string? s) (string->path s) s)) + (map car (call-info info 'scribblings + (lambda () null) (lambda (x) #f))))) + 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)) @@ -663,9 +665,9 @@ ;; let `collection-path' complain about the name, if that's the problem: (with-handlers ([exn? (compose1 raise-user-error exn-message)]) (apply collection-path elems)) - ;; otherwise, it's probably a collection with nothing to compile + ;; otherwise, it's probably a collection with nothing to compile; ;; spell the name - (setup-printf "WARNING" + (setup-printf "warning" "nothing to compile in a given collection path: \"~a\"" (string-join sc "/"))) ccs) From e5c5feca6d054ae1429603a1e7c19226e362a890 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Tue, 15 Dec 2015 14:26:00 -0500 Subject: [PATCH 182/369] Bind channel properly in `place/context`. Closes #1169. --- pkgs/racket-test-core/tests/racket/place-utils.rkt | 7 +++++++ pkgs/racket-test-core/tests/racket/place.rktl | 4 ++++ racket/collects/racket/place.rkt | 4 ++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/place-utils.rkt b/pkgs/racket-test-core/tests/racket/place-utils.rkt index ec2ee243df..2f362468b1 100644 --- a/pkgs/racket-test-core/tests/racket/place-utils.rkt +++ b/pkgs/racket-test-core/tests/racket/place-utils.rkt @@ -86,4 +86,11 @@ #'(time body ...) |# ])) + +(module place-test-submod racket/base + (require racket/place) + (provide p) + (define (p x) + (place-channel-get (place/context ch + (place-channel-put ch x))))) diff --git a/pkgs/racket-test-core/tests/racket/place.rktl b/pkgs/racket-test-core/tests/racket/place.rktl index 8dab0d0c4e..f8bcb705e1 100644 --- a/pkgs/racket-test-core/tests/racket/place.rktl +++ b/pkgs/racket-test-core/tests/racket/place.rktl @@ -102,4 +102,8 @@ (test (not (place-enabled?)) place-message-allowed? (cons v 1)) (test (not (place-enabled?)) place-message-allowed? (vector v))) + +(require (submod "place-utils.rkt" place-test-submod)) +(test 0 p 0) + (report-errs) diff --git a/racket/collects/racket/place.rkt b/racket/collects/racket/place.rkt index e62cb8e71b..b2ade96e54 100644 --- a/racket/collects/racket/place.rkt +++ b/racket/collects/racket/place.rkt @@ -238,7 +238,7 @@ (define-syntax (place/context stx) (syntax-parse stx [(_ ch:id body:expr ...) - (define b #'(let () body ...)) + (define b #'(lambda (ch) body ...)) (define/with-syntax b* (local-expand b 'expression null)) (define/with-syntax (fvs ...) (free-vars #'b*)) (define/with-syntax (i ...) (for/list ([(v i) (in-indexed (syntax->list #'(fvs ...)))]) i)) @@ -246,7 +246,7 @@ #'(let () (define p (place ch (let* ([v (place-channel-get ch)] [fvs (vector-ref v i)] ...) - b*))) + (b* ch)))) (define vec (vector fvs ...)) (for ([e (in-vector vec)] [n (in-list (syntax->list (quote-syntax (fvs ...))))]) From 962a72dfda7b0d808f3157887b5e8b9bde5c7d23 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Thu, 17 Dec 2015 19:35:08 -0500 Subject: [PATCH 183/369] Properly handle (place ...) in submodules. Closes #1173 and PR 12934. --- racket/collects/racket/place.rkt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/racket/collects/racket/place.rkt b/racket/collects/racket/place.rkt index b2ade96e54..237e71f194 100644 --- a/racket/collects/racket/place.rkt +++ b/racket/collects/racket/place.rkt @@ -10,6 +10,7 @@ racket/place/private/th-place racket/place/private/prop racket/private/streams + racket/match (for-syntax racket/base @@ -233,7 +234,12 @@ (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 `(submod ,(if (symbol? name) `(quote ,name) name) ,submod-name) 'main in out err)) + (define submod-ref + (match name + [(? symbol?) `(quote 'name)] + [(? path?) `(submod ,name ,submod-name)] + [`(,p ,s ...) `(submod ,p ,@s ,submod-name)])) + (start-place-func who submod-ref 'main in out err)) (define-syntax (place/context stx) (syntax-parse stx From 506c9be0cdff759aeb22dc6fe1e873bc6dc9853c Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Fri, 18 Dec 2015 20:41:31 -0600 Subject: [PATCH 184/369] add the ability to make chaperone contracts to ->i --- .../tests/racket/contract/arrow-i.rkt | 31 +- .../racket/contract/private/arr-i-parse.rkt | 35 +- .../racket/contract/private/arr-i.rkt | 343 ++++++++++-------- 3 files changed, 247 insertions(+), 162 deletions(-) diff --git a/pkgs/racket-test/tests/racket/contract/arrow-i.rkt b/pkgs/racket-test/tests/racket/contract/arrow-i.rkt index a7b8cc1afc..4292d35971 100644 --- a/pkgs/racket-test/tests/racket/contract/arrow-i.rkt +++ b/pkgs/racket-test/tests/racket/contract/arrow-i.rkt @@ -2,7 +2,7 @@ (require "test-util.rkt") (parameterize ([current-contract-namespace - (make-basic-contract-namespace)]) + (make-basic-contract-namespace 'racket/contract/parametric)]) (define exn:fail:contract:blame? (contract-eval 'exn:fail:contract:blame?)) (test/no-error '(->i ([x integer?]) ([y integer?]) any)) @@ -1397,4 +1397,31 @@ 1)) ;; this used to cause a runtime error in the code that parses ->i - (test/no-error '(->i ([x () any/c] [y (x) any/c]) any))) + (test/no-error '(->i ([x () any/c] [y (x) any/c]) any)) + + (test/spec-passed/result + 'really-chaperones.1 + '(let ([f (λ () 1)]) + (chaperone-of? + (contract (->i #:chaperone () any) f 'pos 'neg) + f)) + #t) + + (test/spec-passed/result + 'really-chaperones.2 + '(let ([f (λ () 1)]) + (chaperone-of? + (contract (->i () [_ (new-∀/c)]) f 'pos 'neg) + f)) + #f) + + (test/spec-passed/result + 'really-chaperones.3 + '(with-handlers ([exn:fail? + (λ (x) + (regexp-match? #rx"^->i:.*chaperone" (exn-message x)))]) + ((contract (->i #:chaperone ([x integer?] [y (x) (new-∀/c)]) any) + (λ (x y) x) + 'pos 'neg) 1 2) + "didn't raise an error") + #t)) diff --git a/racket/collects/racket/contract/private/arr-i-parse.rkt b/racket/collects/racket/contract/private/arr-i-parse.rkt index 7eabb799c1..ab472d387c 100644 --- a/racket/collects/racket/contract/private/arr-i-parse.rkt +++ b/racket/collects/racket/contract/private/arr-i-parse.rkt @@ -20,12 +20,13 @@ code does the parsing and validation of the syntax. |# +;; istx-is-chaperone-contract? : boolean? ;; args : (listof arg?) ;; rst : (or/c #f arg/res?) ;; pre : (listof pre/post?) ;; ress : (or/c #f (listof eres?) (listof lres?)) ;; post : (listof pre/post?) -(struct istx (args rst pre ress post) #:transparent) +(struct istx (is-chaperone-contract? args rst pre ress post) #:transparent) ;; NOTE: the ress field may contain a mixture of eres and lres structs ;; but only temporarily; in that case, a syntax error ;; is signaled and the istx struct is not used afterwards @@ -59,11 +60,13 @@ code does the parsing and validation of the syntax. (define (parse-->i stx) (if (identifier? stx) (raise-syntax-error #f "expected ->i to follow an open parenthesis" stx) - (let-values ([(raw-mandatory-doms raw-optional-doms - id/rest-id pre-cond range post-cond) + (let-values ([(is-chaperone-contract? + raw-mandatory-doms raw-optional-doms + id/rest-id pre-cond range post-cond) (pull-out-pieces stx)]) (let ([candidate - (istx (append (parse-doms stx #f raw-mandatory-doms) + (istx is-chaperone-contract? + (append (parse-doms stx #f raw-mandatory-doms) (parse-doms stx #t raw-optional-doms)) id/rest-id pre-cond @@ -393,12 +396,26 @@ code does the parsing and validation of the syntax. ;; pull-out-pieces : ;; stx -> (values raw-mandatory-doms raw-optional-doms id/rest-id pre-cond range post-cond) (define (pull-out-pieces stx) - (let*-values ([(raw-mandatory-doms leftover) + (let*-values ([(is-chaperone-contract? leftover) (syntax-case stx () - [(_ (raw-mandatory-doms ...) . leftover) + [(_ #:chaperone . leftover) + (values #t #'leftover)] + [(_ . leftover) + (let ([lst (syntax->list stx)]) + (when (null? (cdr lst)) + (raise-syntax-error #f "expected a sequence of mandatory domain elements" + stx)) + (when (keyword? (syntax-e (cadr lst))) + (raise-syntax-error #f "unknown keyword" + stx + (cadr lst))) + (values #f #'leftover))])] + [(raw-mandatory-doms leftover) + (syntax-case leftover () + [((raw-mandatory-doms ...) . leftover) (values (syntax->list #'(raw-mandatory-doms ...)) #'leftover)] - [(_ a . leftover) + [(a . leftover) (raise-syntax-error #f "expected a sequence of mandatory domain elements" stx #'a)] @@ -604,7 +621,9 @@ code does the parsing and validation of the syntax. (values (reverse post-conds) leftover)]))]) (syntax-case leftover () [() - (values raw-mandatory-doms raw-optional-doms id/rest-id pre-conds range post-conds)] + (values is-chaperone-contract? + raw-mandatory-doms raw-optional-doms id/rest-id pre-conds + range post-conds)] [(a . b) (raise-syntax-error #f "bad syntax" stx #'a)] [_ diff --git a/racket/collects/racket/contract/private/arr-i.rkt b/racket/collects/racket/contract/private/arr-i.rkt index 5c4c7a547f..bc2ffe864d 100644 --- a/racket/collects/racket/contract/private/arr-i.rkt +++ b/racket/collects/racket/contract/private/arr-i.rkt @@ -27,7 +27,7 @@ (provide (rename-out [->i/m ->i])) -(define (build-??-args ctc blame) +(define (build-??-args c-or-i-procedure ctc blame) (define arg-ctc-projs (map (λ (x) (contract-projection (->i-arg-contract x))) (->i-arg-ctcs ctc))) (define indy-arg-ctc-projs (map (λ (x) (contract-projection (cdr x))) (->i-indy-arg-ctcs ctc))) @@ -81,7 +81,8 @@ [rng-pr (in-list (->i-indy-rng-ctcs ctc))]) (rng-proj (blame-add-context indy-rng-blame (format "the ~a result of" (car rng-pr)))))) - (list* (λ (val mtd?) + (list* c-or-i-procedure + (λ (val mtd?) (if has-rest (check-procedure/more val mtd? (->i-mandatory-args ctc) @@ -104,10 +105,10 @@ partial-indy-rngs))) (define arr->i-proj - (λ (ctc) + (λ (ctc c-or-i-procedure) (define func (->i-mk-wrapper ctc)) (λ (blame) - (define ???-args (build-??-args ctc blame)) + (define ???-args (build-??-args c-or-i-procedure ctc blame)) (apply func ???-args)))) @@ -183,140 +184,160 @@ pre/post-procs mandatory-args opt-args mandatory-kwds opt-kwds rest mtd? here mk-wrapper mk-val-first-wrapper name-info) - #:property prop:custom-write custom-write-property-proc - #:property prop:contract - (build-contract-property - #:val-first-projection - (λ (ctc) - (define blame-accepting-proj (arr->i-proj ctc)) - (λ (blame) - (λ (val) - (wrapped-extra-arg-arrow - (λ (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?) - (let loop ([infos infos] - [ctcs ctcs] - [dep-ctcs dep-ctcs]) - (cond - [(null? infos) '()] - [else - (let* ([info (car infos)] - [dep/nodep (list-ref info 0)] - [var (list-ref info 1)] - [vars (list-ref info 2)] - [kwd (list-ref info 3)]) - (case dep/nodep - [(nodep) - (if (skip? info) - (loop (cdr infos) (cdr ctcs) dep-ctcs) - `(,@(if kwd - (list kwd) - (list)) - [,var ,(contract-name (car ctcs))] - . - ,(loop (cdr infos) (cdr ctcs) dep-ctcs)))] - [(dep) - (define body-src (list-ref info 5)) - (if (skip? info) - (loop (cdr infos) ctcs (cdr dep-ctcs)) - `(,@(if kwd - (list kwd) - (list)) - [,var ,vars ,body-src] - . - ,(loop (cdr infos) ctcs (cdr dep-ctcs))))]))]))) - (let* ([name-info (->i-name-info ctc)] - [args-info (vector-ref name-info 0)] - [rest-info (vector-ref name-info 1)] - [pre-infos (vector-ref name-info 2)] - [rng-info (vector-ref name-info 3)] - [post-infos (vector-ref name-info 4)]) - `(->i ,(arg/ress->spec args-info - (map ->i-arg-contract (->i-arg-ctcs ctc)) - (->i-arg-dep-ctcs ctc) - (λ (x) (list-ref x 4))) - ,@(let ([rests (arg/ress->spec args-info - (map ->i-arg-contract (->i-arg-ctcs ctc)) - (->i-arg-dep-ctcs ctc) - (λ (x) (not (list-ref x 4))))]) - (if (null? rests) - '() - (list rests))) - ,@(if rest-info - (case (car rest-info) - [(nodep) `(#:rest - [,(list-ref rest-info 1) - ,(contract-name - (car - (reverse - (map ->i-arg-contract (->i-arg-ctcs ctc)))))])] - [(dep) `(#:rest [,(list-ref rest-info 1) - ,(list-ref rest-info 2) - ,(list-ref rest-info 3)])]) - '()) - ,@(apply - append - (for/list ([pre-info pre-infos]) - (define ids (list-ref pre-info 0)) - (define name (list-ref pre-info 1)) - (define code (list-ref pre-info 2)) - (cond - [(string? name) - `(#:pre/name ,ids ,name ,code)] - [(equal? name 'bool) - `(#:pre ,ids ,code)] - [(equal? name 'desc) - `(#:pre/desc ,ids ,code)]))) - ,(cond - [(not rng-info) - 'any] - [else - (let ([infos (arg/ress->spec rng-info - (map cdr (->i-rng-ctcs ctc)) - (->i-rng-dep-ctcs ctc) - (λ (x) #f))]) - (cond - [(or (null? infos) (not (null? (cdr infos)))) - `(values ,@infos)] - [else - (car infos)]))]) - ,@(apply - append - (for/list ([post-info post-infos]) - (define ids (list-ref post-info 0)) - (define name (list-ref post-info 1)) - (define code (list-ref post-info 2)) - (cond - [(string? name) - `(#:post/name ,ids ,name ,code)] - [(equal? name 'bool) - `(#:post ,ids ,code)] - [(equal? name 'desc) - `(#:post/desc ,ids ,code)])))))) - #:first-order - (λ (ctc) - (let ([has-rest (->i-rest ctc)] - [mtd? (->i-mtd? ctc)] - [mand-args (->i-mandatory-args ctc)] - [opt-args (->i-opt-args ctc)] - [mand-kwds (->i-mandatory-kwds ctc)] - [opt-kwds (->i-opt-kwds ctc)]) - (λ (val) - (if has-rest - (check-procedure/more val mtd? mand-args mand-kwds opt-kwds #f #f) - (check-procedure val mtd? mand-args opt-args mand-kwds opt-kwds #f #f))))) - #:exercise exercise->i - #:stronger (λ (this that) (eq? this that)))) ;; WRONG + #:property prop:custom-write custom-write-property-proc) + +(define (mk-prop chaperone?) + (define c-or-i-procedure (if chaperone? chaperone-procedure impersonate-procedure)) + ((if chaperone? build-chaperone-contract-property build-contract-property) + #:val-first-projection + (λ (ctc) + (define blame-accepting-proj (arr->i-proj ctc c-or-i-procedure)) + (λ (blame) + (λ (val) + (wrapped-extra-arg-arrow + (λ (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 c-or-i-procedure)) + (λ (blame) + (λ (val neg-party) + ((blame-accepting-proj (blame-add-missing-party blame neg-party)) val)))) + #:projection (λ (ctc) (arr->i-proj ctc c-or-i-procedure)) + #:name (λ (ctc) + (define (arg/ress->spec infos ctcs dep-ctcs skip?) + (let loop ([infos infos] + [ctcs ctcs] + [dep-ctcs dep-ctcs]) + (cond + [(null? infos) '()] + [else + (let* ([info (car infos)] + [dep/nodep (list-ref info 0)] + [var (list-ref info 1)] + [vars (list-ref info 2)] + [kwd (list-ref info 3)]) + (case dep/nodep + [(nodep) + (if (skip? info) + (loop (cdr infos) (cdr ctcs) dep-ctcs) + `(,@(if kwd + (list kwd) + (list)) + [,var ,(contract-name (car ctcs))] + . + ,(loop (cdr infos) (cdr ctcs) dep-ctcs)))] + [(dep) + (define body-src (list-ref info 5)) + (if (skip? info) + (loop (cdr infos) ctcs (cdr dep-ctcs)) + `(,@(if kwd + (list kwd) + (list)) + [,var ,vars ,body-src] + . + ,(loop (cdr infos) ctcs (cdr dep-ctcs))))]))]))) + (let* ([name-info (->i-name-info ctc)] + [args-info (vector-ref name-info 0)] + [rest-info (vector-ref name-info 1)] + [pre-infos (vector-ref name-info 2)] + [rng-info (vector-ref name-info 3)] + [post-infos (vector-ref name-info 4)]) + `(->i ,(arg/ress->spec args-info + (map ->i-arg-contract (->i-arg-ctcs ctc)) + (->i-arg-dep-ctcs ctc) + (λ (x) (list-ref x 4))) + ,@(let ([rests (arg/ress->spec args-info + (map ->i-arg-contract (->i-arg-ctcs ctc)) + (->i-arg-dep-ctcs ctc) + (λ (x) (not (list-ref x 4))))]) + (if (null? rests) + '() + (list rests))) + ,@(if rest-info + (case (car rest-info) + [(nodep) `(#:rest + [,(list-ref rest-info 1) + ,(contract-name + (car + (reverse + (map ->i-arg-contract (->i-arg-ctcs ctc)))))])] + [(dep) `(#:rest [,(list-ref rest-info 1) + ,(list-ref rest-info 2) + ,(list-ref rest-info 3)])]) + '()) + ,@(apply + append + (for/list ([pre-info pre-infos]) + (define ids (list-ref pre-info 0)) + (define name (list-ref pre-info 1)) + (define code (list-ref pre-info 2)) + (cond + [(string? name) + `(#:pre/name ,ids ,name ,code)] + [(equal? name 'bool) + `(#:pre ,ids ,code)] + [(equal? name 'desc) + `(#:pre/desc ,ids ,code)]))) + ,(cond + [(not rng-info) + 'any] + [else + (let ([infos (arg/ress->spec rng-info + (map cdr (->i-rng-ctcs ctc)) + (->i-rng-dep-ctcs ctc) + (λ (x) #f))]) + (cond + [(or (null? infos) (not (null? (cdr infos)))) + `(values ,@infos)] + [else + (car infos)]))]) + ,@(apply + append + (for/list ([post-info post-infos]) + (define ids (list-ref post-info 0)) + (define name (list-ref post-info 1)) + (define code (list-ref post-info 2)) + (cond + [(string? name) + `(#:post/name ,ids ,name ,code)] + [(equal? name 'bool) + `(#:post ,ids ,code)] + [(equal? name 'desc) + `(#:post/desc ,ids ,code)])))))) + #:first-order + (λ (ctc) + (let ([has-rest (->i-rest ctc)] + [mtd? (->i-mtd? ctc)] + [mand-args (->i-mandatory-args ctc)] + [opt-args (->i-opt-args ctc)] + [mand-kwds (->i-mandatory-kwds ctc)] + [opt-kwds (->i-opt-kwds ctc)]) + (λ (val) + (if has-rest + (check-procedure/more val mtd? mand-args mand-kwds opt-kwds #f #f) + (check-procedure val mtd? mand-args opt-args mand-kwds opt-kwds #f #f))))) + #:exercise exercise->i + #:stronger (λ (this that) (eq? this that)))) ;; WRONG + +(struct chaperone->i ->i () #:property prop:chaperone-contract (mk-prop #t)) +(struct impersonator->i ->i () #:property prop:contract (mk-prop #f)) +(define (make-->i is-chaperone-contract? blame-info + arg-ctcs arg-dep-ctcs indy-arg-ctcs + rng-ctcs rng-dep-ctcs indy-rng-ctcs + pre/post-procs + mandatory-args opt-args mandatory-kwds opt-kwds rest + mtd? here mk-wrapper mk-val-first-wrapper name-info) + (define maker (if is-chaperone-contract? chaperone->i impersonator->i)) + (maker blame-info + arg-ctcs arg-dep-ctcs indy-arg-ctcs + rng-ctcs rng-dep-ctcs indy-rng-ctcs + pre/post-procs + mandatory-args opt-args mandatory-kwds opt-kwds rest + mtd? here mk-wrapper mk-val-first-wrapper name-info)) + + ;; find-ordering : (listof arg) -> (values (listof arg) (listof number)) ;; sorts the arguments according to the dependency order. @@ -655,7 +676,7 @@ evaluted left-to-right.) ;; adds nested lets that bind the wrapper-args and the indy-arg/res-vars to projected values, ;; with 'body' in the body of the let also handles adding code to check to see if unsupplied ;; args are present (skipping the contract check, if so) -(define-for-syntax (add-wrapper-let body swapped-blame? neg-calls? +(define-for-syntax (add-wrapper-let body is-chaperone-contract? swapped-blame? neg-calls? ordered-arg/reses indicies arg/res-proj-vars indy-arg/res-proj-vars wrapper-arg/ress indy-arg/res-vars @@ -706,11 +727,12 @@ evaluted left-to-right.) wrapper-arg (cond [(and (eres? an-arg/res) (arg/res-vars an-arg/res)) - #`(un-dep #,(eres-eid an-arg/res) - #,wrapper-arg - #,(build-blame-identifier #f - swapped-blame? - (arg/res-var an-arg/res)))] + #`(#,(if is-chaperone-contract? #'un-dep/chaperone #'un-dep) + #,(eres-eid an-arg/res) + #,wrapper-arg + #,(build-blame-identifier #f + swapped-blame? + (arg/res-var an-arg/res)))] [(arg/res-vars an-arg/res) #`(#,arg/res-proj-var #,@(map (λ (var) (arg/res-to-indy-var indy-arg-vars @@ -789,6 +811,7 @@ evaluted left-to-right.) #,(add-wrapper-let (add-post-cond an-istx indy-arg-vars ordered-args indy-res-vars ordered-ress #`(values #,@(vector->list wrapper-ress))) + (istx-is-chaperone-contract? an-istx) #f #f ordered-ress res-indices res-proj-vars indy-res-proj-vars @@ -868,6 +891,7 @@ evaluted left-to-right.) (istx-rst an-istx) wrapper-args this-param))) + (istx-is-chaperone-contract? an-istx) #t #f ordered-args arg-indices arg-proj-vars indy-arg-proj-vars @@ -879,7 +903,7 @@ evaluted left-to-right.) #`(λ #,wrapper-proc-arglist (λ (val) (chk val #,(and (syntax-parameter-value #'making-a-method) #t)) - (impersonate-procedure + (c-or-i-procedure val (let ([arg-checker (λ #,(args/vars->arglist an-istx wrapper-args this-param) @@ -954,7 +978,7 @@ evaluted left-to-right.) '())))) (define wrapper-proc-arglist - #`(chk ctc blame swapped-blame #,@(map car blame-ids) + #`(c-or-i-procedure chk ctc blame swapped-blame #,@(map car blame-ids) ;; the pre- and post-condition procs #,@(for/list ([pres (istx-pre an-istx)] @@ -1028,7 +1052,7 @@ evaluted left-to-right.) (define this-param (and (syntax-parameter-value #'making-a-method) (car (generate-temporaries '(this))))) - #`(λ #,wrapper-proc-arglist + #`(λ #,wrapper-proc-arglist (λ (f) (λ (neg-party #,@(args/vars->arglist an-istx wrapper-args this-param)) #,(add-wrapper-let @@ -1037,6 +1061,7 @@ evaluted left-to-right.) (istx-rst an-istx) wrapper-args this-param) + (istx-is-chaperone-contract? an-istx) #t #t ordered-args arg-indices arg-proj-vars indy-arg-proj-vars @@ -1059,8 +1084,17 @@ evaluted left-to-right.) #`(f #,@argument-list))) (begin-encourage-inline - (define (un-dep ctc obj blame) - (let ([ctc (coerce-contract '->i ctc)]) + (define (un-dep/chaperone orig-ctc obj blame) + (let ([ctc (coerce-contract '->i orig-ctc)]) + (unless (chaperone-contract? ctc) + (raise-argument-error '->i + "chaperone-contract?" + orig-ctc)) + (((contract-projection ctc) blame) obj)))) + +(begin-encourage-inline + (define (un-dep orig-ctc obj blame) + (let ([ctc (coerce-contract '->i orig-ctc)]) (((contract-projection ctc) blame) obj)))) (define-for-syntax (mk-used-indy-vars an-istx) @@ -1160,11 +1194,14 @@ evaluted left-to-right.) "could not find ~s in ~s\n" an-id arg/ress-to-look-in)) ans)) + + (define is-chaperone-contract? (istx-is-chaperone-contract? an-istx)) #`(let ([arg-exp-xs (coerce-contract '->i arg-exps)] ... [res-exp-xs (coerce-contract '->i res-exps)] ...) #,(syntax-property - #`(->i + #`(make-->i + #,is-chaperone-contract? ;; the information needed to make the blame records and their new contexts '#,blame-ids ;; all of the non-dependent argument contracts @@ -1185,7 +1222,8 @@ evaluted left-to-right.) #,@(arg/res-vars arg) ;; this used to use opt/direct, but ;; opt/direct duplicates code (bad!) - (un-dep #,ctc-stx val blame)))) + (#,(if is-chaperone-contract? #'un-dep/chaperone #'un-dep) + #,ctc-stx val blame)))) ;; then the non-dependent argument contracts that are themselves dependend on (list #,@(filter values (map (λ (arg/res indy-id) @@ -1225,7 +1263,8 @@ evaluted left-to-right.) ;; this used to use opt/direct, but ;; opt/direct duplicates code (bad!) #,@(arg/res-vars arg) - (un-dep #,arg-stx val blame))))) + (#,(if is-chaperone-contract? #'un-dep/chaperone #'un-dep) + #,arg-stx val blame))))) #''()) #,(if (istx-ress an-istx) #`(list #,@(filter values From 2fad028fd5b1d8bc3c45d0de538d0d2dba35455b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 19 Dec 2015 07:53:58 -0700 Subject: [PATCH 185/369] fix incremental GC bug Also, fix reporting of whether a minor GC was in incremental mode. --- racket/src/racket/gc2/newgc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 4ccbeed7c8..25ce68c1dd 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -4241,6 +4241,7 @@ static int propagate_incremental_marks(NewGC *gc, int do_emph, int fuel) int save_inc, save_check, init_fuel = fuel; if (!fuel) return 0; + if (!gc->inc_mark_stack) return fuel; GC_ASSERT(gc->mark_gen1); @@ -6237,7 +6238,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin finalizer passes */ (void)mark_and_finalize_all(gc, 0, no_full TIME_ARGS); - if (do_incremental) { + if (gc->started_incremental) { if (!gc->all_marked_incremental) { mark_finalizer_structs(gc, FNL_LEVEL_GEN_1); if (!mark_stack_is_empty(gc->inc_mark_stack)) { @@ -6400,7 +6401,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin is_master = (gc == MASTERGC); #endif park_for_inform_callback(gc); - gc->GC_collect_inform_callback(is_master, gc->gc_full, do_incremental, + gc->GC_collect_inform_callback(is_master, gc->gc_full, gc->started_incremental, /* original memory use: */ old_mem_use + old_gen0, /* new memory use; gen0_phantom_count can be non-zero due to From 7d2b5382934d93b63ecfbad687eeacaba0208ccb Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 19 Dec 2015 09:37:00 -0700 Subject: [PATCH 186/369] fix marshaling of a compiled top-level `begin-for-syntax` Closes #1174 --- pkgs/racket-test-core/tests/racket/syntax.rktl | 9 +++++++++ racket/src/racket/src/marshal.c | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test-core/tests/racket/syntax.rktl b/pkgs/racket-test-core/tests/racket/syntax.rktl index bb2dc38bae..2e1d4a920e 100644 --- a/pkgs/racket-test-core/tests/racket/syntax.rktl +++ b/pkgs/racket-test-core/tests/racket/syntax.rktl @@ -1952,6 +1952,15 @@ procedure? (eval (datum->syntax #'here '(lambda () (sort '(1))) (list 'a #f #f #f #f))))) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check marshaling of a top-level `begin-for-syntax`: + +(parameterize ([current-namespace (make-base-namespace)]) + (eval '(require (for-syntax racket/base))) + (write (compile '(begin-for-syntax + (require racket/match))) + (open-output-bytes))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/racket/src/racket/src/marshal.c b/racket/src/racket/src/marshal.c index 8ccc4e553a..7efa4de367 100644 --- a/racket/src/racket/src/marshal.c +++ b/racket/src/racket/src/marshal.c @@ -463,7 +463,7 @@ static Scheme_Object *read_begin_for_syntax(Scheme_Object *obj) static Scheme_Object *write_begin_for_syntax(Scheme_Object *obj) { - return write_define_values(obj); + return scheme_clone_vector(obj, 0, 0); } static Scheme_Object *read_set_bang(Scheme_Object *obj) From 4a29792934c72d550064fa5b550dc27c12be9a93 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 19 Dec 2015 09:45:57 -0600 Subject: [PATCH 187/369] port ->i to late-neg --- .../racket/contract/private/arr-i.rkt | 73 ++++++++++--------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/racket/collects/racket/contract/private/arr-i.rkt b/racket/collects/racket/contract/private/arr-i.rkt index bc2ffe864d..b97fae4a79 100644 --- a/racket/collects/racket/contract/private/arr-i.rkt +++ b/racket/collects/racket/contract/private/arr-i.rkt @@ -28,11 +28,12 @@ (provide (rename-out [->i/m ->i])) (define (build-??-args c-or-i-procedure ctc blame) - (define arg-ctc-projs (map (λ (x) (contract-projection (->i-arg-contract x))) (->i-arg-ctcs ctc))) - (define indy-arg-ctc-projs (map (λ (x) (contract-projection (cdr x))) + (define arg-ctc-projs (map (λ (x) (contract-late-neg-projection (->i-arg-contract x))) + (->i-arg-ctcs ctc))) + (define indy-arg-ctc-projs (map (λ (x) (contract-late-neg-projection (cdr x))) (->i-indy-arg-ctcs ctc))) - (define rng-ctc-projs (map (λ (x) (contract-projection (cdr x))) (->i-rng-ctcs ctc))) - (define indy-rng-ctc-projs (map (λ (x) (contract-projection (cdr x))) + (define rng-ctc-projs (map (λ (x) (contract-late-neg-projection (cdr x))) (->i-rng-ctcs ctc))) + (define indy-rng-ctc-projs (map (λ (x) (contract-late-neg-projection (cdr x))) (->i-indy-rng-ctcs ctc))) (define has-rest (->i-rest ctc)) (define here (->i-here ctc)) @@ -104,7 +105,7 @@ (->i-rng-dep-ctcs ctc) partial-indy-rngs))) -(define arr->i-proj +(define arr->i-late-neg-proj (λ (ctc c-or-i-procedure) (define func (->i-mk-wrapper ctc)) (λ (blame) @@ -191,20 +192,16 @@ ((if chaperone? build-chaperone-contract-property build-contract-property) #:val-first-projection (λ (ctc) - (define blame-accepting-proj (arr->i-proj ctc c-or-i-procedure)) + (define blame-accepting-proj (arr->i-late-neg-proj ctc c-or-i-procedure)) (λ (blame) + (define val+neg-party-accepting-proj (blame-accepting-proj blame)) (λ (val) (wrapped-extra-arg-arrow (λ (neg-party) - ((blame-accepting-proj (blame-add-missing-party blame neg-party)) val)) + (val+neg-party-accepting-proj val neg-party)) (->i-mk-val-first-wrapper ctc))))) #:late-neg-projection - (λ (ctc) - (define blame-accepting-proj (arr->i-proj ctc c-or-i-procedure)) - (λ (blame) - (λ (val neg-party) - ((blame-accepting-proj (blame-add-missing-party blame neg-party)) val)))) - #:projection (λ (ctc) (arr->i-proj ctc c-or-i-procedure)) + (λ (ctc) (arr->i-late-neg-proj ctc c-or-i-procedure)) #:name (λ (ctc) (define (arg/ress->spec infos ctcs dep-ctcs skip?) (let loop ([infos infos] @@ -576,7 +573,7 @@ evaluted left-to-right.) (define-for-syntax (maybe-generate-temporary x) (and x (car (generate-temporaries (list x))))) -(define (signal-pre/post pre? val kind blame condition-result . var-infos) +(define (signal-pre/post pre? val kind blame neg-party condition-result . var-infos) (define vars-str (apply string-append @@ -599,7 +596,7 @@ evaluted left-to-right.) vars-str)] [else (pre-post/desc-result->string condition-result pre? '->i)])) - (raise-blame-error blame val "~a" msg)) + (raise-blame-error blame #:missing-party neg-party val "~a" msg)) (define-for-syntax (add-pre-cond an-istx indy-arg-vars ordered-args indy-res-vars ordered-ress call-stx) @@ -620,6 +617,7 @@ evaluted left-to-right.) val '#,(pre/post-kind pre) swapped-blame + neg-party condition-result #,@(map (λ (x) #`(list '#,x #,(arg/res-to-indy-var indy-arg-vars @@ -650,6 +648,7 @@ evaluted left-to-right.) val '#,(pre/post-kind post) blame + neg-party condition-result #,@(map (λ (x) #`(list '#,x #,(arg/res-to-indy-var indy-arg-vars ordered-args @@ -661,6 +660,7 @@ evaluted left-to-right.) ;; add-wrapper-let : ;; syntax? -- placed into the body position of the generated let expression +;; boolean? -- indicates if this is a chaperone contract ;; boolean? -- indicates if this is an arg or a res; affects only how blame-var-table is filled in ;; (listof arg/res) -- sorted version of the arg/res structs, ordered by evaluation order ;; (listof int) -- indices that give the mapping from the ordered-args to the original order @@ -691,10 +691,10 @@ evaluted left-to-right.) stx)) (for/fold ([body body]) - ([indy-arg/res-var (in-list indy-arg/res-vars)] - [an-arg/res (in-list ordered-arg/reses)] - [index indicies] - [i (in-naturals)]) + ([indy-arg/res-var (in-list indy-arg/res-vars)] + [an-arg/res (in-list ordered-arg/reses)] + [index indicies] + [i (in-naturals)]) (let ([wrapper-arg (vector-ref wrapper-arg/ress index)] [arg/res-proj-var (vector-ref arg/res-proj-vars index)] [indy-arg/res-proj-var (vector-ref indy-arg/res-proj-vars index)]) @@ -716,9 +716,10 @@ evaluted left-to-right.) ordered-ress var)) (arg/res-vars an-arg/res)) - #,wrapper-arg - #,(build-blame-identifier #t swapped-blame? (arg/res-var an-arg/res))) - #`(#,indy-arg/res-proj-var #,wrapper-arg)))]) + #,wrapper-arg + #,(build-blame-identifier #t swapped-blame? (arg/res-var an-arg/res)) + neg-party) + #`(#,indy-arg/res-proj-var #,wrapper-arg neg-party)))]) (list))]) #`(let (#,@indy-binding [#,wrapper-arg @@ -732,7 +733,8 @@ evaluted left-to-right.) #,wrapper-arg #,(build-blame-identifier #f swapped-blame? - (arg/res-var an-arg/res)))] + (arg/res-var an-arg/res)) + neg-party)] [(arg/res-vars an-arg/res) #`(#,arg/res-proj-var #,@(map (λ (var) (arg/res-to-indy-var indy-arg-vars @@ -741,10 +743,11 @@ evaluted left-to-right.) ordered-ress var)) (arg/res-vars an-arg/res)) - #,wrapper-arg - #,(build-blame-identifier #f swapped-blame? (arg/res-var an-arg/res)))] + #,wrapper-arg + #,(build-blame-identifier #f swapped-blame? (arg/res-var an-arg/res)) + neg-party)] [else - #`(#,arg/res-proj-var #,wrapper-arg)]))]) + #`(#,arg/res-proj-var #,wrapper-arg neg-party)]))]) #,body))))) @@ -901,7 +904,7 @@ evaluted left-to-right.) (map cdr blame-ids) (with-syntax ([arg-checker (or (syntax-local-infer-name stx) 'arg-checker)]) #`(λ #,wrapper-proc-arglist - (λ (val) + (λ (val neg-party) (chk val #,(and (syntax-parameter-value #'making-a-method) #t)) (c-or-i-procedure val @@ -1084,18 +1087,18 @@ evaluted left-to-right.) #`(f #,@argument-list))) (begin-encourage-inline - (define (un-dep/chaperone orig-ctc obj blame) + (define (un-dep/chaperone orig-ctc obj blame neg-party) (let ([ctc (coerce-contract '->i orig-ctc)]) (unless (chaperone-contract? ctc) (raise-argument-error '->i "chaperone-contract?" orig-ctc)) - (((contract-projection ctc) blame) obj)))) + (((contract-late-neg-projection ctc) blame) obj neg-party)))) (begin-encourage-inline - (define (un-dep orig-ctc obj blame) + (define (un-dep orig-ctc obj blame neg-party) (let ([ctc (coerce-contract '->i orig-ctc)]) - (((contract-projection ctc) blame) obj)))) + (((contract-late-neg-projection ctc) blame) obj neg-party)))) (define-for-syntax (mk-used-indy-vars an-istx) (let ([vars (make-free-identifier-mapping)]) @@ -1218,12 +1221,12 @@ evaluted left-to-right.) this->i) 'racket/contract:contract-on-boundary (gensym '->i-indy-boundary))) - #`(λ (#,@orig-vars val blame) + #`(λ (#,@orig-vars val blame neg-party) #,@(arg/res-vars arg) ;; this used to use opt/direct, but ;; opt/direct duplicates code (bad!) (#,(if is-chaperone-contract? #'un-dep/chaperone #'un-dep) - #,ctc-stx val blame)))) + #,ctc-stx val blame neg-party)))) ;; then the non-dependent argument contracts that are themselves dependend on (list #,@(filter values (map (λ (arg/res indy-id) @@ -1259,12 +1262,12 @@ evaluted left-to-right.) #`(λ #,orig-vars #,@(arg/res-vars arg) (opt/c #,arg-stx)) - #`(λ (#,@orig-vars val blame) + #`(λ (#,@orig-vars val blame neg-party) ;; this used to use opt/direct, but ;; opt/direct duplicates code (bad!) #,@(arg/res-vars arg) (#,(if is-chaperone-contract? #'un-dep/chaperone #'un-dep) - #,arg-stx val blame))))) + #,arg-stx val blame neg-party))))) #''()) #,(if (istx-ress an-istx) #`(list #,@(filter values From 557b039f3ce8876c3b38956498554f31fbd8cb4f Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 19 Dec 2015 09:48:35 -0600 Subject: [PATCH 188/369] add more racket/contract non late-neg projection warnings --- racket/collects/racket/contract/base.rkt | 3 ++- .../collects/racket/contract/private/arr-i.rkt | 1 + .../racket/contract/private/arrow-val-first.rkt | 1 + .../collects/racket/contract/private/misc.rkt | 17 +++++++++++------ 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/racket/collects/racket/contract/base.rkt b/racket/collects/racket/contract/base.rkt index ccb1991c26..dec48b2016 100644 --- a/racket/collects/racket/contract/base.rkt +++ b/racket/collects/racket/contract/base.rkt @@ -49,7 +49,8 @@ (except-out (all-from-out "private/misc.rkt") check-between/c check-unary-between/c - random-any/c) + random-any/c + maybe-warn-about-val-first) symbols or/c first-or/c one-of/c flat-rec-contract provide/contract diff --git a/racket/collects/racket/contract/private/arr-i.rkt b/racket/collects/racket/contract/private/arr-i.rkt index b97fae4a79..ba5eddfa20 100644 --- a/racket/collects/racket/contract/private/arr-i.rkt +++ b/racket/collects/racket/contract/private/arr-i.rkt @@ -193,6 +193,7 @@ #:val-first-projection (λ (ctc) (define blame-accepting-proj (arr->i-late-neg-proj ctc c-or-i-procedure)) + (maybe-warn-about-val-first ctc) (λ (blame) (define val+neg-party-accepting-proj (blame-accepting-proj blame)) (λ (val) diff --git a/racket/collects/racket/contract/private/arrow-val-first.rkt b/racket/collects/racket/contract/private/arrow-val-first.rkt index 046750d58b..f8c0e94f40 100644 --- a/racket/collects/racket/contract/private/arrow-val-first.rkt +++ b/racket/collects/racket/contract/private/arrow-val-first.rkt @@ -1152,6 +1152,7 @@ (define (make-property build-X-property chaperone-or-impersonate-procedure) (define val-first-proj (λ (->stct) + (maybe-warn-about-val-first ->stct) (->-proj chaperone-or-impersonate-procedure ->stct (base->-min-arity ->stct) (base->-doms ->stct) diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index 5d6bdc6726..7cd5432198 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -68,7 +68,9 @@ random-any/c rename-contract - if/c) + if/c + + maybe-warn-about-val-first) (define-syntax (flat-murec-contract stx) (syntax-case stx () @@ -2108,15 +2110,18 @@ x))))) (define warn-about-val-first? (make-parameter #t)) +(define (maybe-warn-about-val-first ctc) + (when (warn-about-val-first?) + (log-racket/contract-warning + "building val-first-projection of contract ~s for~a" + ctc + (build-context)))) + (define (get/build-val-first-projection ctc) (cond [(contract-struct-val-first-projection ctc) => values] [else - (when (warn-about-val-first?) - (log-racket/contract-warning - "building val-first-projection of contract ~s for~a" - ctc - (build-context))) + (maybe-warn-about-val-first ctc) (late-neg-projection->val-first-projection (get/build-late-neg-projection ctc))])) (define (late-neg-projection->val-first-projection lnp) From 8e2179a6eb028b3399e0d8fa9676c1dc138429a2 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 19 Dec 2015 10:38:04 -0600 Subject: [PATCH 189/369] port struct-type-property/c to late-neg and add some tests for it --- .../racket/contract/struct-type-property.rkt | 77 +++++++++++++++++++ .../racket/contract/private/struct-prop.rkt | 16 ++-- 2 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 pkgs/racket-test/tests/racket/contract/struct-type-property.rkt diff --git a/pkgs/racket-test/tests/racket/contract/struct-type-property.rkt b/pkgs/racket-test/tests/racket/contract/struct-type-property.rkt new file mode 100644 index 0000000000..45d8023be1 --- /dev/null +++ b/pkgs/racket-test/tests/racket/contract/struct-type-property.rkt @@ -0,0 +1,77 @@ +#lang racket/base + +(require "test-util.rkt") + +(parameterize ([current-contract-namespace + (make-basic-contract-namespace)]) + (test/spec-passed + 'struct-type-prop.1 + '(let () + (define-values (_prop prop? prop-ref) (make-struct-type-property 'prop)) + (define app-prop (contract (-> prop? integer? boolean?) + (λ (x v) (((prop-ref x) x) v)) + 'pos1 'neg1)) + (define prop (contract (struct-type-property/c (-> prop? (-> integer? boolean?))) + _prop + 'pos2 'neg2)) + (struct s (f) #:property prop (λ (x) (s-f x))) + (define s1 (s even?)) + (app-prop s1 5))) + + (test/neg-blame + 'struct-type-prop.2 + '(let () + (define-values (_prop prop? prop-ref) (make-struct-type-property 'prop)) + (define app-prop (contract (-> prop? integer? boolean?) + (λ (x v) (((prop-ref x) x) v)) + 'pos1 'neg1)) + (define prop (contract (struct-type-property/c (-> prop? (-> integer? boolean?))) + _prop + 'pos2 'neg2)) + (struct s (f) #:property prop (λ (x) (s-f x))) + (define s1 (s even?)) + (app-prop s1 'apple))) + + (test/neg-blame + 'struct-type-prop.3 + '(let () + (define-values (_prop prop? prop-ref) (make-struct-type-property 'prop)) + (define app-prop (contract (-> prop? integer? boolean?) + (λ (x v) (((prop-ref x) x) v)) + 'pos1 'neg1)) + (define prop (contract (struct-type-property/c (-> prop? (-> integer? boolean?))) + _prop + 'pos 'neg)) + (struct s (f) #:property prop (λ (x) (s-f x))) + (define s2 (s "not a fun")) + (app-prop s2 5))) + + (test/neg-blame + 'struct-type-prop.4 + '(let () + (define-values (_prop prop? prop-ref) (make-struct-type-property 'prop)) + (define app-prop (contract (-> prop? integer? boolean?) + (λ (x v) (((prop-ref x) x) v)) + 'pos1 'neg1)) + (define prop (contract (struct-type-property/c (-> prop? (-> integer? boolean?))) + _prop + 'pos 'neg)) + (struct s (f) #:property prop (λ (x) (s-f x))) + (define s3 (s list)) + (app-prop s3 5))) + + (test/pos-blame + 'struct-type-prop.5 + '(let () + (define-values (_prop prop? prop-ref) (make-struct-type-property 'prop)) + (define app-prop (contract (-> prop? integer? boolean?) + (λ (x v) (((prop-ref x) x) v)) + 'pos1 'neg1)) + (define prop (contract (struct-type-property/c (-> prop? (-> integer? boolean?))) + _prop + 'pos2 'neg2)) + (struct s (f) #:property prop (λ (x) (s-f x))) + (define s3 (s list?)) + ((prop-ref s3) 'apple))) + + ) diff --git a/racket/collects/racket/contract/private/struct-prop.rkt b/racket/collects/racket/contract/private/struct-prop.rkt index 52ee2345b9..24f096d8c2 100644 --- a/racket/collects/racket/contract/private/struct-prop.rkt +++ b/racket/collects/racket/contract/private/struct-prop.rkt @@ -5,23 +5,23 @@ "misc.rkt") (provide (rename-out [struct-type-property/c* struct-type-property/c])) -(define (get-stpc-proj stpc) - (define get-val-proj - (contract-projection +(define (get-stpc-late-neg-proj stpc) + (define get-late-neg-proj + (contract-late-neg-projection (struct-type-property/c-value-contract stpc))) (λ (input-blame) (define blame (blame-add-context input-blame "the struct property value of" #:swap? #t)) - (define val-proj (get-val-proj blame)) - (λ (x) + (define late-neg-proj (get-late-neg-proj blame)) + (λ (x neg-party) (unless (struct-type-property? x) - (raise-blame-error input-blame x + (raise-blame-error input-blame x #:neg-party '(expected "struct-type-property" given: "~e") x)) (define-values (nprop _pred _acc) (make-struct-type-property (wrap-name x) (lambda (val _info) - (val-proj val)) + (late-neg-proj val neg-party)) (list (cons x values)))) nprop))) @@ -37,7 +37,7 @@ 'struct-type-property/c (struct-type-property/c-value-contract c))) #:first-order (lambda (c) struct-type-property?) - #:projection get-stpc-proj)) + #:late-neg-projection get-stpc-late-neg-proj)) (define struct-type-property/c* (let ([struct-type-property/c From 93d286914e5c1945b40362de4ab25b640179cfad Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 19 Dec 2015 10:44:49 -0600 Subject: [PATCH 190/369] =?UTF-8?q?port=20new-=E2=88=80/c=20and=20new-?= =?UTF-8?q?=E2=88=83/c=20to=20late-neg?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../racket/contract/private/exists.rkt | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/racket/collects/racket/contract/private/exists.rkt b/racket/collects/racket/contract/private/exists.rkt index f5161c4dd0..8fbfda0f6a 100644 --- a/racket/collects/racket/contract/private/exists.rkt +++ b/racket/collects/racket/contract/private/exists.rkt @@ -11,19 +11,21 @@ [_new-∀/c new-∀/c]) ∀∃?) -(define (∀∃-proj ctc) - (let ([in (∀∃/c-in ctc)] - [out (∀∃/c-out ctc)] - [pred? (∀∃/c-pred? ctc)] - [neg? (∀∃/c-neg? ctc)]) - (define name (∀∃/c-name ctc)) - (λ (blame) - (if (equal? neg? (blame-swapped? blame)) - (λ (val) - (if (pred? val) - (out val) - (raise-blame-error blame val "not ~a: ~e" name val))) - in)))) +(define (∀∃-late-neg-proj ctc) + (define in (∀∃/c-in ctc)) + (define (inj v neg-party) (in v)) + (define out (∀∃/c-out ctc)) + (define pred? (∀∃/c-pred? ctc)) + (define neg? (∀∃/c-neg? ctc)) + (define name (∀∃/c-name ctc)) + (λ (blame) + (if (equal? neg? (blame-swapped? blame)) + (λ (val neg-party) + (if (pred? val) + (out val) + (raise-blame-error blame val #:missing-party neg-party + "not ~a: ~e" name val))) + inj))) (define-struct ∀∃/c (in out pred? name neg?) #:omit-define-syntaxes @@ -32,7 +34,7 @@ (build-contract-property #:name (λ (ctc) (∀∃/c-name ctc)) #:first-order (λ (ctc) (λ (x) #t)) ;; ??? - #:projection ∀∃-proj + #:late-neg-projection ∀∃-late-neg-proj #:stronger (λ (this that) (equal? this that)) #:generate (λ (ctc) (cond From 2e34599ce37068072a98d8b14a3065bfc31848b5 Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Sat, 19 Dec 2015 16:27:18 -0500 Subject: [PATCH 191/369] Support custom categories on root documentation page When custom categories are used in older versions, raco setup will report a warning, but the documentation will still appear under the Miscellaneous section. Thus, this is a backwards compatible implementation of the idea. --- pkgs/racket-doc/scribblings/raco/setup.scrbl | 12 +++++++--- .../scribblings/main/private/manuals.rkt | 22 +++++++++++++++---- pkgs/racket-index/setup/scribble.rkt | 3 ++- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/pkgs/racket-doc/scribblings/raco/setup.scrbl b/pkgs/racket-doc/scribblings/raco/setup.scrbl index 7a4340a9b0..c1f2f14a89 100644 --- a/pkgs/racket-doc/scribblings/raco/setup.scrbl +++ b/pkgs/racket-doc/scribblings/raco/setup.scrbl @@ -452,9 +452,13 @@ Optional @filepath{info.rkt} fields trigger additional actions by ] The @racket[_category] list specifies how to show the document in - the root table of contents. The list must start with a symbol, - usually one of the following categories, which are ordered as - below in the root documentation page: + the root table of contents. The list must start with a category, + which determines where the manual appears in the root + documentation page. A category is either a string or a symbol. If + it is a string, then the string is the category label on the root + page. If it is a symbol, then it a default category label is + used. The available symbols and the order of categories on the + root documentation page is as below: @itemize[ @@ -483,6 +487,8 @@ Optional @filepath{info.rkt} fields trigger additional actions by @item{@racket['interop] : Documentation for interoperability tools and libraries.} + @item{All string categories as ordered by @racket[string<=?].} + @item{@racket['library] : Documentation for libraries; this category is the default and used for unrecognized category symbols.} diff --git a/pkgs/racket-index/scribblings/main/private/manuals.rkt b/pkgs/racket-index/scribblings/main/private/manuals.rkt index 3e74a9d51f..981e8647d0 100644 --- a/pkgs/racket-index/scribblings/main/private/manuals.rkt +++ b/pkgs/racket-index/scribblings/main/private/manuals.rkt @@ -28,7 +28,7 @@ (truncate (/ (caar l) 10))))]) (if sep? (cons (mk-sep lbl) l) l))])))) -(define (get-docs all? tag) +(define (get-docs all? tag #:custom-secs [custom-secs (make-hash)]) (let* ([recs (find-relevant-directory-records (list tag) (if all? 'all-available 'no-user))] [infos (map get-info/full (map directory-record-path recs))] [docs (append-map @@ -55,7 +55,10 @@ ;; Category (let ([the-cat (if (pair? new-cat) (car new-cat) 'unknown)]) - (or (and (or (eq? the-cat 'omit) + (or (and (string? the-cat) + (let ([the-cat-sym (gensym)]) + (hash-ref! custom-secs the-cat the-cat-sym))) + (and (or (eq? the-cat 'omit) (eq? the-cat 'omit-start)) the-cat) (ormap (lambda (sec) @@ -90,7 +93,18 @@ (cdr l))) (define (make-start-page all?) - (let* ([docs (get-docs all? 'scribblings)] + (let* ([custom-secs (make-hash)] + [docs (get-docs all? 'scribblings + #:custom-secs custom-secs)] + [sections+custom + (append-map (λ (sec) + (if (eq? 'library (sec-cat sec)) + (append (for/list ([label (sort (hash-keys custom-secs) + string<=?)]) + (make-sec (hash-ref custom-secs label) label)) + (list sec)) + (list sec))) + sections)] [plain-line (lambda content (list (make-flow (list (make-paragraph content)))))] @@ -151,5 +165,5 @@ renderer part resolve-info))]) (string-ci (car ad) (car bd)))))))]))) - sections)))) + sections+custom)))) (make-delayed-block contents))) diff --git a/pkgs/racket-index/setup/scribble.rkt b/pkgs/racket-index/setup/scribble.rkt index e27f085c50..7026b98f1f 100644 --- a/pkgs/racket-index/setup/scribble.rkt +++ b/pkgs/racket-index/setup/scribble.rkt @@ -162,7 +162,8 @@ (or (not name) (collection-name-element? name)) (and (list? cat) (<= 1 (length cat) 2) - (symbol? (car cat)) + (or (symbol? (car cat)) + (string? (car cat))) (or (null? (cdr cat)) (real? (cadr cat)))) (and (exact-positive-integer? out-count)) From 260bfe9fec2e671dca4f583853b4210191d3fb2b Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Sat, 19 Dec 2015 21:56:55 -0500 Subject: [PATCH 192/369] A kinder, gentler, friendly starting documentation page --- pkgs/racket-index/scribblings/main/config.rkt | 4 ++- pkgs/racket-index/scribblings/main/info.rkt | 5 ++-- .../scribblings/main/private/root.rkt | 30 +++++++++++++++++++ pkgs/racket-index/scribblings/main/root.scrbl | 10 +++++++ .../scribblings/main/user/info.rkt | 3 +- .../scribblings/main/user/root.scrbl | 10 +++++++ .../user/{start.scrbl => user-start.scrbl} | 0 pkgs/racket-index/setup/scribble.rkt | 28 ++++++++++++----- 8 files changed, 79 insertions(+), 11 deletions(-) create mode 100644 pkgs/racket-index/scribblings/main/private/root.rkt create mode 100644 pkgs/racket-index/scribblings/main/root.scrbl create mode 100644 pkgs/racket-index/scribblings/main/user/root.scrbl rename pkgs/racket-index/scribblings/main/user/{start.scrbl => user-start.scrbl} (100%) diff --git a/pkgs/racket-index/scribblings/main/config.rkt b/pkgs/racket-index/scribblings/main/config.rkt index 267561ac60..43702c2aed 100644 --- a/pkgs/racket-index/scribblings/main/config.rkt +++ b/pkgs/racket-index/scribblings/main/config.rkt @@ -13,7 +13,9 @@ ;; user-specific pages using cookies). (Note: the subpath must match ;; where the corresponding document is generated, this is a hack.) (define links - `((start "Racket Documentation" user "index.html") + `((root "Racket Documentation" user "index.html") + --- + (start "Manual List" user "start/index.html") (search "Search Manuals" user "search/index.html") --- (license "License" plt "license/index.html") diff --git a/pkgs/racket-index/scribblings/main/info.rkt b/pkgs/racket-index/scribblings/main/info.rkt index e1fd50aec2..f538cb5f43 100644 --- a/pkgs/racket-index/scribblings/main/info.rkt +++ b/pkgs/racket-index/scribblings/main/info.rkt @@ -1,8 +1,9 @@ #lang info (define scribblings - '(("start.scrbl" - (main-doc-root depends-all-main no-depend-on) (omit)) + '(("root.scrbl" (main-doc-root no-depend-on) (omit)) + ("start.scrbl" + (depends-all-main no-depend-on) (omit)) ("search.scrbl" (depends-all-main no-depend-on) (omit) "search" 1 10) ("local-redirect.scrbl" (depends-all-main no-depend-on) (omit) "local-redirect" 1 10) ("license.scrbl" () (omit)) diff --git a/pkgs/racket-index/scribblings/main/private/root.rkt b/pkgs/racket-index/scribblings/main/private/root.rkt new file mode 100644 index 0000000000..36688205ee --- /dev/null +++ b/pkgs/racket-index/scribblings/main/private/root.rkt @@ -0,0 +1,30 @@ +#lang at-exp racket/base +(require scribble/core + scribble/decode + scribble/manual) + +(define h bold) + +(define (root global?) + (make-splice + @list{@h{Are you looking for a Racket tutorial?} + + If you are new to programming, try looking at @other-doc['(lib "scribblings/quick/quick.scrbl")]. Otherwise, you may be interested in @other-doc['(lib "scribblings/more/more.scrbl")]. + + @h{Are you looking for a quick cheat sheet on Racket?} + + This is not the page you are looking for. The @other-doc['(lib "racket-cheat/racket-cheat.scrbl")] is the page you are looking for. + + @h{Are you looking for the complete reference for Racket and its standard library?} + + @other-doc['(lib "scribblings/reference/reference.scrbl")] is an exhaustive reference and @other-doc['(lib "scribblings/guide/guide.scrbl")] is a more casual introduction through applications. + + @h{Are you looking for a list of the manuals of the libraries available on this system?} + + The @other-doc[(if global? '(lib "scribblings/main/start.scrbl") '(lib "scribblings/main/user/user-start.scrbl"))] contains categorized links to everything you have installed. + + @h{Can't find what you are looking for locally?} + + The online @link["http://pkg-build.racket-lang.org/doc/start/index.html"]{Manual List} contains categorized documentation all packages indexed on @link["http://pkgs.racket-lang.org"]{@tt{http://pkgs.racket-lang.org}}. If you can't find something you need on your system, try looking there.})) + +(provide root) diff --git a/pkgs/racket-index/scribblings/main/root.scrbl b/pkgs/racket-index/scribblings/main/root.scrbl new file mode 100644 index 0000000000..49fbfd7668 --- /dev/null +++ b/pkgs/racket-index/scribblings/main/root.scrbl @@ -0,0 +1,10 @@ +#lang scribble/doc +@(require scribble/manual + scribble/core + scribble/html-properties + "private/utils.rkt" + "private/root.rkt") + +@main-page['root #t #:show-root-info? #t] + +@root[#t] diff --git a/pkgs/racket-index/scribblings/main/user/info.rkt b/pkgs/racket-index/scribblings/main/user/info.rkt index 850a154d67..bad57a4809 100644 --- a/pkgs/racket-index/scribblings/main/user/info.rkt +++ b/pkgs/racket-index/scribblings/main/user/info.rkt @@ -1,7 +1,8 @@ #lang info (define scribblings - '(("start.scrbl" (user-doc-root depends-all no-depend-on) (omit)) + '(("root.scrbl" (user-doc-root no-depend-on) (omit)) + ("user-start.scrbl" (depends-all no-depend-on) (omit)) ("search.scrbl" (user-doc depends-all-user no-depend-on) (omit)) ("local-redirect.scrbl" (user-doc depends-all-user no-depend-on) (omit)) ("release.scrbl" (user-doc depends-all no-depend-on) (omit)))) diff --git a/pkgs/racket-index/scribblings/main/user/root.scrbl b/pkgs/racket-index/scribblings/main/user/root.scrbl new file mode 100644 index 0000000000..96f4f03cc8 --- /dev/null +++ b/pkgs/racket-index/scribblings/main/user/root.scrbl @@ -0,0 +1,10 @@ +#lang scribble/doc +@(require scribble/manual + scribble/core + scribble/html-properties + "../private/utils.rkt" + "../private/root.rkt") + +@main-page['root #f] + +@root[#f] diff --git a/pkgs/racket-index/scribblings/main/user/start.scrbl b/pkgs/racket-index/scribblings/main/user/user-start.scrbl similarity index 100% rename from pkgs/racket-index/scribblings/main/user/start.scrbl rename to pkgs/racket-index/scribblings/main/user/user-start.scrbl diff --git a/pkgs/racket-index/setup/scribble.rkt b/pkgs/racket-index/setup/scribble.rkt index 7026b98f1f..bfc842c030 100644 --- a/pkgs/racket-index/setup/scribble.rkt +++ b/pkgs/racket-index/setup/scribble.rkt @@ -1113,9 +1113,14 @@ with-record-error setup-printf workerid #f #f lock) doc))]) - (let ([v-in (load-sxref info-in-file)]) - (unless (equal? (car v-in) (list vers (doc-flags doc))) - (error "old info has wrong version or flags")) + (let ([v-in (load-sxref info-in-file)] + [should-be (list vers (doc-flags doc))]) + (unless (equal? (car v-in) should-be) + (error 'scribble + "old info(~e) has wrong version or flags: ~e should be ~e" + info-in-file + (car v-in) + should-be)) (when (and (or (not provides-time) (provides-time . < . info-out-time)) (can-build? only-dirs doc)) @@ -1169,9 +1174,15 @@ [out-vs (and info-out-time (with-handlers ([exn:fail? (lambda (exn) #f)]) (for/list ([info-out-file info-out-files]) - (let ([v (load-sxref info-out-file)]) - (unless (equal? (car v) (list vers (doc-flags doc))) - (error "old info has wrong version or flags")) + (let ([v (load-sxref info-out-file)] + [should-be (list vers (doc-flags doc))]) + (unless (equal? (car v) + should-be) + (error 'scribble + "old info(~e) has wrong version or flags: ~e should be ~e" + info-out-file + (car v) + should-be)) v))))] [scis (send renderer serialize-infos ri (add1 (doc-out-count doc)) v)] [defss (send renderer get-defineds ci (add1 (doc-out-count doc)) v)] @@ -1380,7 +1391,10 @@ (equal? in-version2 expected) (for/and ([out-version out-versions]) (equal? out-version expected))) - (error "old info has wrong version or flags")) + (error 'scribble "old info(~e) has wrong version or flags: ~e should all be ~e" + in-filename + (list* in-version in-version2 out-versions) + expected)) (match (with-my-namespace (lambda () (deserialize undef+searches))) From 3ed5eef44dc045d374e2b7fb040d26b18bcc5169 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 19 Dec 2015 17:04:08 -0600 Subject: [PATCH 193/369] put a little more info into the test case failure messages --- pkgs/racket-test/tests/racket/contract/test-util.rkt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test/tests/racket/contract/test-util.rkt b/pkgs/racket-test/tests/racket/contract/test-util.rkt index d802643daf..0d789dfa63 100644 --- a/pkgs/racket-test/tests/racket/contract/test-util.rkt +++ b/pkgs/racket-test/tests/racket/contract/test-util.rkt @@ -176,7 +176,9 @@ #:test-case-name ',name 'no-exn-raised eval - '(with-handlers ([exn:fail? exn-message]) + '(with-handlers ([exn:fail? (λ (x) (cons (exn-message x) + (continuation-mark-set->context + (exn-continuation-marks x))))]) ,expression 'no-exn-raised))) (let ([new-expression (rewrite-out expression)]) From efcbd12116e0763ca382163c21cb26916abf904c Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 19 Dec 2015 17:04:34 -0600 Subject: [PATCH 194/369] port class/c and friends to late-neg projections --- .../racket/contract/private/object.rkt | 6 +- .../collects/racket/private/class-c-new.rkt | 8 +- .../collects/racket/private/class-c-old.rkt | 128 ++++++++++-------- .../racket/private/class-internal.rkt | 12 +- 4 files changed, 83 insertions(+), 71 deletions(-) diff --git a/racket/collects/racket/contract/private/object.rkt b/racket/collects/racket/contract/private/object.rkt index 8ce589f349..f94fe74dcb 100644 --- a/racket/collects/racket/contract/private/object.rkt +++ b/racket/collects/racket/contract/private/object.rkt @@ -43,11 +43,11 @@ #:omit-define-syntaxes #:property prop:contract (build-contract-property - #:projection + #:late-neg-projection (λ (ctc) (λ (blame) - (λ (val) - (make-wrapper-object ctc val blame + (λ (val neg-party) + (make-wrapper-object ctc val blame neg-party (object-contract-methods ctc) (object-contract-method-ctcs ctc) (object-contract-fields ctc) (object-contract-field-ctcs ctc))))) #:name diff --git a/racket/collects/racket/private/class-c-new.rkt b/racket/collects/racket/private/class-c-new.rkt index 4835068886..abcb0e5549 100644 --- a/racket/collects/racket/private/class-c-new.rkt +++ b/racket/collects/racket/private/class-c-new.rkt @@ -160,7 +160,7 @@ (ext-class/c-contract-opaque? this) (ext-class/c-contract-name this))) (λ (neg-party) - (((class/c-proj ctc) (blame-add-missing-party blame neg-party)) cls))] + (((class/c-late-neg-proj ctc) blame) cls neg-party))] [else (build-neg-acceptor-proc this maybe-err blame cls #f '() (make-hasheq) (make-hasheq))])] @@ -176,7 +176,8 @@ (define mth->idx (class-method-ht cls)) (define mtd-vec (class-methods cls)) - (define internal-proj (internal-class/c-proj (ext-class/c-contract-internal-ctc this))) + (define internal-late-neg-proj + (internal-class/c-late-neg-proj (ext-class/c-contract-internal-ctc this))) ;; The #f may survive if the method is just-check-existence or ;; if the contract doesn't mention the method (and it isn't opaque) @@ -330,8 +331,7 @@ ;; on the class only when it is ;; time to instantiate it; not here (define class+one-property/adjusted - (chaperone-struct ((internal-proj (blame-add-missing-party blame neg-party)) - cls) + (chaperone-struct ((internal-late-neg-proj blame) cls neg-party) set-class-orig-cls! (λ (a b) b) impersonator-prop:wrapped-class-info the-info)) diff --git a/racket/collects/racket/private/class-c-old.rkt b/racket/collects/racket/private/class-c-old.rkt index cb2a2be7f7..ffced24345 100644 --- a/racket/collects/racket/private/class-c-old.rkt +++ b/racket/collects/racket/private/class-c-old.rkt @@ -10,7 +10,7 @@ "../contract/combinator.rkt" (only-in "../contract/private/arrow.rkt" making-a-method method-contract?)) -(provide make-class/c class/c-proj +(provide make-class/c class/c-late-neg-proj blame-add-method-context blame-add-field-context blame-add-init-context class/c ->m ->*m ->dm case->m object/c instanceof/c make-wrapper-object @@ -18,7 +18,7 @@ (for-syntax parse-class/c-specs) (struct-out internal-class/c) just-check-existence just-check-existence? - build-internal-class/c internal-class/c-proj + build-internal-class/c internal-class/c-late-neg-proj class/c-internal-name-clauses dynamic-object/c) @@ -143,31 +143,31 @@ #t) -(define (class/c-proj ctc) - (define ep (class/c-external-proj ctc)) - (define ip (internal-class/c-proj (class/c-internal ctc))) +(define (class/c-late-neg-proj ctc) + (define ep (class/c-external-late-neg-proj ctc)) + (define ip (internal-class/c-late-neg-proj (class/c-internal ctc))) (λ (blame) (define eb (ep blame)) (define ib (ip blame)) - (λ (val) - (ib (eb val))))) + (λ (val neg-party) + (ib (eb val neg-party) neg-party)))) -(define (class/c-external-proj ctc) +(define (class/c-external-late-neg-proj ctc) (define ctc-methods (class/c-methods ctc)) (λ (blame) (define public-method-projections (for/list ([name (in-list ctc-methods)] [c (in-list (class/c-method-contracts ctc))]) (and c - ((contract-projection c) (blame-add-method-context blame name))))) + ((contract-late-neg-projection c) (blame-add-method-context blame name))))) (define external-field-projections (for/list ([f (in-list (class/c-fields ctc))] [c (in-list (class/c-field-contracts ctc))]) (and c - (let ([p-pos ((contract-projection c) + (let ([p-pos ((contract-late-neg-projection c) (blame-add-field-context blame f #:swap? #f))] - [p-neg ((contract-projection c) + [p-neg ((contract-late-neg-projection c) (blame-add-field-context blame f #:swap? #t))]) (cons p-pos p-neg))))) @@ -176,12 +176,14 @@ (for/list ([init (in-list (class/c-inits ctc))] [ctc (in-list (class/c-init-contracts ctc))]) (if ctc - (list init ((contract-projection ctc) + (list init ((contract-late-neg-projection ctc) (blame-add-init-context blame init))) (list init #f)))) - (λ (cls) - (class/c-check-first-order ctc cls (λ args (apply raise-blame-error blame cls args))) + (λ (cls neg-party) + (class/c-check-first-order + ctc cls + (λ args (apply raise-blame-error blame #:missing-party neg-party cls args))) (let* ([name (class-name cls)] [never-wrapped? (eq? (class-orig-cls cls) cls)] ;; Only add a new slot if we're not projecting an already contracted class. @@ -296,7 +298,9 @@ ;; we're passing through a contract boundary, so the positive blame (aka ;; value server) is taking responsibility for any interface-contracted ;; methods) - (define info (replace-ictc-blame (cadr entry) #f (blame-positive blame))) + (define info (replace-ictc-blame + (cadr entry) #f + (blame-positive (blame-add-missing-party blame neg-party)))) (vector-set! methods i (concretize-ictc-method m (car entry) info))))) ;; Now apply projections (for ([m (in-list ctc-methods)] @@ -304,7 +308,7 @@ (when p (define i (hash-ref method-ht m)) (define mp (vector-ref methods i)) - (vector-set! methods i (make-method (p mp) m))))) + (vector-set! methods i (make-method (p mp neg-party) m))))) ;; Handle external field contracts (unless no-field-ctcs? @@ -314,7 +318,7 @@ (define fi (hash-ref field-ht f)) (define p-pos (car p-pr)) (define p-neg (cdr p-pr)) - (hash-set! field-ht f (field-info-extend-external fi p-pos p-neg))))) + (hash-set! field-ht f (field-info-extend-external fi p-pos p-neg neg-party))))) ;; Unlike the others, we always want to do this, even if there are no init contracts, ;; since we still need to handle either calling the previous class/c's init or @@ -351,7 +355,7 @@ (loop (cdr init-args) (cdr inits/c) (cons (cons (car init-arg) (if p - (p (cdr init-arg)) + (p (cdr init-arg) neg-party) (cdr init-arg))) handled-args)))] [else (loop (cdr init-args) @@ -376,7 +380,7 @@ (copy-seals cls c))))) -(define (internal-class/c-proj internal-ctc) +(define (internal-class/c-late-neg-proj internal-ctc) (define dynamic-features (append (internal-class/c-overrides internal-ctc) (internal-class/c-augments internal-ctc) @@ -393,26 +397,27 @@ (for/list ([name (in-list (internal-class/c-supers internal-ctc))] [c (in-list (internal-class/c-super-contracts internal-ctc))]) (and c - ((contract-projection c) (blame-add-method-context blame name))))) + ((contract-late-neg-projection c) (blame-add-method-context blame name))))) (define inner-projections (for/list ([name (in-list (internal-class/c-inners internal-ctc))] [c (in-list (internal-class/c-inner-contracts internal-ctc))]) (and c - ((contract-projection c) (blame-add-method-context bswap name))))) + ((contract-late-neg-projection c) (blame-add-method-context bswap name))))) (define internal-field-projections (for/list ([f (in-list (internal-class/c-inherit-fields internal-ctc))] [c (in-list (internal-class/c-inherit-field-contracts internal-ctc))]) (and c - (let ([p-pos ((contract-projection c) blame)] - [p-neg ((contract-projection c) bswap)]) + (let* ([blame-acceptor (contract-late-neg-projection c)] + [p-pos (blame-acceptor blame)] + [p-neg (blame-acceptor bswap)]) (cons p-pos p-neg))))) (define override-projections (for/list ([m (in-list (internal-class/c-overrides internal-ctc))] [c (in-list (internal-class/c-override-contracts internal-ctc))]) (and c - ((contract-projection c) (blame-add-method-context bswap m))))) + ((contract-late-neg-projection c) (blame-add-method-context bswap m))))) (define augment/augride-projections (for/list ([m (in-list (append (internal-class/c-augments internal-ctc) @@ -420,17 +425,19 @@ [c (in-list (append (internal-class/c-augment-contracts internal-ctc) (internal-class/c-augride-contracts internal-ctc)))]) (and c - ((contract-projection c) (blame-add-method-context blame m))))) + ((contract-late-neg-projection c) (blame-add-method-context blame m))))) (define inherit-projections (for/list ([m (in-list (internal-class/c-inherits internal-ctc))] [c (in-list (internal-class/c-inherit-contracts internal-ctc))]) (and c - ((contract-projection c) (blame-add-method-context blame m))))) - (λ (cls) + ((contract-late-neg-projection c) (blame-add-method-context blame m))))) + (λ (cls neg-party) (internal-class/c-check-first-order internal-ctc cls - (λ args (apply raise-blame-error blame cls args))) + (λ args (apply raise-blame-error + #:missing-party neg-party + blame cls args))) (let* ([name (class-name cls)] [never-wrapped? (eq? (class-orig-cls cls) cls)] @@ -563,7 +570,7 @@ (when p (define i (hash-ref method-ht m)) (define mp (vector-ref super-methods i)) - (vector-set! super-methods i (make-method (p mp) m))))) + (vector-set! super-methods i (make-method (p mp neg-party) m))))) ;; Add inner projections (unless (null? (internal-class/c-inners internal-ctc)) @@ -573,7 +580,7 @@ (when p (define i (hash-ref method-ht m)) (define old-proj (vector-ref inner-projs i)) - (vector-set! inner-projs i (λ (v) (old-proj (p v))))))) + (vector-set! inner-projs i (λ (v) (old-proj (p v neg-party))))))) ;; Handle external field contracts (unless no-field-ctcs? @@ -583,7 +590,7 @@ (define fi (hash-ref field-ht f)) (define p-pos (car p-pr)) (define p-neg (cdr p-pr)) - (hash-set! field-ht f (field-info-extend-internal fi p-pos p-neg))))) + (hash-set! field-ht f (field-info-extend-internal fi p-pos p-neg neg-party))))) ;; Now the trickiest of them all, internal dynamic dispatch. ;; First we update any dynamic indexes, as applicable. @@ -628,7 +635,7 @@ [old-idx (vector-ref old-idxs i)] [proj-vec (vector-ref dynamic-projs i)] [old-proj (vector-ref proj-vec old-idx)]) - (vector-set! proj-vec old-idx (λ (v) (old-proj (p v)))))))) + (vector-set! proj-vec old-idx (λ (v) (old-proj (p v neg-party)))))))) ;; For augment and augride contracts, we both update the projection ;; and go ahead and apply the projection to the last slot (which will @@ -645,9 +652,9 @@ [proj-vec (vector-ref dynamic-projs i)] [int-vec (vector-ref int-methods i)] [old-proj (vector-ref proj-vec old-idx)]) - (vector-set! proj-vec old-idx (λ (v) (p (old-proj v)))) + (vector-set! proj-vec old-idx (λ (v) (p (old-proj v) neg-party))) (vector-set! int-vec new-idx - (make-method (p (vector-ref int-vec new-idx)) m)))))) + (make-method (p (vector-ref int-vec new-idx) neg-party) m)))))) ;; Now (that things have been extended appropriately) we handle ;; inherits. @@ -659,7 +666,7 @@ [new-idx (vector-ref dynamic-idxs i)] [int-vec (vector-ref int-methods i)]) (vector-set! int-vec new-idx - (make-method (p (vector-ref int-vec new-idx)) m))))))) + (make-method (p (vector-ref int-vec new-idx) neg-party) m))))))) ;; Unlike the others, we always want to do this, even if there are no init contracts, ;; since we still need to handle either calling the previous class/c's init or @@ -943,7 +950,7 @@ #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property - #:projection class/c-proj + #:late-neg-projection class/c-late-neg-proj #:name build-class/c-name #:stronger class/c-stronger #:first-order @@ -1207,23 +1214,26 @@ #:key (compose symbol->string car))) (values (map car sorted) (map cdr sorted))) -(define (instanceof/c-proj ctc) +(define (instanceof/c-late-neg-proj ctc) (define proj (if (base-instanceof/c? ctc) - (contract-projection (base-instanceof/c-class-ctc ctc)) - (object/c-class-proj ctc))) + (contract-late-neg-projection (base-instanceof/c-class-ctc ctc)) + (object/c-late-neg-class-proj ctc))) (λ (blame) (define p (proj (blame-add-context blame #f))) - (λ (val) + (λ (val neg-party) (unless (object? val) - (raise-blame-error blame val '(expected: "an object" given: "~e") val)) + (raise-blame-error blame #:missing-party neg-party + val '(expected: "an object" given: "~e") val)) (when (base-object/c? ctc) (check-object-contract val (base-object/c-methods ctc) (base-object/c-fields ctc) - (λ args (apply raise-blame-error blame val args)))) + (λ args (apply raise-blame-error blame #:missing-party neg-party + val args)))) (define original-obj (if (has-original-object? val) (original-object val) val)) - (define new-cls (p (object-ref val))) + (define new-cls (p (object-ref val) neg-party)) + (define p-closed-over-neg-party (λ (v) (p v neg-party))) (cond [(impersonator-prop:has-wrapped-class-neg-party? new-cls) (define the-info (impersonator-prop:get-wrapped-class-info new-cls)) @@ -1266,7 +1276,7 @@ '()))) (define all-new-projs - (cons p + (cons p-closed-over-neg-party (if (has-impersonator-prop:instanceof/c-projs? val) (get-impersonator-prop:instanceof/c-projs val) '()))) @@ -1375,7 +1385,7 @@ #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property - #:projection instanceof/c-proj + #:late-neg-projection instanceof/c-late-neg-proj #:name (λ (ctc) (build-compound-type-name 'instanceof/c (base-instanceof/c-class-ctc ctc))) @@ -1411,15 +1421,15 @@ method-names (coerce-contracts 'dynamic-object/c method-contracts) field-names (coerce-contracts 'dynamic-object/c field-contracts))) -(define (object/c-class-proj ctc) +(define (object/c-late-neg-class-proj ctc) (define methods (base-object/c-methods ctc)) (define method-contracts (base-object/c-method-contracts ctc)) (define fields (base-object/c-fields ctc)) (define field-contracts (base-object/c-field-contracts ctc)) (λ (blame) - (λ (val) + (λ (val neg-party) (make-wrapper-class - val blame + val blame neg-party methods method-contracts fields field-contracts)))) (define (check-object-contract obj methods fields fail) @@ -1477,7 +1487,7 @@ #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property - #:projection instanceof/c-proj + #:late-neg-projection instanceof/c-late-neg-proj #:name (λ (ctc) (let* ([pair-ids-ctcs @@ -1518,18 +1528,18 @@ ;; make-wrapper-object: contract object blame ;; (listof symbol) (listof contract?) (listof symbol) (listof contract?) ;; -> wrapped object -(define (make-wrapper-object ctc obj blame methods method-contracts fields field-contracts) +(define (make-wrapper-object ctc obj blame neg-party methods method-contracts fields field-contracts) (check-object-contract obj methods fields (λ args (apply raise-blame-error blame obj args))) (let ([original-obj (if (has-original-object? obj) (original-object obj) obj)] [new-cls (make-wrapper-class (object-ref obj) ;; TODO: object-ref audit - blame + blame neg-party methods method-contracts fields field-contracts)]) (impersonate-struct obj object-ref (λ (o c) new-cls) ;; TODO: object-ref audit impersonator-prop:contracted ctc impersonator-prop:original-object original-obj))) -(define (make-wrapper-class cls blame methods method-contracts fields field-contracts) +(define (make-wrapper-class cls blame neg-party methods method-contracts fields field-contracts) (let* ([name (class-name cls)] [method-width (class-method-width cls)] [method-ht (class-method-ht cls)] @@ -1625,9 +1635,10 @@ [c (in-list method-contracts)]) (when c (let ([i (hash-ref method-ht m)] - [p ((contract-projection c) (blame-add-context blame (format "the ~a method in" m) - #:important m))]) - (vector-set! meths i (make-method (p (vector-ref meths i)) m)))))) + [p ((contract-late-neg-projection c) + (blame-add-context blame (format "the ~a method in" m) + #:important m))]) + (vector-set! meths i (make-method (p (vector-ref meths i) neg-party) m)))))) ;; Handle external field contracts (unless (null? fields) @@ -1635,8 +1646,9 @@ [c (in-list field-contracts)]) (unless (just-check-existence? c) (define fi (hash-ref field-ht f)) - (define p-pos ((contract-projection c) (blame-add-field-context blame f #:swap? #f))) - (define p-neg ((contract-projection c) (blame-add-field-context blame f #:swap? #t))) - (hash-set! field-ht f (field-info-extend-external fi p-pos p-neg))))) + (define prj (contract-late-neg-projection c)) + (define p-pos (prj (blame-add-field-context blame f #:swap? #f))) + (define p-neg (prj (blame-add-field-context blame f #:swap? #t))) + (hash-set! field-ht f (field-info-extend-external fi p-pos p-neg neg-party))))) (copy-seals cls c))) diff --git a/racket/collects/racket/private/class-internal.rkt b/racket/collects/racket/private/class-internal.rkt index 73fa1e50cd..0c53c99176 100644 --- a/racket/collects/racket/private/class-internal.rkt +++ b/racket/collects/racket/private/class-internal.rkt @@ -292,21 +292,21 @@ [field-set! (make-struct-field-mutator (class-field-set! cls) rpos)]) (vector field-ref field-set! field-ref field-set!))) -(define (field-info-extend-internal fi ppos pneg) +(define (field-info-extend-internal fi ppos pneg neg-party) (let* ([old-ref (unsafe-vector-ref fi 0)] [old-set! (unsafe-vector-ref fi 1)]) - (vector (λ (o) (ppos (old-ref o))) - (λ (o v) (old-set! o (pneg v))) + (vector (λ (o) (ppos (old-ref o) neg-party)) + (λ (o v) (old-set! o (pneg v neg-party))) (unsafe-vector-ref fi 2) (unsafe-vector-ref fi 3)))) -(define (field-info-extend-external fi ppos pneg) +(define (field-info-extend-external fi ppos pneg neg-party) (let* ([old-ref (unsafe-vector-ref fi 2)] [old-set! (unsafe-vector-ref fi 3)]) (vector (unsafe-vector-ref fi 0) (unsafe-vector-ref fi 1) - (λ (o) (ppos (old-ref o))) - (λ (o v) (old-set! o (pneg v)))))) + (λ (o) (ppos (old-ref o) neg-party)) + (λ (o v) (old-set! o (pneg v neg-party)))))) (define (field-info-internal-ref fi) (unsafe-vector-ref fi 0)) (define (field-info-internal-set! fi) (unsafe-vector-ref fi 1)) From 00c0ddb7f697761e5b2548ebb642b48cdee94d18 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 19 Dec 2015 17:23:13 -0600 Subject: [PATCH 195/369] port vector/c to late-neg projection (and throw away some redundant code) --- .../racket/contract/private/vector.rkt | 101 ++++++------------ 1 file changed, 31 insertions(+), 70 deletions(-) diff --git a/racket/collects/racket/contract/private/vector.rkt b/racket/collects/racket/contract/private/vector.rkt index 264775c635..9274738fe1 100644 --- a/racket/collects/racket/contract/private/vector.rkt +++ b/racket/collects/racket/contract/private/vector.rkt @@ -134,20 +134,7 @@ (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 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) ele-blame)]) - (for ([e (in-vector val)]) - (p e))) - val))))) + #:stronger vectorof-stronger)) (define (blame-add-element-of-context blame #:swap? [swap? #f]) (blame-add-context blame "an element of" #:swap? swap?)) @@ -210,37 +197,6 @@ (define-values (prop:neg-blame-party prop:neg-blame-party? prop:neg-blame-party-get) (make-impersonator-property 'prop:neg-blame-party)) -(define (vectorof-ho-projection vector-wrapper) - (λ (ctc) - (let ([elem-ctc (base-vectorof-elem ctc)] - [immutable (base-vectorof-immutable ctc)] - [check (check-vectorof ctc)]) - (λ (blame) - (let ([elem-pos-proj ((contract-projection elem-ctc) - (blame-add-element-of-context blame))] - [elem-neg-proj ((contract-projection elem-ctc) - (blame-add-element-of-context blame #:swap? #t))]) - (define checked-ref (λ (vec i val) - (with-contract-continuation-mark - blame (elem-pos-proj val)))) - (define checked-set (λ (vec i val) - (with-contract-continuation-mark - blame (elem-neg-proj val)))) - (define raise-blame (λ (val . args) - (apply raise-blame-error blame val args))) - (λ (val) - (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))) - (vector-wrapper - val - checked-ref - checked-set - impersonator-prop:contracted ctc - impersonator-prop:blame blame)))))))) - (define-struct (chaperone-vectorof base-vectorof) () #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract @@ -248,8 +204,7 @@ #:name vectorof-name #:first-order vectorof-first-order #:stronger vectorof-stronger - #:late-neg-projection (vectorof-late-neg-ho-projection chaperone-vector) - #:projection (vectorof-ho-projection chaperone-vector))) + #:late-neg-projection (vectorof-late-neg-ho-projection chaperone-vector))) (define-struct (impersonator-vectorof base-vectorof) () #:property prop:custom-write custom-write-property-proc @@ -258,8 +213,7 @@ #:name vectorof-name #:first-order vectorof-first-order #:stronger vectorof-stronger - #:late-neg-projection (vectorof-late-neg-ho-projection chaperone-vector) - #:projection (vectorof-ho-projection impersonate-vector))) + #:late-neg-projection (vectorof-late-neg-ho-projection chaperone-vector))) (define-syntax (wrap-vectorof stx) (syntax-case stx () @@ -312,26 +266,28 @@ (list '#:immutable immutable) null))))) -(define (check-vector/c ctc val blame) +(define (check-vector/c ctc val blame neg-party) (define elem-ctcs (base-vector/c-elems ctc)) (define immutable (base-vector/c-immutable ctc)) (unless (vector? val) - (raise-blame-error blame val '(expected: "a vector" given: "~e") val)) + (raise-blame-error blame #:missing-party neg-party val + '(expected: "a vector" given: "~e") val)) (cond [(eq? immutable #t) (unless (immutable? val) - (raise-blame-error blame val + (raise-blame-error blame #:missing-party neg-party val '(expected: "an immutable vector" given: "~e") val))] [(eq? immutable #f) (when (immutable? val) - (raise-blame-error blame val + (raise-blame-error blame #:missing-party neg-party val '(expected: "a mutable vector" given: "~e") val))] [else (void)]) (define elem-count (length elem-ctcs)) (unless (= (vector-length val) elem-count) - (raise-blame-error blame val '(expected: "a vector of ~a element~a" given: "~e") + (raise-blame-error blame #:missing-party neg-party val + '(expected: "a vector of ~a element~a" given: "~e") elem-count (if (= elem-count 1) "" "s") val))) @@ -396,21 +352,24 @@ #:name vector/c-name #:first-order vector/c-first-order #:stronger vector/c-stronger - #:projection + #:late-neg-projection (λ (ctc) (λ (blame) (define blame+ctxt (blame-add-element-of-context blame)) - (λ (val) + (define val+np-acceptors + (for/list ([c (in-list (base-vector/c-elems ctc))]) + ((contract-late-neg-projection c) blame+ctxt))) + (λ (val neg-party) (with-contract-continuation-mark - blame + (cons blame neg-party) (begin - (check-vector/c ctc val blame) + (check-vector/c ctc val blame neg-party) (for ([e (in-vector val)] - [c (in-list (base-vector/c-elems ctc))]) - (((contract-projection c) blame+ctxt) e)) + [p (in-list val+np-acceptors)]) + (p e neg-party)) val))))))) -(define (vector/c-ho-projection vector-wrapper) +(define (vector/c-ho-late-neg-projection vector-wrapper) (λ (ctc) (let ([elem-ctcs (base-vector/c-elems ctc)] [immutable (base-vector/c-immutable ctc)]) @@ -418,29 +377,31 @@ (let ([elem-pos-projs (for/vector #:length (length elem-ctcs) ([c (in-list elem-ctcs)] [i (in-naturals)]) - ((contract-projection c) + ((contract-late-neg-projection c) (blame-add-context blame (format "the ~a element of" (n->th i)))))] [elem-neg-projs (for/vector #:length (length elem-ctcs) ([c (in-list elem-ctcs)] [i (in-naturals)]) - ((contract-projection c) + ((contract-late-neg-projection c) (blame-add-context blame (format "the ~a element of" (n->th i)) #:swap? #t)))]) - (λ (val) - (check-vector/c ctc val blame) + (λ (val neg-party) + (check-vector/c ctc val blame neg-party) (if (and (immutable? val) (not (chaperone? val))) (apply vector-immutable (for/list ([e (in-vector val)] [i (in-naturals)]) - ((vector-ref elem-pos-projs i) e))) + ((vector-ref elem-pos-projs i) e neg-party))) (vector-wrapper val (λ (vec i val) (with-contract-continuation-mark - blame ((vector-ref elem-pos-projs i) val))) + (cons blame neg-party) + ((vector-ref elem-pos-projs i) val neg-party))) (λ (vec i val) (with-contract-continuation-mark - blame ((vector-ref elem-neg-projs i) val))) + (cons blame neg-party) + ((vector-ref elem-neg-projs i) val neg-party))) impersonator-prop:contracted ctc impersonator-prop:blame blame)))))))) @@ -451,7 +412,7 @@ #:name vector/c-name #:first-order vector/c-first-order #:stronger vector/c-stronger - #:projection (vector/c-ho-projection chaperone-vector))) + #:late-neg-projection (vector/c-ho-late-neg-projection chaperone-vector))) (define-struct (impersonator-vector/c base-vector/c) () #:property prop:custom-write custom-write-property-proc @@ -460,7 +421,7 @@ #:name vector/c-name #:first-order vector/c-first-order #:stronger vector/c-stronger - #:projection (vector/c-ho-projection impersonate-vector))) + #:late-neg-projection (vector/c-ho-late-neg-projection impersonate-vector))) (define-syntax (wrap-vector/c stx) (syntax-case stx () From a712117030aafa86b21f60038046e8754247cce1 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 19 Dec 2015 17:30:27 -0600 Subject: [PATCH 196/369] adjust syntax-parse's contract support to use the late-neg projections --- racket/collects/syntax/parse/experimental/provide.rkt | 4 ++-- racket/collects/syntax/parse/experimental/reflect.rkt | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/racket/collects/syntax/parse/experimental/provide.rkt b/racket/collects/syntax/parse/experimental/provide.rkt index 848a2fec7c..25829ec138 100644 --- a/racket/collects/syntax/parse/experimental/provide.rkt +++ b/racket/collects/syntax/parse/experimental/provide.rkt @@ -150,7 +150,7 @@ (if (flat-contract? ctc) (flat-named-contract name (flat-contract-predicate ctc)) (let* ([ctc-fo (contract-first-order ctc)] - [proj (contract-projection ctc)]) + [late-neg-proj (contract-late-neg-projection ctc)]) (make-contract #:name name - #:projection proj + #:late-neg-projection late-neg-proj #:first-order ctc-fo))))) diff --git a/racket/collects/syntax/parse/experimental/reflect.rkt b/racket/collects/syntax/parse/experimental/reflect.rkt index e0c6f76b53..6d16e87522 100644 --- a/racket/collects/syntax/parse/experimental/reflect.rkt +++ b/racket/collects/syntax/parse/experimental/reflect.rkt @@ -125,20 +125,20 @@ (#: any/c ...) #:rest list? (or/c reified-syntax-class? reified-splicing-syntax-class/c)) - #:projection + #:late-neg-projection (lambda (blame) (let ([check-reified - ((contract-projection + ((contract-late-neg-projection (or/c reified-syntax-class? reified-splicing-syntax-class?)) (blame-swap blame))]) - (lambda (f) + (lambda (f neg-party) (if (and (procedure? f) (procedure-arity-includes? f 1)) (make-keyword-procedure (lambda (kws kwargs r . args) - (keyword-apply f kws kwargs (check-reified r) args))) + (keyword-apply f kws kwargs (check-reified r neg-party) args))) (raise-blame-error - blame + blame #:missing-party neg-party f "expected a procedure of at least one argument, given ~e" f))))) From 3b1e535049f57516ee3284ff90a8f561ca5e0c6b Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 19 Dec 2015 17:34:10 -0600 Subject: [PATCH 197/369] port recursive-contract to late-neg --- .../collects/racket/contract/private/base.rkt | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/racket/collects/racket/contract/private/base.rkt b/racket/collects/racket/contract/private/base.rkt index 446bf538a6..3cdac2fe97 100644 --- a/racket/collects/racket/contract/private/base.rkt +++ b/racket/collects/racket/contract/private/base.rkt @@ -140,27 +140,27 @@ forced-ctc] [else current])) -(define (recursive-contract-projection ctc) +(define (recursive-contract-late-neg-projection ctc) (cond [(recursive-contract-list-contract? ctc) (λ (blame) (define r-ctc (force-recursive-contract ctc)) - (define f (contract-projection r-ctc)) + (define f (contract-late-neg-projection r-ctc)) (define blame-known (blame-add-context blame #f)) - (λ (val) + (λ (val neg-party) (unless (list? val) - (raise-blame-error blame-known + (raise-blame-error blame-known #:missing-party neg-party val '(expected: "list?" given: "~e") val)) - ((f blame-known) val)))] + ((f blame-known) val neg-party)))] [else (λ (blame) (define r-ctc (force-recursive-contract ctc)) - (define f (contract-projection r-ctc)) + (define f (contract-late-neg-projection r-ctc)) (define blame-known (blame-add-context blame #f)) - (λ (val) - ((f blame-known) val)))])) + (λ (val neg-party) + ((f blame-known) val neg-party)))])) (define (recursive-contract-stronger this that) (equal? this that)) @@ -187,7 +187,7 @@ (build-flat-contract-property #:name recursive-contract-name #:first-order recursive-contract-first-order - #:projection recursive-contract-projection + #:late-neg-projection recursive-contract-late-neg-projection #:stronger recursive-contract-stronger #:generate recursive-contract-generate #:list-contract? recursive-contract-list-contract?)) @@ -197,7 +197,7 @@ (build-chaperone-contract-property #:name recursive-contract-name #:first-order recursive-contract-first-order - #:projection recursive-contract-projection + #:late-neg-projection recursive-contract-late-neg-projection #:stronger recursive-contract-stronger #:generate recursive-contract-generate #:list-contract? recursive-contract-list-contract?)) @@ -207,7 +207,7 @@ (build-contract-property #:name recursive-contract-name #:first-order recursive-contract-first-order - #:projection recursive-contract-projection + #:late-neg-projection recursive-contract-late-neg-projection #:stronger recursive-contract-stronger #:generate recursive-contract-generate #:list-contract? recursive-contract-list-contract?)) From bd4b2439639f7229b2332945862ab9ae074f5651 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 19 Dec 2015 18:33:52 -0600 Subject: [PATCH 198/369] port xml contracts to late-neg --- racket/collects/xml/private/structures.rkt | 7 ++++--- racket/collects/xml/private/xexpr-core.rkt | 8 ++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/racket/collects/xml/private/structures.rkt b/racket/collects/xml/private/structures.rkt index c276c40d0b..9fc8985447 100644 --- a/racket/collects/xml/private/structures.rkt +++ b/racket/collects/xml/private/structures.rkt @@ -43,13 +43,14 @@ (define permissive/c (make-contract #:name 'permissive/c - #:projection + #:late-neg-projection (lambda (blame) - (lambda (v) + (lambda (v neg-party) (if (permissive-xexprs) v (raise-blame-error - blame v "not in permissive mode")))) + blame #:missing-party neg-party + v "not in permissive mode")))) #:first-order (lambda (v) #t))) diff --git a/racket/collects/xml/private/xexpr-core.rkt b/racket/collects/xml/private/xexpr-core.rkt index c2211213ed..66c883f1b2 100644 --- a/racket/collects/xml/private/xexpr-core.rkt +++ b/racket/collects/xml/private/xexpr-core.rkt @@ -42,14 +42,14 @@ (define xexpr/c (make-flat-contract - #:name 'xexpr? - #:projection + #:name 'xexpr/c + #:late-neg-projection (lambda (blame) - (lambda (val) + (lambda (val neg-party) (with-handlers ([exn:invalid-xexpr? (lambda (exn) (raise-blame-error - blame + blame #:missing-party neg-party val "Not an Xexpr. ~a\n\nContext:\n~a" (exn-message exn) From 783443f9d74b0d24b5d4c471255d705219adf8ce Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 19 Dec 2015 18:35:32 -0600 Subject: [PATCH 199/369] update the docs for ->i (should have been in commit 506c9be0cdf) --- .../scribblings/reference/contracts.scrbl | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index d821401051..b1ff992a28 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -1094,18 +1094,21 @@ symbols, and that return a symbol. } @defform*/subs[#:literals (any values) -[(->i (mandatory-dependent-dom ...) +[(->i maybe-chaperone + (mandatory-dependent-dom ...) dependent-rest pre-condition dependent-range post-condition) - (->i (mandatory-dependent-dom ...) + (->i maybe-chaperone + (mandatory-dependent-dom ...) (optional-dependent-dom ...) dependent-rest pre-condition dependent-range post-condition)] -([mandatory-dependent-dom id+ctc +([maybe-chaperone #:chaperone (code:line)] + [mandatory-dependent-dom id+ctc (code:line keyword id+ctc)] [optional-dependent-dom id+ctc (code:line keyword id+ctc)] @@ -1140,6 +1143,12 @@ combinator in that each argument and result is named and these names can be used in the subcontracts and in the pre-/post-condition clauses. In other words, @racket[->i] expresses dependencies among arguments and results. +The optional first keyword argument to @racket[->i] indicates if the result +contract will be a chaperone. If it is @racket[#:chaperone], all of the contract for the arguments +and results must be chaperone contracts and the result of @racket[->i] will be +a chaperone contract. If it is not present, then the result +contract will not be a chaperone contract. + The first sub-form of a @racket[->i] contract covers the mandatory and the second sub-form covers the optional arguments. Following that is an optional rest-args contract, and an optional pre-condition. The pre-condition is From 53fa16fc9c505cd9cffca7d3af273667c648cff5 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 19 Dec 2015 21:50:58 -0600 Subject: [PATCH 200/369] adjust hash/c to more completely follow the late-neg protocol --- racket/collects/racket/contract/private/hash.rkt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/racket/collects/racket/contract/private/hash.rkt b/racket/collects/racket/contract/private/hash.rkt index b5f9005c8e..1ea2d680a6 100644 --- a/racket/collects/racket/contract/private/hash.rkt +++ b/racket/collects/racket/contract/private/hash.rkt @@ -194,9 +194,9 @@ (define immutable (base-hash/c-immutable ctc)) (define flat? (flat-hash/c? ctc)) (λ (blame) - (define dom-proj ((contract-projection (base-hash/c-dom ctc)) + (define dom-proj ((contract-late-neg-projection (base-hash/c-dom ctc)) (blame-add-key-context blame #f))) - (define rng-proj ((contract-projection (base-hash/c-rng ctc)) + (define rng-proj ((contract-late-neg-projection (base-hash/c-rng ctc)) (blame-add-value-context blame #f))) (λ (val neg-party) (cond @@ -204,8 +204,8 @@ val] [else (for ([(k v) (in-hash val)]) - (dom-proj k) - (rng-proj v)) + (dom-proj k neg-party) + (rng-proj v neg-party)) val])))))) (define (ho-projection chaperone-or-impersonate-hash) From 15e24fce78743a3ec94bc48432e151341325de3c Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 19 Dec 2015 21:51:40 -0600 Subject: [PATCH 201/369] adjust set/c to follow the late-neg protocol and make it do some work earlier --- racket/collects/racket/set.rkt | 171 +++++++++++++++++++-------------- 1 file changed, 98 insertions(+), 73 deletions(-) diff --git a/racket/collects/racket/set.rkt b/racket/collects/racket/set.rkt index 2e2082d997..60c9eb9068 100644 --- a/racket/collects/racket/set.rkt +++ b/racket/collects/racket/set.rkt @@ -5,7 +5,8 @@ racket/private/set racket/private/set-types racket/generic - racket/private/for) + racket/private/for + (for-syntax racket/base)) (provide (all-from-out racket/private/set) (all-from-out racket/private/set-types) @@ -86,94 +87,112 @@ (lambda (x) (and (generic-set? x) (cmp? x) (kind? x)))) -(define (set-contract-check cmp kind b x) +(define (set-contract-check cmp kind b neg-party x) (unless (generic-set? x) - (raise-blame-error b x "expected a set")) + (raise-blame-error b #:missing-party neg-party x "expected a set")) (case cmp [(equal) (unless (set-equal? x) - (raise-blame-error b x "expected an equal?-based set"))] + (raise-blame-error b #:missing-party neg-party x "expected an equal?-based set"))] [(eqv) (unless (set-eqv? x) - (raise-blame-error b x "expected an eqv?-based set"))] + (raise-blame-error b #:missing-party neg-party x "expected an eqv?-based set"))] [(eq) (unless (set-eq? x) - (raise-blame-error b x "expected an eq?-based set"))]) + (raise-blame-error b #:missing-party neg-party x "expected an eq?-based set"))]) (case kind [(mutable-or-weak) (unless (or (set-mutable? x) (set-weak? x)) - (raise-blame-error b x "expected a mutable or weak set"))] + (raise-blame-error b #:missing-party neg-party x "expected a mutable or weak set"))] [(mutable) (unless (set-mutable? x) - (raise-blame-error b x "expected a mutable set"))] + (raise-blame-error b #:missing-party neg-party x "expected a mutable set"))] [(weak) (unless (set-weak? x) - (raise-blame-error b x "expected a weak set"))] + (raise-blame-error b #:missing-party neg-party x "expected a weak set"))] [(immutable) (unless (set? x) - (raise-blame-error b x "expected an immutable set"))])) + (raise-blame-error b #:missing-party neg-party x "expected an immutable set"))])) -(define (set-contract-projection mode) +(define (set-contract-late-neg-projection chaperone-ctc?) (lambda (ctc) (define elem/c (set-contract-elem/c ctc)) (define cmp (set-contract-cmp ctc)) (define kind (set-contract-kind ctc)) - (lambda (b) - (lambda (x) - (set-contract-check cmp kind b x) + (lambda (blame) + (define (method sym c) + (define name (contract-name c)) + (define str (format "method ~a with contract ~.s" sym name)) + (define b2 (blame-add-context blame str)) + ((contract-late-neg-projection c) b2)) + (define-syntax (redirect stx) + (syntax-case stx () + [(_ [id expr] ...) + (with-syntax ([(proj-id ...) (generate-temporaries #'(id ...))]) + #'(let ([proj-id (method 'id expr)] ...) + (λ (x neg-party) + (redirect-generics chaperone-ctc? + gen:set x [id (λ (x) (proj-id x neg-party))] ...))))])) + (define me (if chaperone-contract? + (make-chaperone-contract + #:name (set-contract-name ctc) + #:stronger set-contract-stronger + #:late-neg-projection + (λ (blame) (λ (val neg-party) (do-redirect val neg-party)))) + (make-contract + #:name (set-contract-name ctc) + #:stronger set-contract-stronger + #:late-neg-projection + (λ (blame) (λ (val neg-party) (do-redirect val neg-party)))))) + (define do-redirect + (redirect + [set-member? (-> generic-set? elem/c boolean?)] + [set-empty? (or/c (-> generic-set? boolean?) #f)] + [set-count (or/c (-> generic-set? exact-nonnegative-integer?) #f)] + [set=? (or/c (-> generic-set? me boolean?) #f)] + [subset? (or/c (-> generic-set? me boolean?) #f)] + [proper-subset? (or/c (-> generic-set? me boolean?) #f)] + [set-map (or/c (-> generic-set? (-> elem/c any/c) list?) #f)] + [set-for-each (or/c (-> generic-set? (-> elem/c any) void?) #f)] + [set-copy (or/c (-> generic-set? generic-set?) #f)] + [in-set (or/c (-> generic-set? sequence?) #f)] + [set->list (or/c (-> generic-set? (listof elem/c)) #f)] + [set->stream (or/c (-> generic-set? stream?) #f)] + [set-first (or/c (-> generic-set? elem/c) #f)] + [set-rest (or/c (-> generic-set? me) #f)] + [set-add (or/c (-> generic-set? elem/c me) #f)] + [set-remove (or/c (-> generic-set? elem/c me) #f)] + [set-clear (or/c (-> generic-set? me) #f)] + [set-copy-clear (or/c (-> generic-set? generic-set?) #f)] + [set-union + (or/c (->* [generic-set?] [] #:rest (listof me) me) #f)] + [set-intersect + (or/c (->* [generic-set?] [] #:rest (listof me) me) #f)] + [set-subtract + (or/c (->* [generic-set?] [] #:rest (listof me) me) #f)] + [set-symmetric-difference + (or/c (->* [generic-set?] [] #:rest (listof me) me) #f)] + [set-add! (or/c (-> generic-set? elem/c void?) #f)] + [set-remove! (or/c (-> generic-set? elem/c void?) #f)] + [set-clear! (or/c (-> generic-set? void?) #f)] + [set-union! + (or/c (->* [generic-set?] [] #:rest (listof me) void?) #f)] + [set-intersect! + (or/c (->* [generic-set?] [] #:rest (listof me) void?) #f)] + [set-subtract! + (or/c (->* [generic-set?] [] #:rest (listof me) void?) #f)] + [set-symmetric-difference! + (or/c (->* [generic-set?] [] #:rest (listof me) void?) #f)])) + (define proj + ((contract-projection elem/c) + (blame-add-context blame "an element of"))) + (lambda (x neg-party) + (set-contract-check cmp kind blame neg-party x) (cond [(list? x) - (define proj - ((contract-projection elem/c) - (blame-add-context b "an element of"))) (map proj x)] [else - (define (method sym c) - (lambda (x) - (define name (contract-name c)) - (define str (format "method ~a with contract ~.s" sym name)) - (define b2 (blame-add-context b str)) - (((contract-projection c) b2) x))) - (define-syntax-rule (redirect [id expr] ...) - (redirect-generics mode gen:set x [id (method 'id expr)] ...)) - (redirect - [set-member? (-> generic-set? elem/c boolean?)] - [set-empty? (or/c (-> generic-set? boolean?) #f)] - [set-count (or/c (-> generic-set? exact-nonnegative-integer?) #f)] - [set=? (or/c (-> generic-set? ctc boolean?) #f)] - [subset? (or/c (-> generic-set? ctc boolean?) #f)] - [proper-subset? (or/c (-> generic-set? ctc boolean?) #f)] - [set-map (or/c (-> generic-set? (-> elem/c any/c) list?) #f)] - [set-for-each (or/c (-> generic-set? (-> elem/c any) void?) #f)] - [set-copy (or/c (-> generic-set? generic-set?) #f)] - [in-set (or/c (-> generic-set? sequence?) #f)] - [set->list (or/c (-> generic-set? (listof elem/c)) #f)] - [set->stream (or/c (-> generic-set? stream?) #f)] - [set-first (or/c (-> generic-set? elem/c) #f)] - [set-rest (or/c (-> generic-set? ctc) #f)] - [set-add (or/c (-> generic-set? elem/c ctc) #f)] - [set-remove (or/c (-> generic-set? elem/c ctc) #f)] - [set-clear (or/c (-> generic-set? ctc) #f)] - [set-copy-clear (or/c (-> generic-set? generic-set?) #f)] - [set-union - (or/c (->* [generic-set?] [] #:rest (listof ctc) ctc) #f)] - [set-intersect - (or/c (->* [generic-set?] [] #:rest (listof ctc) ctc) #f)] - [set-subtract - (or/c (->* [generic-set?] [] #:rest (listof ctc) ctc) #f)] - [set-symmetric-difference - (or/c (->* [generic-set?] [] #:rest (listof ctc) ctc) #f)] - [set-add! (or/c (-> generic-set? elem/c void?) #f)] - [set-remove! (or/c (-> generic-set? elem/c void?) #f)] - [set-clear! (or/c (-> generic-set? void?) #f)] - [set-union! - (or/c (->* [generic-set?] [] #:rest (listof ctc) void?) #f)] - [set-intersect! - (or/c (->* [generic-set?] [] #:rest (listof ctc) void?) #f)] - [set-subtract! - (or/c (->* [generic-set?] [] #:rest (listof ctc) void?) #f)] - [set-symmetric-difference! - (or/c (->* [generic-set?] [] #:rest (listof ctc) void?) #f)])]))))) + (do-redirect x neg-party)]))))) (define (flat-set-contract-first-order ctc) (define set-passes? (set-contract-first-order ctc)) @@ -183,37 +202,43 @@ (for/and ([e (in-set x)]) (elem-passes? e))))) -(define (flat-set-contract-projection ctc) +(define (flat-set-contract-late-neg-projection ctc) (define elem/c (set-contract-elem/c ctc)) (define cmp (set-contract-cmp ctc)) (define kind (set-contract-kind ctc)) (lambda (b) - (lambda (x) - (set-contract-check cmp kind b x) - (define proj - ((contract-projection elem/c) - (blame-add-context b "an element of"))) + (define proj + ((contract-late-neg-projection elem/c) + (blame-add-context b "an element of"))) + (lambda (x neg-party) + (set-contract-check cmp kind b neg-party x) (for ([e (in-set x)]) - (proj e)) + (proj e neg-party)) x))) +(define (set-contract-stronger this that) + #f) + (struct flat-set-contract set-contract [] #:property prop:flat-contract (build-flat-contract-property #:name set-contract-name + #:stronger set-contract-stronger #:first-order flat-set-contract-first-order - #:projection flat-set-contract-projection)) + #:late-neg-projection flat-set-contract-late-neg-projection)) (struct chaperone-set-contract set-contract [] #:property prop:chaperone-contract (build-chaperone-contract-property #:name set-contract-name + #:stronger set-contract-stronger #:first-order set-contract-first-order - #:projection (set-contract-projection #t))) + #:late-neg-projection (set-contract-late-neg-projection #t))) (struct impersonator-set-contract set-contract [] #:property prop:contract (build-contract-property #:name set-contract-name + #:stronger set-contract-stronger #:first-order set-contract-first-order - #:projection (set-contract-projection #f))) + #:late-neg-projection (set-contract-late-neg-projection #f))) From ddaffc824887c25d39834fc0fadca3322664620b Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Sun, 20 Dec 2015 10:51:19 -0500 Subject: [PATCH 202/369] Revert "A kinder, gentler, friendly starting documentation page" This reverts commit 260bfe9fec2e671dca4f583853b4210191d3fb2b. --- pkgs/racket-index/scribblings/main/config.rkt | 4 +-- pkgs/racket-index/scribblings/main/info.rkt | 5 ++-- .../scribblings/main/private/root.rkt | 30 ------------------- pkgs/racket-index/scribblings/main/root.scrbl | 10 ------- .../scribblings/main/user/info.rkt | 3 +- .../scribblings/main/user/root.scrbl | 10 ------- .../user/{user-start.scrbl => start.scrbl} | 0 pkgs/racket-index/setup/scribble.rkt | 28 +++++------------ 8 files changed, 11 insertions(+), 79 deletions(-) delete mode 100644 pkgs/racket-index/scribblings/main/private/root.rkt delete mode 100644 pkgs/racket-index/scribblings/main/root.scrbl delete mode 100644 pkgs/racket-index/scribblings/main/user/root.scrbl rename pkgs/racket-index/scribblings/main/user/{user-start.scrbl => start.scrbl} (100%) diff --git a/pkgs/racket-index/scribblings/main/config.rkt b/pkgs/racket-index/scribblings/main/config.rkt index 43702c2aed..267561ac60 100644 --- a/pkgs/racket-index/scribblings/main/config.rkt +++ b/pkgs/racket-index/scribblings/main/config.rkt @@ -13,9 +13,7 @@ ;; user-specific pages using cookies). (Note: the subpath must match ;; where the corresponding document is generated, this is a hack.) (define links - `((root "Racket Documentation" user "index.html") - --- - (start "Manual List" user "start/index.html") + `((start "Racket Documentation" user "index.html") (search "Search Manuals" user "search/index.html") --- (license "License" plt "license/index.html") diff --git a/pkgs/racket-index/scribblings/main/info.rkt b/pkgs/racket-index/scribblings/main/info.rkt index f538cb5f43..e1fd50aec2 100644 --- a/pkgs/racket-index/scribblings/main/info.rkt +++ b/pkgs/racket-index/scribblings/main/info.rkt @@ -1,9 +1,8 @@ #lang info (define scribblings - '(("root.scrbl" (main-doc-root no-depend-on) (omit)) - ("start.scrbl" - (depends-all-main no-depend-on) (omit)) + '(("start.scrbl" + (main-doc-root depends-all-main no-depend-on) (omit)) ("search.scrbl" (depends-all-main no-depend-on) (omit) "search" 1 10) ("local-redirect.scrbl" (depends-all-main no-depend-on) (omit) "local-redirect" 1 10) ("license.scrbl" () (omit)) diff --git a/pkgs/racket-index/scribblings/main/private/root.rkt b/pkgs/racket-index/scribblings/main/private/root.rkt deleted file mode 100644 index 36688205ee..0000000000 --- a/pkgs/racket-index/scribblings/main/private/root.rkt +++ /dev/null @@ -1,30 +0,0 @@ -#lang at-exp racket/base -(require scribble/core - scribble/decode - scribble/manual) - -(define h bold) - -(define (root global?) - (make-splice - @list{@h{Are you looking for a Racket tutorial?} - - If you are new to programming, try looking at @other-doc['(lib "scribblings/quick/quick.scrbl")]. Otherwise, you may be interested in @other-doc['(lib "scribblings/more/more.scrbl")]. - - @h{Are you looking for a quick cheat sheet on Racket?} - - This is not the page you are looking for. The @other-doc['(lib "racket-cheat/racket-cheat.scrbl")] is the page you are looking for. - - @h{Are you looking for the complete reference for Racket and its standard library?} - - @other-doc['(lib "scribblings/reference/reference.scrbl")] is an exhaustive reference and @other-doc['(lib "scribblings/guide/guide.scrbl")] is a more casual introduction through applications. - - @h{Are you looking for a list of the manuals of the libraries available on this system?} - - The @other-doc[(if global? '(lib "scribblings/main/start.scrbl") '(lib "scribblings/main/user/user-start.scrbl"))] contains categorized links to everything you have installed. - - @h{Can't find what you are looking for locally?} - - The online @link["http://pkg-build.racket-lang.org/doc/start/index.html"]{Manual List} contains categorized documentation all packages indexed on @link["http://pkgs.racket-lang.org"]{@tt{http://pkgs.racket-lang.org}}. If you can't find something you need on your system, try looking there.})) - -(provide root) diff --git a/pkgs/racket-index/scribblings/main/root.scrbl b/pkgs/racket-index/scribblings/main/root.scrbl deleted file mode 100644 index 49fbfd7668..0000000000 --- a/pkgs/racket-index/scribblings/main/root.scrbl +++ /dev/null @@ -1,10 +0,0 @@ -#lang scribble/doc -@(require scribble/manual - scribble/core - scribble/html-properties - "private/utils.rkt" - "private/root.rkt") - -@main-page['root #t #:show-root-info? #t] - -@root[#t] diff --git a/pkgs/racket-index/scribblings/main/user/info.rkt b/pkgs/racket-index/scribblings/main/user/info.rkt index bad57a4809..850a154d67 100644 --- a/pkgs/racket-index/scribblings/main/user/info.rkt +++ b/pkgs/racket-index/scribblings/main/user/info.rkt @@ -1,8 +1,7 @@ #lang info (define scribblings - '(("root.scrbl" (user-doc-root no-depend-on) (omit)) - ("user-start.scrbl" (depends-all no-depend-on) (omit)) + '(("start.scrbl" (user-doc-root depends-all no-depend-on) (omit)) ("search.scrbl" (user-doc depends-all-user no-depend-on) (omit)) ("local-redirect.scrbl" (user-doc depends-all-user no-depend-on) (omit)) ("release.scrbl" (user-doc depends-all no-depend-on) (omit)))) diff --git a/pkgs/racket-index/scribblings/main/user/root.scrbl b/pkgs/racket-index/scribblings/main/user/root.scrbl deleted file mode 100644 index 96f4f03cc8..0000000000 --- a/pkgs/racket-index/scribblings/main/user/root.scrbl +++ /dev/null @@ -1,10 +0,0 @@ -#lang scribble/doc -@(require scribble/manual - scribble/core - scribble/html-properties - "../private/utils.rkt" - "../private/root.rkt") - -@main-page['root #f] - -@root[#f] diff --git a/pkgs/racket-index/scribblings/main/user/user-start.scrbl b/pkgs/racket-index/scribblings/main/user/start.scrbl similarity index 100% rename from pkgs/racket-index/scribblings/main/user/user-start.scrbl rename to pkgs/racket-index/scribblings/main/user/start.scrbl diff --git a/pkgs/racket-index/setup/scribble.rkt b/pkgs/racket-index/setup/scribble.rkt index bfc842c030..7026b98f1f 100644 --- a/pkgs/racket-index/setup/scribble.rkt +++ b/pkgs/racket-index/setup/scribble.rkt @@ -1113,14 +1113,9 @@ with-record-error setup-printf workerid #f #f lock) doc))]) - (let ([v-in (load-sxref info-in-file)] - [should-be (list vers (doc-flags doc))]) - (unless (equal? (car v-in) should-be) - (error 'scribble - "old info(~e) has wrong version or flags: ~e should be ~e" - info-in-file - (car v-in) - should-be)) + (let ([v-in (load-sxref info-in-file)]) + (unless (equal? (car v-in) (list vers (doc-flags doc))) + (error "old info has wrong version or flags")) (when (and (or (not provides-time) (provides-time . < . info-out-time)) (can-build? only-dirs doc)) @@ -1174,15 +1169,9 @@ [out-vs (and info-out-time (with-handlers ([exn:fail? (lambda (exn) #f)]) (for/list ([info-out-file info-out-files]) - (let ([v (load-sxref info-out-file)] - [should-be (list vers (doc-flags doc))]) - (unless (equal? (car v) - should-be) - (error 'scribble - "old info(~e) has wrong version or flags: ~e should be ~e" - info-out-file - (car v) - should-be)) + (let ([v (load-sxref info-out-file)]) + (unless (equal? (car v) (list vers (doc-flags doc))) + (error "old info has wrong version or flags")) v))))] [scis (send renderer serialize-infos ri (add1 (doc-out-count doc)) v)] [defss (send renderer get-defineds ci (add1 (doc-out-count doc)) v)] @@ -1391,10 +1380,7 @@ (equal? in-version2 expected) (for/and ([out-version out-versions]) (equal? out-version expected))) - (error 'scribble "old info(~e) has wrong version or flags: ~e should all be ~e" - in-filename - (list* in-version in-version2 out-versions) - expected)) + (error "old info has wrong version or flags")) (match (with-my-namespace (lambda () (deserialize undef+searches))) From 6957780cd5775f410623a1155e531a9584050060 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 19 Dec 2015 10:17:39 -0700 Subject: [PATCH 203/369] incremental GC: tune departure from incremental mode At the completion of an incremental major GC, if incremental mode wasn't requested recently, schedule an immediate major GC to reduce the heap back to its normal footprint. --- racket/src/racket/gc2/newgc.c | 30 ++++++++++++++++++++++-------- racket/src/racket/gc2/newgc.h | 2 +- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 25ce68c1dd..5821c24c63 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -3666,7 +3666,10 @@ void GC_request_incremental_mode(void) { NewGC *gc = GC_get_GC(); - gc->incremental_requested = 1; + /* The request will expire gradually, so that an extra major GC will + be triggered if incremental mode hasn't been requested recently + enough: */ + gc->incremental_requested = 8; } void GC_set_incremental_mode(int on) @@ -6091,7 +6094,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin uintptr_t old_gen0; uintptr_t old_mem_allocated; int next_gc_full; - int do_incremental = 0, check_inc_repair; + int do_incremental = 0, had_started_incremental, check_inc_repair; old_mem_use = gc->memory_in_use; /* includes gc->phantom_count */ old_gen0 = gen0_size_in_use(gc) + gc->gen0_phantom_count; @@ -6114,7 +6117,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin fraction of the actual use by live data: */ || (gc->memory_in_use > (FULL_COLLECTION_SIZE_RATIO * gc->last_full_mem_use - * (gc->started_incremental + * (gc->incremental_requested ? INCREMENTAL_EXTRA_SIZE_RATIO : 1))) /* Just in case, for a full GC every so often, unless @@ -6134,7 +6137,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin return; next_gc_full = (gc->gc_full - && !gc->started_incremental + && !gc->incremental_requested && !gc->full_needed_for_finalization); if (gc->full_needed_for_finalization && gc->gc_full) @@ -6178,7 +6181,8 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (do_incremental) gc->started_incremental = 1; - gc->incremental_requested = 0; + if (gc->incremental_requested) + --gc->incremental_requested; gc->mark_gen1 = (gc->gc_full || gc->started_incremental) && !gc->all_marked_incremental; gc->check_gen1 = gc->gc_full && !gc->all_marked_incremental; @@ -6384,12 +6388,14 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin else gc->since_last_full += 10; } + had_started_incremental = gc->started_incremental; if (gc->gc_full) { gc->last_full_mem_use = gc->memory_in_use; gc->started_incremental = 0; gc->all_marked_incremental = 0; gc->finished_incremental = 0; gc->inc_prop_count = 0; + gc->incremental_requested = 0; /* request expires completely after a full GC */ } /* inform the system (if it wants us to) that we're done with collection */ @@ -6401,7 +6407,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin is_master = (gc == MASTERGC); #endif park_for_inform_callback(gc); - gc->GC_collect_inform_callback(is_master, gc->gc_full, gc->started_incremental, + gc->GC_collect_inform_callback(is_master, gc->gc_full, had_started_incremental, /* original memory use: */ old_mem_use + old_gen0, /* new memory use; gen0_phantom_count can be non-zero due to @@ -6435,8 +6441,16 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (gc->gc_full) merge_run_queues(gc); - if (!gc->run_queue) - next_gc_full = 0; + if (!gc->run_queue) { + if (had_started_incremental) { + /* Keep next_gc_full, if it's set, because that means incremental + mode wasn't requested recently, even through we're wrapping up + an incremental GC; another major GC is likely to reclaim more + memory, reduce fragentation, and generally improve heap + health */ + } else + next_gc_full = 0; + } /* Run any queued finalizers, EXCEPT in the case where this collection was triggered during the execution of a finalizer. diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 973eeb3dec..76215402f4 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -228,7 +228,7 @@ typedef struct NewGC { unsigned char inc_gen1 :1; /* during incremental marking of old generation */ unsigned char fnl_gen1 :1; /* during incremental finalization of old generation */ unsigned char during_backpointer :1; - unsigned char incremental_requested :1; + unsigned char incremental_requested :4; /* counts down to track recentness of request */ unsigned char high_fragmentation :1; unsigned char unprotected_page :1; From 9711000b70c8bdfbceb577189a940a170dd9d331 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 19 Dec 2015 11:41:03 -0700 Subject: [PATCH 204/369] drop generation 1/2 except in incremental mode Originally, generation 1/2 was intended to delay major collections when the heap is especially large. It doesn't seem to be effective in that case, and it can slow down minor GCs, so continue to use it only in incremental mode (where it helps significantly with fragmentation). --- 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 5821c24c63..a3a9e4a706 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -252,10 +252,8 @@ MAYBE_UNUSED static void GCVERBOSEprintf(NewGC *gc, const char *fmt, ...) { #define HIGH_FRAGMENTATION_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)) \ - || (gc)->started_incremental) + gen-1/2 space: */ +#define AGE_GEN_0_TO_GEN_HALF(gc) ((gc)->started_incremental) /* Incremental mode */ static int always_collect_incremental_on_minor = 0; From 513849c1e3a207310d2b599c6cefcbf26f6780b0 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 19 Dec 2015 17:40:10 -0700 Subject: [PATCH 205/369] incremental GC: make accounting incremental for the root custodian --- .../scribblings/guide/performance.scrbl | 8 - racket/src/racket/gc2/mem_account.c | 148 ++++++++++++++---- racket/src/racket/gc2/newgc.c | 37 +++-- racket/src/racket/gc2/newgc.h | 3 +- 4 files changed, 147 insertions(+), 49 deletions(-) diff --git a/pkgs/racket-doc/scribblings/guide/performance.scrbl b/pkgs/racket-doc/scribblings/guide/performance.scrbl index d0a9970572..da33166505 100644 --- a/pkgs/racket-doc/scribblings/guide/performance.scrbl +++ b/pkgs/racket-doc/scribblings/guide/performance.scrbl @@ -626,11 +626,3 @@ runs @filepath{main.rkt} with garbage-collection logging to stderr collections are reported by @litchar{min} lines, increment-mode minor collection are reported with @litchar{mIn} lines, and major collections are reported with @litchar{MAJ} lines. - -Some Racket features can interfere with incremental mode. In -particular, memory accounting via @racket[custodian-limit-memory] -triggers an accounting pass during a major collection, and that pass -is not currently incremental. Note that DrRacket uses -@racket[custodian-limit-memory] to control the memory use of programs -run within DrRacket, so incremental mode is useful mainly outside of -DrRacket. (See also @secref["DrRacket-perf"].) diff --git a/racket/src/racket/gc2/mem_account.c b/racket/src/racket/gc2/mem_account.c index ea3e8ffbdf..4aadc9f450 100644 --- a/racket/src/racket/gc2/mem_account.c +++ b/racket/src/racket/gc2/mem_account.c @@ -385,7 +385,8 @@ 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, 0); + if (page->generation != AGE_GEN_HALF) + push_ptr(gc, ptr, 0); } } } @@ -470,15 +471,34 @@ static void btc_overmem_abort(NewGC *gc) "Info will be wrong.\n")); } -static void propagate_accounting_marks(NewGC *gc) +static void propagate_accounting_marks(NewGC *gc, int no_full) { void *p; + int fuel = (gc->gc_full + ? -1 + : (no_full + ? INCREMENTAL_COLLECT_FUEL_PER_100M / INCREMENTAL_MINOR_REQUEST_DIVISOR + : (INCREMENTAL_COLLECT_FUEL_PER_100M * AS_100M(gc->memory_in_use)) / 2)); - while(pop_ptr(gc, &p, 0) && !gc->kill_propagation_loop) { + while (pop_ptr(gc, &p, 0) && !gc->kill_propagation_loop) { + gc->traverse_count = 0; + /* GCDEBUG((DEBUGOUTF, "btc_account: popped off page %p:%p, ptr %p\n", page, page->addr, p)); */ propagate_marks_worker(gc, p, 0); + + if (fuel >= 0) { + fuel--; + fuel -= (gc->traverse_count >> 2); + if (gc->unprotected_page) { + gc->unprotected_page = 0; + fuel -= 100; + } + if (fuel <= 0) + break; + } } - if(gc->kill_propagation_loop) + + if (gc->kill_propagation_loop) reset_pointer_stack(gc); } @@ -499,14 +519,33 @@ inline static int BTC_get_redirect_tag(NewGC *gc, int tag) { return tag; } -static void BTC_do_accounting(NewGC *gc) +static void BTC_do_accounting(NewGC *gc, int no_full) { const int table_size = gc->owner_table_size; + int init_table_start, init_table_end, do_mark_threads; OTEntry **owner_table = gc->owner_table; + MarkSegment *orig_mark_stack; - gc->really_doing_accounting = gc->next_really_doing_accounting; - gc->next_really_doing_accounting = 0; + GC_ASSERT(gc->gc_full || gc->finished_incremental); + GC_ASSERT(gc->gc_full || !gc->accounted_incremental); + if (gc->gc_full) { + if (!gc->acct_mark_stack) + gc->really_doing_accounting = gc->next_really_doing_accounting; + gc->next_really_doing_accounting = 0; + } else { + if (gc->next_really_doing_accounting) + gc->really_doing_accounting = 1; + + GC_ASSERT(!gc->mark_gen1); + GC_ASSERT(!gc->inc_gen1); + GC_ASSERT(!gc->check_gen1); + + gc->mark_gen1 = 1; + gc->check_gen1 = 1; + gc->inc_gen1 = 1; + } + if(gc->really_doing_accounting) { Scheme_Custodian *cur = owner_table[current_owner(gc, NULL)]->originator, *last, *parent; Scheme_Custodian_Reference *box = cur->global_next; @@ -520,8 +559,31 @@ static void BTC_do_accounting(NewGC *gc) gc->unsafe_allocation_abort = btc_overmem_abort; gc->master_page_btc_mark_checked = 0; + if (!gc->gc_full || gc->acct_mark_stack) { + orig_mark_stack = gc->mark_stack; + if (gc->acct_mark_stack) { + gc->mark_stack = gc->acct_mark_stack; + init_table_start = 2; + do_mark_threads = 0; + } else { + gc->mark_stack = NULL; + mark_stack_initialize(gc); + init_table_start = 1; + do_mark_threads = 1; + } + if (gc->gc_full) + init_table_end = table_size; + else + init_table_end = 2; + } else { + orig_mark_stack = NULL; + init_table_start = 1; + init_table_end = table_size; + do_mark_threads = 1; + } + /* clear the memory use numbers out */ - for(i = 1; i < table_size; i++) + for(i = init_table_start; i < init_table_end; i++) if(owner_table[i]) { owner_table[i]->memory_use = 0; #ifdef MZ_USE_PLACES @@ -529,7 +591,7 @@ static void BTC_do_accounting(NewGC *gc) owner_table[i]->master_memory_use = 0; #endif } - + /* start with root: */ while (cur->parent && SCHEME_PTR1_VAL(cur->parent)) { cur = SCHEME_PTR1_VAL(cur->parent); @@ -541,6 +603,8 @@ static void BTC_do_accounting(NewGC *gc) while(cur) { int owner = custodian_to_owner_set(gc, cur); + GC_ASSERT(gc->gc_full || (owner == 1)); + GC_ASSERT(owner >= 0); GC_ASSERT(owner <= gc->owner_table_size); @@ -549,44 +613,70 @@ static void BTC_do_accounting(NewGC *gc) gc->current_mark_owner = owner; GCDEBUG((DEBUGOUTF,"MARKING THREADS OF OWNER %i (CUST %p)\n", owner, cur)); gc->kill_propagation_loop = 0; - mark_threads(gc, owner); - mark_cust_boxes(gc, cur); + if (do_mark_threads) { + mark_threads(gc, owner); + mark_cust_boxes(gc, cur); + } GCDEBUG((DEBUGOUTF, "Propagating accounting marks\n")); - propagate_accounting_marks(gc); + propagate_accounting_marks(gc, no_full); + + owner_table = gc->owner_table; + owner_table[owner]->memory_use = add_no_overflow(owner_table[owner]->memory_use, + gcBYTES_TO_WORDS(gc->acct_phantom_count)); + + if (!gc->gc_full) + break; last = cur; 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, - gcBYTES_TO_WORDS(gc->acct_phantom_count)); + do_mark_threads = 1; } release_master_btc_mark(gc); - /* walk backward folding totals int parent */ - cur = last; - while (cur) { - int owner = custodian_to_owner_set(gc, cur); + if (gc->gc_full) { + /* walk backward folding totals into parent */ + cur = last; + while (cur) { + int owner = custodian_to_owner_set(gc, cur); - box = cur->parent; parent = box ? SCHEME_PTR1_VAL(box) : NULL; - if (parent) { - int powner = custodian_to_owner_set(gc, parent); + box = cur->parent; parent = box ? SCHEME_PTR1_VAL(box) : NULL; + if (parent) { + int powner = custodian_to_owner_set(gc, parent); - owner_table = gc->owner_table; - owner_table[powner]->memory_use = add_no_overflow(owner_table[powner]->memory_use, - owner_table[owner]->memory_use); - owner_table[powner]->master_memory_use += owner_table[owner]->master_memory_use; + owner_table = gc->owner_table; + owner_table[powner]->memory_use = add_no_overflow(owner_table[powner]->memory_use, + owner_table[owner]->memory_use); + owner_table[powner]->master_memory_use += owner_table[owner]->master_memory_use; + } + + box = cur->global_prev; cur = box ? SCHEME_PTR1_VAL(box) : NULL; } - box = cur->global_prev; cur = box ? SCHEME_PTR1_VAL(box) : NULL; + if (orig_mark_stack) { + free_stack_pages_at(gc->mark_stack); + gc->acct_mark_stack = NULL; + gc->mark_stack = orig_mark_stack; + } + } else { + gc->acct_mark_stack = gc->mark_stack; + gc->mark_stack = orig_mark_stack; } gc->in_unsafe_allocation_mode = 0; gc->doing_memory_accounting = 0; - gc->old_btc_mark = gc->new_btc_mark; - gc->new_btc_mark = !gc->new_btc_mark; + if (gc->gc_full) { + gc->old_btc_mark = gc->new_btc_mark; + gc->new_btc_mark = !gc->new_btc_mark; + } + } + + if (!gc->gc_full) { + gc->mark_gen1 = 0; + gc->check_gen1 = 0; + gc->inc_gen1 = 0; } } diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index a3a9e4a706..1904abbafb 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -275,6 +275,8 @@ static int always_collect_incremental_on_minor = 0; seems to have been excessively conservative. */ #define FORCE_MAJOR_AFTER_COUNT 1000 +#define AS_100M(c) ((c / (1024 * 1024 * 100)) + 1) + /* 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 @@ -2120,7 +2122,8 @@ static int inc_marked_gen1(NewGC *gc, void *p) static int is_in_generation_half(NewGC *gc, const void *p) { mpage *page; - if (gc->gc_full) return 0; + if (gc->gc_full) /* generation half is never used for a full GC */ + return 0; page = pagemap_find_page_for_marking(gc, p, 1); if (!page) return 0; GC_ASSERT((page->generation == AGE_GEN_1) @@ -2784,7 +2787,7 @@ static void push_ptr(NewGC *gc, void *ptr, int inc_gen1) } #endif - GC_ASSERT(inc_gen1 || !gc->inc_gen1); + GC_ASSERT(inc_gen1 || !gc->inc_gen1 || gc->doing_memory_accounting); GC_ASSERT(!inc_gen1 || !gc->all_marked_incremental); push_ptr_at(ptr, inc_gen1 ? &gc->inc_mark_stack : &gc->mark_stack); @@ -3128,7 +3131,7 @@ static int designate_modified_gc(NewGC *gc, void *p) pages that are otherwise unmodified in the current pass: */ || gc->fnl_gen1 /* Memory accounting can also modify otherwise unadjusted - pages after incrementa mode: */ + pages after incremental mode: */ || (gc->doing_memory_accounting && gc->finished_incremental))) { check_incremental_unprotect(gc, page); gc->unprotected_page = 1; /* for using fuel */ @@ -3757,7 +3760,7 @@ static void page_newly_marked_on(NewGC *gc, mpage *page, int is_a_master_page, i /* If this page isn't already marked as old, it must be a medium page whose generation will be updated in the clean-up phase */ GC_ASSERT((page->generation >= AGE_GEN_1) || (page->size_class == SIZE_CLASS_MED_PAGE)); - GC_ASSERT(!gc->finished_incremental); + GC_ASSERT(!gc->finished_incremental || (!gc->accounted_incremental && gc->really_doing_accounting)); GC_ASSERT(!page->non_dead_as_mark); page->inc_marked_on = 1; page->inc_modified_next = gc->inc_modified_next; @@ -4201,7 +4204,7 @@ static inline void propagate_marks_worker(NewGC *gc, void *pp, int inc_gen1) start = PPTR(BIG_PAGE_TO_OBJECT(page)); alloc_type = page->page_type; end = PAGE_END_VSS(page); - GC_ASSERT(inc_gen1 || !page->mprotected); + GC_ASSERT(inc_gen1 || !page->mprotected || gc->doing_memory_accounting); } else { objhead *info; p = pp; @@ -5511,7 +5514,11 @@ static void incremental_repair_pages(NewGC *gc, int fuel) GC_ASSERT(page == gc->inc_repair_next); #endif - while (fuel && gc->inc_repair_next) { + /* If gc->finished_incremental already, then we must be in the + process of accounting incrementally */ + GC_ASSERT(!gc->finished_incremental || !gc->inc_repair_next || gc->really_doing_accounting); + + while ((fuel || gc->finished_incremental) && gc->inc_repair_next) { page = gc->inc_repair_next; gc->inc_repair_next = page->inc_modified_next; if (!gc->inc_repair_next) @@ -5960,8 +5967,6 @@ extern double scheme_get_inexact_milliseconds(void); # define TIME_ARGS /**/ #endif -#define AS_100M(c) ((c / (1024 * 1024 * 100)) + 1) - static int mark_and_finalize_all(NewGC *gc, int old_gen, int no_full TIME_FORMAL_ARGS) { int fuel = (old_gen @@ -6105,6 +6110,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin GC_ASSERT(!gc->all_marked_incremental || gc->started_incremental); GC_ASSERT(!gc->all_marked_incremental || mark_stack_is_empty(gc->inc_mark_stack)); GC_ASSERT(!gc->finished_incremental || (gc->all_marked_incremental && !gc->inc_repair_next)); + GC_ASSERT(!gc->accounted_incremental || gc->finished_incremental); /* determine if this should be a full collection or not */ gc->gc_full = (force_full @@ -6129,13 +6135,14 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin && !gc->started_incremental) /* In incremental mode, GC earlier if we've done everything that we can do incrementally. */ - || gc->finished_incremental); + || gc->accounted_incremental); if (gc->gc_full && no_full) return; next_gc_full = (gc->gc_full && !gc->incremental_requested + && !always_collect_incremental_on_minor && !gc->full_needed_for_finalization); if (gc->full_needed_for_finalization && gc->gc_full) @@ -6320,8 +6327,15 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin reset_nursery(gc); TIME_STEP("reset nursurey"); #ifdef NEWGC_BTC_ACCOUNT - if (gc->gc_full && postmaster_and_place_gc(gc)) - BTC_do_accounting(gc); + if ((gc->gc_full || (gc->finished_incremental && !gc->accounted_incremental)) + && postmaster_and_place_gc(gc)) { + BTC_do_accounting(gc, no_full); + if (!gc->gc_full && mark_stack_is_empty(gc->acct_mark_stack)) + gc->accounted_incremental = 1; + } +#else + if (gc->finished_incremental) + gc->accounted_incremental = 1; #endif TIME_STEP("accounted"); @@ -6392,6 +6406,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin gc->started_incremental = 0; gc->all_marked_incremental = 0; gc->finished_incremental = 0; + gc->accounted_incremental = 0; gc->inc_prop_count = 0; gc->incremental_requested = 0; /* request expires completely after a full GC */ } diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 76215402f4..1f589b1b4a 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -184,7 +184,7 @@ typedef struct NewGC { the end of the GC cycle: */ struct mpage *reprotect_next; - MarkSegment *mark_stack, *inc_mark_stack; + MarkSegment *mark_stack, *inc_mark_stack, *acct_mark_stack; /* Finalization */ Fnl *run_queue, *last_in_queue; @@ -214,6 +214,7 @@ typedef struct NewGC { unsigned char started_incremental :1; /* must stick with incremental until major GC */ unsigned char all_marked_incremental :1; /* finished all marking for an incremental GC */ unsigned char finished_incremental :1; /* finished marking and reparing an incremental GC */ + unsigned char accounted_incremental :1; /* memory accounting for an incremental GC */ unsigned char in_unsafe_allocation_mode :1; unsigned char full_needed_for_finalization :1; unsigned char no_further_modifications :1; From 3a99a19c5623d51035d58756ec08a4e5f12193d0 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 19 Dec 2015 11:35:41 -0700 Subject: [PATCH 206/369] reduce double major GCs When a major GC triggers finalization, another major GC is scheduled immediately on the grounds that the finalizer may release other values. That was important at once time, but the finalization and weak-reference implementation has improved to the point where the extra ful GC no longer seems necessary or useful. --- racket/src/racket/gc2/newgc.c | 32 +++++++++----------------------- racket/src/racket/gc2/newgc.h | 2 +- 2 files changed, 10 insertions(+), 24 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 1904abbafb..2f15929221 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -6086,11 +6086,6 @@ static int mark_and_finalize_all_incremental(NewGC *gc, int no_full TIME_FORMAL_ return more_to_do; } -/* Full GCs trigger finalization. Finalization releases data - in the old generation. So one more full GC is needed to - really clean up. The full_needed_for_finalization flag triggers - the second full GC. */ - static void garbage_collect(NewGC *gc, int force_full, int no_full, int switching_master, Log_Master_Info *lmi) { uintptr_t old_mem_use; @@ -6130,7 +6125,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin && !gc->started_incremental) /* Finalization triggers an extra full in case it releases a lot of additional memory: */ - || (gc->full_needed_for_finalization + || (gc->full_needed_again && !gc->incremental_requested && !gc->started_incremental) /* In incremental mode, GC earlier if we've done everything @@ -6140,13 +6135,16 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (gc->gc_full && no_full) return; + /* Switch from incremental to not, schedule another + full GC for next time: */ next_gc_full = (gc->gc_full + && gc->started_incremental && !gc->incremental_requested && !always_collect_incremental_on_minor - && !gc->full_needed_for_finalization); + && !gc->full_needed_again); - if (gc->full_needed_for_finalization && gc->gc_full) - gc->full_needed_for_finalization= 0; + if (gc->full_needed_again && gc->gc_full) + gc->full_needed_again = 0; #ifdef GC_DEBUG_PAGES if (gc->gc_full == 1) { @@ -6454,17 +6452,6 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (gc->gc_full) merge_run_queues(gc); - if (!gc->run_queue) { - if (had_started_incremental) { - /* Keep next_gc_full, if it's set, because that means incremental - mode wasn't requested recently, even through we're wrapping up - an incremental GC; another major GC is likely to reclaim more - memory, reduce fragentation, and generally improve heap - health */ - } else - next_gc_full = 0; - } - /* Run any queued finalizers, EXCEPT in the case where this collection was triggered during the execution of a finalizer. Without the exception, finalization effectively becomes @@ -6500,13 +6487,12 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin gc->park[1] = gc->park_fsave[1]; gc->park_fsave[0] = NULL; gc->park_fsave[1] = NULL; - } else - next_gc_full = 0; + } DUMP_HEAP(); CLOSE_DEBUG_FILE(); if (next_gc_full) - gc->full_needed_for_finalization = 1; + gc->full_needed_again = 1; #ifdef MZ_USE_PLACES if (postmaster_and_place_gc(gc)) { diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 1f589b1b4a..bca883d5ca 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -216,7 +216,7 @@ typedef struct NewGC { unsigned char finished_incremental :1; /* finished marking and reparing an incremental GC */ unsigned char accounted_incremental :1; /* memory accounting for an incremental GC */ unsigned char in_unsafe_allocation_mode :1; - unsigned char full_needed_for_finalization :1; + unsigned char full_needed_again :1; unsigned char no_further_modifications :1; unsigned char gc_full :1; /* a flag saying if this is a full/major collection */ unsigned char had_finished_incremental :1; /* when gc_full, indicates full GC after incremental finished */ From 0553f191d7fc6cdc7289fc0705a7c4a93f2d239e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 20 Dec 2015 08:04:55 -0700 Subject: [PATCH 207/369] adjust PLT_INCREMENTAL_GC so it can disable generational GC A value that starts "1", "y", or "Y" enabled incremental mode permanently (any value was allowed formerly), while a value that starts "0", "n", or "N" causes incremental-mode requests to be ignored. --- .../scribblings/guide/performance.scrbl | 5 +++-- .../scribblings/reference/memory.scrbl | 10 ++++++++-- racket/src/racket/cmdline.inc | 19 +++++++++++++++++-- racket/src/racket/gc2/gc2.h | 3 ++- racket/src/racket/gc2/newgc.c | 16 ++++++++++------ 5 files changed, 40 insertions(+), 13 deletions(-) diff --git a/pkgs/racket-doc/scribblings/guide/performance.scrbl b/pkgs/racket-doc/scribblings/guide/performance.scrbl index da33166505..e647146b2c 100644 --- a/pkgs/racket-doc/scribblings/guide/performance.scrbl +++ b/pkgs/racket-doc/scribblings/guide/performance.scrbl @@ -598,8 +598,9 @@ pause is as short as a minor collection's pause. Incremental mode tends to run more slowly overall, but it can provide much more consistent real-time behavior. -If the @envvar{PLT_INCREMENTAL_GC} environment variable is set when -Racket starts, incremental mode is permanently enabled. Since +If the @envvar{PLT_INCREMENTAL_GC} environment variable is set +to a value that starts with @litchar{1}, @litchar{y}, or @litchar{Y} +when Racket starts, incremental mode is permanently enabled. Since incremental mode is only useful for certain parts of some programs, however, and since the need for incremental mode is a property of a program rather than its environment, the preferred way to enable diff --git a/pkgs/racket-doc/scribblings/reference/memory.scrbl b/pkgs/racket-doc/scribblings/reference/memory.scrbl index b91df7dc20..4f5f76ef16 100644 --- a/pkgs/racket-doc/scribblings/reference/memory.scrbl +++ b/pkgs/racket-doc/scribblings/reference/memory.scrbl @@ -200,7 +200,8 @@ execution. Otherwise, @racket[#f] is returned.} Set the @as-index{@envvar{PLTDISABLEGC}} environment variable (to any value) before Racket starts to disable @tech{garbage collection}. Set -the @as-index{@envvar{PLT_INCREMENTAL_GC}} environment variable to +the @as-index{@envvar{PLT_INCREMENTAL_GC}} environment variable +to a value that starts with @litchar{1}, @litchar{y}, or @litchar{Y} to request incremental mode at all times, but calling @racket[(collect-garbage 'incremental)] in a program with a periodic task is generally a better mechanism for requesting incremental mode. @@ -302,6 +303,7 @@ collection mode, the text has the format @history[#:changed "6.3.0.7" @elem{Added @envvar{PLT_INCREMENTAL_GC}.}] + @defproc[(collect-garbage [request (or/c 'major 'minor 'incremental) 'major]) void?]{ Requests an immediate @tech{garbage collection} or requests a @@ -336,7 +338,11 @@ garbage-collection mode, depending on @racket[request]: 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.} + implies longer minor-collection times and higher memory use. + + If the @envvar{PLT_INCREMENTAL_GC} environment variable's value + starts with @litchar{0}, @litchar{n}, or @litchar{N} on + start-up, then incremental-mode requests are ignored.} ] diff --git a/racket/src/racket/cmdline.inc b/racket/src/racket/cmdline.inc index 4e0a5914ef..a532da07f5 100644 --- a/racket/src/racket/cmdline.inc +++ b/racket/src/racket/cmdline.inc @@ -1542,8 +1542,23 @@ static int run_from_cmd_line(int argc, char *_argv[], if (getenv("PLTDISABLEGC")) { scheme_enable_garbage_collection(0); } - if (getenv("PLT_INCREMENTAL_GC")) { - scheme_incremental_garbage_collection(1); + { + char *s; + s = getenv("PLT_INCREMENTAL_GC"); + if (s) { + if ((s[0] == '0') || (s[0] == 'n') || (s[0] == 'N')) + scheme_incremental_garbage_collection(0); + else if ((s[0] == '1') || (s[0] == 'y') || (s[0] == 'Y')) + scheme_incremental_garbage_collection(1); + else { + PRINTF("%s: unrecognized value for PLT_INCREMENTAL_GC;\n" + " a value that starts \"1\", \"y\", or \"Y\" permanently enables incremental mode,\n" + " and a value that starts \"0\", \"n\", or \"N\" disables incremental mode,\n" + " and the default enables incremental mode as requested via `collect-garbage'\n" + " unrecognized value: %s\n", + prog, s); + } + } } #endif diff --git a/racket/src/racket/gc2/gc2.h b/racket/src/racket/gc2/gc2.h index f5e6d68bdc..724c99af58 100644 --- a/racket/src/racket/gc2/gc2.h +++ b/racket/src/racket/gc2/gc2.h @@ -176,7 +176,8 @@ GC2_EXTERN void GC_request_incremental_mode(void); GC2_EXTERN void GC_set_incremental_mode(int on); /* - Sets whether incremental mode is the default. */ + Sets whether incremental mode is the default (1), always disabled (0), + or available on demand (-1). */ GC2_EXTERN void GC_free_all(void); /* diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 2f15929221..63653dcaa1 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -257,6 +257,7 @@ MAYBE_UNUSED static void GCVERBOSEprintf(NewGC *gc, const char *fmt, ...) { /* Incremental mode */ static int always_collect_incremental_on_minor = 0; +static int never_collect_incremental_on_minor = 0; #define INCREMENTAL_COLLECT_FUEL_PER_100M (4 * 1024) #define INCREMENTAL_REPAIR_FUEL_PER_100M 32 @@ -3665,17 +3666,20 @@ void GC_gcollect_minor(void) void GC_request_incremental_mode(void) { - NewGC *gc = GC_get_GC(); + if (!never_collect_incremental_on_minor) { + NewGC *gc = GC_get_GC(); - /* The request will expire gradually, so that an extra major GC will - be triggered if incremental mode hasn't been requested recently - enough: */ - gc->incremental_requested = 8; + /* The request will expire gradually, so that an extra major GC will + be triggered if incremental mode hasn't been requested recently + enough: */ + gc->incremental_requested = 8; + } } void GC_set_incremental_mode(int on) { - always_collect_incremental_on_minor = 1; + always_collect_incremental_on_minor = (on > 0); + never_collect_incremental_on_minor = !on; } void GC_enable_collection(int on) From efc8bcc2fd83aac985d3bb86ca65fcbfdcbaff79 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 20 Dec 2015 07:47:08 -0600 Subject: [PATCH 208/369] update contract in comment --- racket/collects/racket/private/class-c-old.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/racket/private/class-c-old.rkt b/racket/collects/racket/private/class-c-old.rkt index ffced24345..22e31cf62d 100644 --- a/racket/collects/racket/private/class-c-old.rkt +++ b/racket/collects/racket/private/class-c-old.rkt @@ -1525,7 +1525,7 @@ (let bindings (make-base-object/c methods method-ctcs fields field-ctcs)))))])) -;; make-wrapper-object: contract object blame +;; make-wrapper-object: contract object blame neg-party ;; (listof symbol) (listof contract?) (listof symbol) (listof contract?) ;; -> wrapped object (define (make-wrapper-object ctc obj blame neg-party methods method-contracts fields field-contracts) From 35b232073079f4969635af70596e41c4b12915d8 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 20 Dec 2015 21:16:39 -0600 Subject: [PATCH 209/369] add more warning logging for contracts that don't have late-neg projections --- .../collects/racket/contract/private/misc.rkt | 7 ---- .../collects/racket/contract/private/prop.rkt | 40 ++++++++++++++++--- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index 7cd5432198..890649d25d 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -2147,13 +2147,6 @@ (λ (x) (val+np-acceptor x #f)))) -(define (build-context) - (apply - string-append - (for/list ([i (in-list (continuation-mark-set->context - (current-continuation-marks)))]) - (format "\n ~s" i)))) - (define (flat-contract predicate) (coerce-flat-contract 'flat-contract predicate)) (define (flat-named-contract name pre-contract [generate #f]) (cond diff --git a/racket/collects/racket/contract/private/prop.rkt b/racket/collects/racket/contract/private/prop.rkt index 61c90bf389..ea451a3e3b 100644 --- a/racket/collects/racket/contract/private/prop.rkt +++ b/racket/collects/racket/contract/private/prop.rkt @@ -50,7 +50,9 @@ prop:arrow-contract prop:arrow-contract? prop:arrow-contract-get-info - (struct-out arrow-contract-info)) + (struct-out arrow-contract-info) + + build-context) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -253,6 +255,8 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(define-logger racket/contract) + (define ((build-property mk default-name proc-name first-order?) #:name [get-name #f] #:first-order [get-first-order #f] @@ -272,7 +276,14 @@ (string-append "expected either the #:get-projection, #:val-first-project, or #:late-neg-projection" " to not be #f, but all three were #f"))) - + + (unless get-late-neg-projection + (unless first-order? + (log-racket/contract-warning + "no late-neg-projection passed to ~s~a" + proc-name + (build-context)))) + (mk (or get-name (λ (c) default-name)) (or get-first-order get-any?) get-projection @@ -289,6 +300,13 @@ [else get-late-neg-projection]) list-contract?)) +(define (build-context) + (apply + string-append + (for/list ([i (in-list (continuation-mark-set->context + (current-continuation-marks)))]) + (format "\n ~s" i)))) + (define build-contract-property (procedure-rename (build-property make-contract-property 'anonymous-contract 'build-contract-property #f) @@ -410,7 +428,7 @@ #:exercise (lambda (c) (make-flat-contract-exercise c)) #:list-contract? (λ (c) (make-flat-contract-list-contract? c)))) -(define ((build-contract mk default-name) +(define ((build-contract mk default-name proc-name) #:name [name #f] #:first-order [first-order #f] #:projection [projection #f] @@ -421,6 +439,12 @@ #:exercise [exercise (λ (ctc) (λ (fuel) (values void '())))] #:list-contract? [list-contract? (λ (ctc) #f)]) + (unless late-neg-projection + (log-racket/contract-warning + "no late-neg-projection passed to ~s~a" + proc-name + (build-context))) + (mk (or name default-name) (or first-order any?) projection val-first-projection late-neg-projection @@ -447,17 +471,21 @@ (define make-contract (procedure-rename - (build-contract make-make-contract 'anonymous-contract) + (build-contract make-make-contract 'anonymous-contract 'make-contract) 'make-contract)) (define make-chaperone-contract (procedure-rename - (build-contract make-make-chaperone-contract 'anonymous-chaperone-contract) + (build-contract make-make-chaperone-contract + 'anonymous-chaperone-contract + 'make-chaperone-contract) 'make-chaperone-contract)) (define make-flat-contract (procedure-rename - (build-contract make-make-flat-contract 'anonymous-flat-contract) + (build-contract make-make-flat-contract + 'anonymous-flat-contract + 'make-flat-contract) 'make-flat-contract)) ;; property should be bound to a function that accepts the contract and From 7d02f4c7b1330707fea88de1d3c2a104e6ff13ae Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 20 Dec 2015 21:17:14 -0600 Subject: [PATCH 210/369] port parametric->/c to late-neg --- .../racket/contract/private/parametric.rkt | 51 ++++++++++--------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/racket/collects/racket/contract/private/parametric.rkt b/racket/collects/racket/contract/private/parametric.rkt index c789f44c76..a599a51276 100644 --- a/racket/collects/racket/contract/private/parametric.rkt +++ b/racket/collects/racket/contract/private/parametric.rkt @@ -54,38 +54,40 @@ (apply (polymorphic-contract-body that) instances))] [else #f])] [else #f])) - #:projection + #:late-neg-projection (lambda (c) (lambda (orig-blame) (define blame (blame-add-context orig-blame #f)) - (define (wrap p) + (define negative? (blame-swapped? blame)) + (define barrier/c (polymorphic-contract-barrier c)) + (define vars (polymorphic-contract-vars c)) + (define (wrap p neg-party) ;; values in polymorphic types come in from negative position, ;; relative to the poly/c contract - (define negative? (blame-swapped? blame)) - (define barrier/c (polymorphic-contract-barrier c)) (define instances - (for/list ([var (in-list (polymorphic-contract-vars c))]) + (for/list ([var (in-list vars)]) (barrier/c negative? var))) (define protector (apply (polymorphic-contract-body c) instances)) - (((contract-projection protector) blame) p)) + (((contract-late-neg-projection protector) blame) p neg-party)) - (lambda (p) + (lambda (p neg-party) (unless (procedure? p) - (raise-blame-error blame p '(expected "a procedure" given: "~e") p)) + (raise-blame-error blame #:missing-party neg-party + p '(expected "a procedure" given: "~e") p)) (make-keyword-procedure (lambda (keys vals . args) (keyword-apply (wrap p) keys vals args)) (case-lambda - [() ((wrap p))] - [(a) ((wrap p) a)] - [(a b) ((wrap p) a b)] - [(a b c) ((wrap p) a b c)] - [(a b c d) ((wrap p) a b c d)] - [(a b c d e) ((wrap p) a b c d e)] - [(a b c d e f) ((wrap p) a b c d e f)] - [(a b c d e f g) ((wrap p) a b c d e f g)] - [(a b c d e f g h) ((wrap p) a b c d e f g h)] - [args (apply (wrap p) args)]))))))) + [() ((wrap p neg-party))] + [(a) ((wrap p neg-party) a)] + [(a b) ((wrap p neg-party) a b)] + [(a b c) ((wrap p neg-party) a b c)] + [(a b c d) ((wrap p neg-party) a b c d)] + [(a b c d e) ((wrap p neg-party) a b c d e)] + [(a b c d e f) ((wrap p neg-party) a b c d e f)] + [(a b c d e f g) ((wrap p neg-party) a b c d e f g)] + [(a b c d e f g h) ((wrap p neg-party) a b c d e f g h)] + [args (apply (wrap p neg-party) args)]))))))) (define (opaque/c positive? name) (define-values [ type make pred getter setter ] @@ -100,17 +102,20 @@ #:name (lambda (c) (barrier-contract-name c)) #:first-order (λ (c) (barrier-contract-pred c)) #:stronger (λ (this that) (eq? this that)) - #:projection + #:late-neg-projection (lambda (c) (define mk (barrier-contract-make c)) + (define (mk-np x neg-party) (mk x)) (define pred (barrier-contract-pred c)) (define get (barrier-contract-get c)) + (define cp? (barrier-contract-positive? c)) (lambda (blame) - (if (equal? (blame-original? blame) (barrier-contract-positive? c)) - mk - (lambda (x) + (if (equal? (blame-original? blame) cp?) + mk-np + (lambda (x neg-party) (if (pred x) (get x) - (raise-blame-error blame x '(expected: "~a" given: "~e") + (raise-blame-error blame #:missing-party neg-party + x '(expected: "~a" given: "~e") (barrier-contract-name c) x)))))))) From 8776ab768652533abf7c0a0382c9c375d082d724 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 21 Dec 2015 07:36:56 -0600 Subject: [PATCH 211/369] remove implementations of non-late-neg projections from bunch of combinators --- .../collects/racket/contract/private/box.rkt | 33 +-- .../collects/racket/contract/private/misc.rkt | 237 +----------------- .../collects/racket/contract/private/orc.rkt | 88 ------- 3 files changed, 5 insertions(+), 353 deletions(-) diff --git a/racket/collects/racket/contract/private/box.rkt b/racket/collects/racket/contract/private/box.rkt index 5f2c1a2e2b..d0461ca79c 100644 --- a/racket/collects/racket/contract/private/box.rkt +++ b/racket/collects/racket/contract/private/box.rkt @@ -128,32 +128,7 @@ [fail-proc (fail-proc neg-party)] [else (late-neg-proj (unbox val) neg-party) - val])))) - #:projection - (λ (ctc) - (λ (blame) - (λ (val) - (check-box/c ctc val blame) - (((contract-projection (base-box/c-content-w ctc)) blame) (unbox val)) - val))))) - -(define (ho-projection box-wrapper) - (λ (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-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-r-proj (unbox val))) - (box-wrapper val - (λ (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)))))))) + val])))))) (define (ho-late-neg-projection chaperone/impersonate-box) (λ (ctc) @@ -188,8 +163,7 @@ #:name box/c-name #:first-order box/c-first-order #:stronger box/c-stronger - #:late-neg-projection (ho-late-neg-projection chaperone-box) - #:projection (ho-projection chaperone-box))) + #:late-neg-projection (ho-late-neg-projection chaperone-box))) (define-struct (impersonator-box/c base-box/c) () #:property prop:custom-write custom-write-property-proc @@ -198,8 +172,7 @@ #:name box/c-name #:first-order box/c-first-order #:stronger box/c-stronger - #:late-neg-projection (ho-late-neg-projection impersonate-box) - #:projection (ho-projection impersonate-box))) + #:late-neg-projection (ho-late-neg-projection impersonate-box))) (define-syntax (wrap-box/c stx) (syntax-case stx () diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index 890649d25d..edbe1673fc 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -110,17 +110,6 @@ (let ([tests (map contract-first-order (base-and/c-ctcs ctc))]) (λ (x) (for/and ([test (in-list tests)]) (test x))))) -(define (and-proj ctc) - (let ([mk-pos-projs (map contract-projection (base-and/c-ctcs ctc))]) - (lambda (blame) - (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)))))) - (for/fold ([proj (car projs)]) - ([p (in-list (cdr projs))]) - (λ (v) (p (proj v))))))) - (define (late-neg-and-proj ctc) (define mk-pos-projs (map get/build-late-neg-projection (base-and/c-ctcs ctc))) (λ (blame) @@ -137,22 +126,6 @@ (loop (cdr projs) ((car projs) val neg-party))]))))) -(define (first-order-and-proj ctc) - (λ (blame) - (λ (val) - (let loop ([predicates (first-order-and/c-predicates ctc)] - [ctcs (base-and/c-ctcs ctc)]) - (cond - [(null? predicates) val] - [else - (cond - [((car predicates) val) - (loop (cdr predicates) (cdr ctcs))] - [else - (define ctc1-proj (contract-projection (car ctcs))) - (define new-blame (blame-add-context blame "an and/c case of")) - ((ctc1-proj new-blame) val)])]))))) - (define (first-order-late-neg-and-proj ctc) (define predicates (first-order-and/c-predicates ctc)) (define blame-accepters (map get/build-late-neg-projection (base-and/c-ctcs ctc))) @@ -270,7 +243,6 @@ #:property prop:custom-write custom-write-property-proc #:property prop:flat-contract (build-flat-contract-property - #:projection first-order-and-proj #:late-neg-projection first-order-late-neg-and-proj #:name and-name #:first-order and-first-order @@ -280,7 +252,6 @@ #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract (build-chaperone-contract-property - #:projection and-proj #:late-neg-projection late-neg-and-proj #:name and-name #:first-order and-first-order @@ -290,7 +261,6 @@ #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property - #:projection and-proj #:late-neg-projection late-neg-and-proj #:name and-name #:first-order and-first-order @@ -674,47 +644,6 @@ [else (elem-fo? v)])))])) -(define (listof-projection ctc) - (define elem-proj (contract-projection (listof-ctc-elem-c ctc))) - (define pred? (if (pe-listof-ctc? ctc) - list? - non-empty-list?)) - (λ (blame) - (define elem-proj+blame (elem-proj (blame-add-listof-context blame))) - (cond - [(flat-listof-ctc? ctc) - (if (im-listof-ctc? ctc) - (λ (val) - (let loop ([val val]) - (cond - [(pair? val) - (elem-proj+blame (car val)) - (loop (cdr val))] - [else - (elem-proj+blame val)])) - val) - (λ (val) - (if (pred? val) - (begin - (for ([x (in-list val)]) - (elem-proj+blame x)) - val) - (raise-listof-blame-error blame val (pe-listof-ctc? ctc) #f))))] - [else - (if (im-listof-ctc? ctc) - (λ (val) - (let loop ([val val]) - (cond - [(pair? val) - (cons (elem-proj+blame (car val)) - (loop (cdr val)))] - [else (elem-proj+blame val)]))) - (λ (val) - (if (pred? val) - (for/list ([x (in-list val)]) - (elem-proj+blame x)) - (raise-listof-blame-error blame val (pe-listof-ctc? ctc) #f))))]))) - (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) @@ -762,7 +691,6 @@ (build-flat-contract-property #:name list-name #:first-order list-fo-check - #:projection listof-projection #:late-neg-projection listof-late-neg-projection #:generate listof-generate #:exercise listof-exercise @@ -772,7 +700,6 @@ (build-chaperone-contract-property #:name list-name #:first-order list-fo-check - #:projection listof-projection #:late-neg-projection listof-late-neg-projection #:generate listof-generate #:exercise listof-exercise @@ -782,7 +709,6 @@ (build-contract-property #:name list-name #:first-order list-fo-check - #:projection listof-projection #:late-neg-projection listof-late-neg-projection #:generate listof-generate #:exercise listof-exercise @@ -877,7 +803,6 @@ (define (blame-add-car-context blame) (blame-add-context blame "the car of")) (define (blame-add-cdr-context blame) (blame-add-context blame "the cdr of")) - (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)) @@ -893,19 +818,6 @@ (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)) - (define ctc-cdr (the-cons/c-tl-ctc ctc)) - (define car-proj (contract-projection ctc-car)) - (define cdr-proj (contract-projection ctc-cdr)) - (λ (blame) - (let ([car-p (car-proj (blame-add-car-context blame))] - [cdr-p (cdr-proj (blame-add-cdr-context blame))]) - (λ (v) - (unless (pair? v) - (raise-not-cons-blame-error blame v)) - (combine v (car-p (car v)) (cdr-p (cdr v))))))) - (define (cons/c-first-order ctc) (define ctc-car (the-cons/c-hd-ctc ctc)) (define ctc-cdr (the-cons/c-tl-ctc ctc)) @@ -962,7 +874,6 @@ #:property prop:flat-contract (build-flat-contract-property #: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 #:stronger cons/c-stronger? @@ -973,7 +884,6 @@ #:property prop:chaperone-contract (build-chaperone-contract-property #: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 #:stronger cons/c-stronger? @@ -984,7 +894,6 @@ #:property prop:contract (build-contract-property #: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 #:stronger cons/c-stronger? @@ -1267,38 +1176,8 @@ val '(expected "a list" given: "~e") val)])))) - #:projection - (lambda (c) - (lambda (blame) - (lambda (x) - (unless (list? x) - (raise-blame-error blame x '(expected "a list" given: "~e") x)) - (let* ([args (generic-list/c-args c)] - [expected (length args)] - [actual (length x)]) - (expected-a-list-of-len x actual expected blame) - (for ([arg/c (in-list args)] [v (in-list x)] [i (in-naturals 1)]) - (((contract-projection arg/c) - (add-list-context blame i)) - v)) - x)))) #:list-contract? (λ (c) #t))) -(define (list/c-chaperone/other-projection c) - (define args (map contract-projection (generic-list/c-args c))) - (define expected (length args)) - (λ (blame) - (define projs (for/list ([arg/c (in-list args)] - [i (in-naturals 1)]) - (arg/c (add-list-context blame i)))) - (λ (x) - (unless (list? x) (expected-a-list x blame)) - (define actual (length x)) - (expected-a-list-of-len x actual expected blame #:missing-party #f) - (for/list ([item (in-list x)] - [proj (in-list projs)]) - (proj item))))) - (define (expected-a-list x blame #:missing-party [missing-party #f]) (raise-blame-error blame #:missing-party missing-party x '(expected: "a list" given: "~e") x)) @@ -1363,7 +1242,6 @@ #:generate list/c-generate #:exercise list/c-exercise #:stronger list/c-stronger - #:projection list/c-chaperone/other-projection #:late-neg-projection list/c-chaperone/other-late-neg-projection #:list-contract? (λ (c) #t))) @@ -1376,7 +1254,6 @@ #:generate list/c-generate #:exercise list/c-exercise #:stronger list/c-stronger - #:projection list/c-chaperone/other-projection #:late-neg-projection list/c-chaperone/other-late-neg-projection #:list-contract? (λ (c) #t))) @@ -1477,25 +1354,6 @@ #:omit-define-syntaxes #:property prop:contract (build-contract-property - #:projection - (λ (ctc) - (let* ([in-proc (contract-projection (parameter/c-in ctc))] - [out-proc (contract-projection (parameter/c-out ctc))]) - (λ (blame) - (define blame/c (blame-add-context blame "the parameter of")) - (define (add-profiling f) - (λ (x) (with-contract-continuation-mark (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) - (make-derived-parameter - val - partial-neg-contract - partial-pos-contract)] - [else - (raise-blame-error blame val '(expected "a parameter"))]))))) #:late-neg-projection (λ (ctc) (define in-proc (get/build-late-neg-projection (parameter/c-in ctc))) @@ -1563,12 +1421,9 @@ n)) (make-procedure-arity-includes/c n)) -(define (get-any-projection c) any-projection) -(define (any-projection b) any-function) -(define (any-function x) x) - (define (get-any? c) any?) (define (any? x) #t) +(define any/c-blame->neg-party-fn (λ (blame) any/c-neg-party-fn)) (define any/c-neg-party-fn (λ (val neg-party) val)) (define (random-any/c env fuel) @@ -1608,8 +1463,7 @@ #:omit-define-syntaxes #:property prop:flat-contract (build-flat-contract-property - #:projection get-any-projection - #:late-neg-projection (λ (ctc) (λ (blame) any/c-neg-party-fn)) + #:late-neg-projection (λ (ctc) any/c-blame->neg-party-fn) #:stronger (λ (this that) (any/c? that)) #:name (λ (ctc) 'any/c) #:generate (λ (ctc) @@ -1623,16 +1477,6 @@ (define-syntax (any stx) (raise-syntax-error 'any "use of 'any' outside the range of an arrow contract" stx)) -(define (none-curried-proj ctc) - (λ (blame) - (λ (val) - (raise-blame-error - blame - val - '("~s accepts no values" given: "~e") - (none/c-name ctc) - val)))) - (define (((none-curried-late-neg-proj ctc) blame) val neg-party) (raise-blame-error blame #:missing-party neg-party @@ -1646,7 +1490,6 @@ #:omit-define-syntaxes #:property prop:flat-contract (build-flat-contract-property - #:projection none-curried-proj #:late-neg-projection none-curried-late-neg-proj #:stronger (λ (this that) #t) #:name (λ (ctc) (none/c-name ctc)) @@ -1680,42 +1523,6 @@ (list '#:call/cc) (base-prompt-tag/c-call/ccs ctc)))) ;; build a projection for prompt tags -(define ((prompt-tag/c-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 contract-projection (base-prompt-tag/c-ctcs ctc))) - (define call/cc-projs - (map contract-projection (base-prompt-tag/c-call/ccs ctc))) - (λ (blame) - (define (make-proj projs swap?) - (λ vs - (define vs2 (for/list ([proj projs] [v vs]) - ((proj (if swap? (blame-swap blame) blame)) v))) - (apply values vs2))) - ;; prompt/abort projections - (define proj1 (make-proj ho-projs #f)) - (define proj2 (make-proj ho-projs #t)) - ;; call/cc projections - (define call/cc-guard (make-proj call/cc-projs #f)) - (define call/cc-proxy - (λ (f) - (proc-proxy - f - (λ args - (apply values (make-proj call/cc-projs #t) args))))) - ;; now do the actual wrapping - (λ (val) - (unless (contract-first-order-passes? ctc val) - (raise-blame-error - blame val - '(expected: "~s" given: "~e") - (contract-name ctc) - val)) - (proxy val proj1 proj2 call/cc-guard call/cc-proxy - impersonator-prop:contracted ctc - impersonator-prop:blame blame)))) - (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)) @@ -1779,7 +1586,6 @@ #:property prop:chaperone-contract (build-chaperone-contract-property #: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? #:name prompt-tag/c-name)) @@ -1789,7 +1595,6 @@ #:property prop:contract (build-contract-property #: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? #:name prompt-tag/c-name)) @@ -1808,23 +1613,6 @@ 'continuation-mark-key/c (base-continuation-mark-key/c-ctc ctc))) -(define ((continuation-mark-key/c-proj proxy) ctc) - (define ho-proj - (contract-projection (base-continuation-mark-key/c-ctc ctc))) - (λ (blame) - (define proj1 (ho-proj blame)) - (define proj2 (ho-proj (blame-swap blame))) - (λ (val) - (unless (contract-first-order-passes? ctc val) - (raise-blame-error - blame val - '(expected: "~s" given: "~e") - (contract-name ctc) - val)) - (proxy val proj1 proj2 - impersonator-prop:contracted ctc - impersonator-prop:blame blame)))) - (define ((continuation-mark-key/c-late-neg-proj proxy) ctc) (define ho-proj (get/build-late-neg-projection (base-continuation-mark-key/c-ctc ctc))) @@ -1864,7 +1652,6 @@ #:property prop:chaperone-contract (build-chaperone-contract-property #: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? #:name continuation-mark-key/c-name)) @@ -1876,7 +1663,6 @@ #:property prop:contract (build-contract-property #: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? #:name continuation-mark-key/c-name)) @@ -1960,23 +1746,6 @@ 'channel/c (base-channel/c-ctc ctc))) -(define ((channel/c-proj proxy) ctc) - (define ho-proj - (contract-projection (base-channel/c-ctc ctc))) - (λ (blame) - (define proj1 (λ (ch) (values ch (λ (v) ((ho-proj blame) v))))) - (define proj2 (λ (ch v) ((ho-proj (blame-swap blame)) v))) - (λ (val) - (unless (contract-first-order-passes? ctc val) - (raise-blame-error - blame val - '(expected: "~s" given: "~e") - (contract-name ctc) - val)) - (proxy val proj1 proj2 - impersonator-prop:contracted ctc - impersonator-prop:blame blame)))) - (define ((channel/c-late-neg-proj proxy) ctc) (define ho-proj (get/build-late-neg-projection (base-channel/c-ctc ctc))) @@ -2016,7 +1785,6 @@ #:property prop:chaperone-contract (build-chaperone-contract-property #: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? #:name channel/c-name)) @@ -2027,7 +1795,6 @@ #:property prop:contract (build-contract-property #: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? #:name channel/c-name)) diff --git a/racket/collects/racket/contract/private/orc.rkt b/racket/collects/racket/contract/private/orc.rkt index 2b1e410333..63b4a505b5 100644 --- a/racket/collects/racket/contract/private/orc.rkt +++ b/racket/collects/racket/contract/private/orc.rkt @@ -72,17 +72,6 @@ (let ([r (loop (car rst) (cdr rst))]) (λ (x) (or (fst-pred x) (r x))))])))])) -(define (single-or/c-projection ctc) - (let ([c-proc (contract-projection (single-or/c-ho-ctc ctc))] - [pred (single-or/c-pred ctc)]) - (λ (blame) - (define partial-contract - (c-proc (blame-add-or-context blame))) - (λ (val) - (cond - [(pred val) val] - [else (partial-contract val)]))))) - (define (single-or/c-late-neg-projection ctc) (define c-proj (get/build-late-neg-projection (single-or/c-ho-ctc ctc))) (define c-first-order (contract-first-order (single-or/c-ho-ctc ctc))) @@ -218,7 +207,6 @@ #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract (build-chaperone-contract-property - #:projection single-or/c-projection #:late-neg-projection single-or/c-late-neg-projection #:name single-or/c-name #:first-order single-or/c-first-order @@ -233,7 +221,6 @@ #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property - #:projection single-or/c-projection #:late-neg-projection single-or/c-late-neg-projection #:name single-or/c-name #:first-order single-or/c-first-order @@ -244,52 +231,6 @@ #:exercise (λ (ctc) (or/c-exercise (list (single-or/c-ho-ctc ctc)))) #:list-contract? single-or/c-list-contract?)) -(define (multi-or/c-proj ctc) - (let* ([ho-contracts (multi-or/c-ho-ctcs ctc)] - [c-procs (map (λ (x) (contract-projection x)) ho-contracts)] - [first-order-checks (map (λ (x) (contract-first-order x)) ho-contracts)] - [predicates (map flat-contract-predicate (multi-or/c-flat-ctcs ctc))]) - (λ (blame) - (define disj-blame (blame-add-or-context blame)) - (define partial-contracts - (for/list ([c-proc (in-list c-procs)]) - (c-proc disj-blame))) - (λ (val) - (cond - [(ormap (λ (pred) (pred val)) predicates) - val] - [else - (let loop ([checks first-order-checks] - [procs partial-contracts] - [contracts ho-contracts] - [candidate-proc #f] - [candidate-contract #f]) - (cond - [(null? checks) - (if candidate-proc - (candidate-proc val) - (raise-none-or-matched blame val #f))] - [((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)))] - [else - (loop (cdr checks) - (cdr procs) - (cdr contracts) - candidate-proc - candidate-contract)]))]))))) - (define (multi-or/c-late-neg-proj ctc) (define ho-contracts (multi-or/c-ho-ctcs ctc)) (define c-projs (map get/build-late-neg-projection ho-contracts)) @@ -376,7 +317,6 @@ #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract (build-chaperone-contract-property - #:projection multi-or/c-proj #:late-neg-projection multi-or/c-late-neg-proj #:name multi-or/c-name #:first-order multi-or/c-first-order @@ -391,7 +331,6 @@ #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property - #:projection multi-or/c-proj #:late-neg-projection multi-or/c-late-neg-proj #:name multi-or/c-name #:first-order multi-or/c-first-order @@ -453,31 +392,6 @@ (define-struct (flat-first-or/c flat-or/c) ()) -(define (first-or/c-proj ctc) - (define contracts (base-first-or/c-ctcs ctc)) - (define c-procs (map (λ (x) (contract-projection x)) contracts)) - (define first-order-checks (map (λ (x) (contract-first-order x)) contracts)) - (λ (blame) - (define disj-blame (blame-add-ior-context blame)) - (define partial-contracts - (for/list ([c-proc (in-list c-procs)]) - (c-proc disj-blame))) - (λ (val) - (let loop ([checks first-order-checks] - [procs partial-contracts] - [contracts contracts]) - (cond - [(null? checks) - (raise-none-ior-matched blame val #f)] - [else - (cond - [((car checks) val) - ((car procs) val)] - [else - (loop (cdr checks) - (cdr procs) - (cdr contracts))])]))))) - (define (first-or/c-late-neg-proj ctc) (define ho-contracts (base-first-or/c-ctcs ctc)) (define c-projs (map get/build-late-neg-projection ho-contracts)) @@ -538,7 +452,6 @@ (define-struct (chaperone-first-or/c base-first-or/c) () #:property prop:chaperone-contract (build-chaperone-contract-property - #:projection first-or/c-proj #:late-neg-projection first-or/c-late-neg-proj #:name first-or/c-name #:first-order first-or/c-first-order @@ -549,7 +462,6 @@ (define-struct (impersonator-first-or/c base-first-or/c) () #:property prop:contract (build-contract-property - #:projection first-or/c-proj #:late-neg-projection first-or/c-late-neg-proj #:name first-or/c-name #:first-order first-or/c-first-order From e4ffa6c97c2133e75a6b375681b4cae243fc0b24 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 21 Dec 2015 09:20:09 -0600 Subject: [PATCH 212/369] port if/c to late-neg, add tests, and fix some (minor) bugs --- .../tests/racket/contract/flat-contracts.rkt | 3 + .../racket-test/tests/racket/contract/ifc.rkt | 85 ++++++++++++++++ .../tests/racket/contract/name.rkt | 5 + .../collects/racket/contract/private/misc.rkt | 98 ++++++++++++------- 4 files changed, 153 insertions(+), 38 deletions(-) create mode 100644 pkgs/racket-test/tests/racket/contract/ifc.rkt diff --git a/pkgs/racket-test/tests/racket/contract/flat-contracts.rkt b/pkgs/racket-test/tests/racket/contract/flat-contracts.rkt index b992b427ac..3c538b504d 100644 --- a/pkgs/racket-test/tests/racket/contract/flat-contracts.rkt +++ b/pkgs/racket-test/tests/racket/contract/flat-contracts.rkt @@ -71,6 +71,9 @@ (test-flat-contract #rx#".x." "axq" "x") (test-flat-contract ''() '() #f) + (test-flat-contract '(if/c integer? even? list?) 2 3) + (test-flat-contract '(if/c integer? even? list?) '() #f) + (test/spec-passed 'any/c '(contract any/c 1 'pos 'neg)) (test-flat-contract 'printable/c (vector (cons 1 (box #f))) (lambda (x) x)) (let () diff --git a/pkgs/racket-test/tests/racket/contract/ifc.rkt b/pkgs/racket-test/tests/racket/contract/ifc.rkt new file mode 100644 index 0000000000..69fa592650 --- /dev/null +++ b/pkgs/racket-test/tests/racket/contract/ifc.rkt @@ -0,0 +1,85 @@ +#lang racket/base +(require "test-util.rkt") + +(parameterize ([current-contract-namespace + (make-basic-contract-namespace)]) + + (test/spec-passed/result + 'if/c1 + '(contract (if/c integer? even? (listof number?)) + 2 + 'pos 'neg) + 2) + + (test/spec-passed/result + 'if/c2 + '(contract (if/c integer? even? (listof number?)) + '() + 'pos 'neg) + '()) + + (test/pos-blame + 'if/c3 + '(contract (if/c integer? even? (listof number?)) + 3 + 'pos 'neg)) + + (test/pos-blame + 'if/c4 + '(contract (if/c integer? even? (listof number?)) + '(#f) + 'pos 'neg)) + + (test/pos-blame + 'if/c5 + '(contract (if/c integer? even? (listof number?)) + #f + 'pos 'neg)) + + (test/pos-blame + 'if/c6 + '(contract (if/c (λ (x) (and (procedure? x) (procedure-arity-includes? x 1))) + (-> integer? integer?) + number?) + #f + 'pos 'neg)) + + (test/neg-blame + 'if/c7 + '((contract (if/c (λ (x) (and (procedure? x) (procedure-arity-includes? x 1))) + (-> integer? integer?) + number?) + (λ (x) x) + 'pos 'neg) + #f)) + + (test/spec-passed/result + 'if/c8 + '(contract (if/c (λ (x) (and (procedure? x) (procedure-arity-includes? x 1))) + (-> integer? integer?) + number?) + 1 + 'pos 'neg) + 1) + + (test/spec-passed/result + 'if/c9 + '(let ([f (λ (x) x)]) + (chaperone-of? + (contract (if/c (λ (x) (and (procedure? x) (procedure-arity-includes? x 1))) + (-> integer? integer?) + number?) + f + 'pos 'neg) + f)) + #t) + + (test/spec-passed/result + 'if/c10 + '(chaperone-contract? + (if/c (λ (x) (and (procedure? x) (procedure-arity-includes? x 1))) + (-> integer? integer?) + number?)) + #t)) + + diff --git a/pkgs/racket-test/tests/racket/contract/name.rkt b/pkgs/racket-test/tests/racket/contract/name.rkt index 384f830148..d81b3b79ed 100644 --- a/pkgs/racket-test/tests/racket/contract/name.rkt +++ b/pkgs/racket-test/tests/racket/contract/name.rkt @@ -32,6 +32,11 @@ (or/c (-> (>=/c 5) (>=/c 5)) boolean?)) (test-name '(or/c boolean? (-> (>=/c 5) (>=/c 5))) (or/c boolean? (-> (>=/c 5) (>=/c 5)))) + + (test-name '(if/c integer? odd? (-> integer? integer?)) + (if/c integer? odd? (-> integer? integer?))) + (test-name '(if/c integer? odd? boolean?) + (if/c integer? odd? boolean?)) (test-name '(first-or/c) (first-or/c)) (test-name '(first-or/c integer? gt0?) (first-or/c integer? (let ([gt0? (lambda (x) (> x 0))]) gt0?))) diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index edbe1673fc..301f086a6c 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -1999,44 +1999,66 @@ #: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)))))))) + (unless (procedure-arity-includes? predicate 1) + (raise-type-error 'if/c "procedure that accepts 1 argument" predicate)) + (define then-ctc (coerce-contract 'if/c then/c)) + (define else-ctc (coerce-contract 'if/c else/c)) + (cond + [(and (flat-contract? then-ctc) + (flat-contract? else-ctc)) + (define then-pred (flat-contract-predicate then-ctc)) + (define else-pred (flat-contract-predicate else-ctc)) + (define name `(if/c ,(object-name predicate) + ,(contract-name then-pred) + ,(contract-name else-pred))) + (define (pred x) + (if (predicate x) (then-pred x) (else-pred x))) + (flat-named-contract name pred)] + [(and (chaperone-contract? then-ctc) + (chaperone-contract? else-ctc)) + (chaperone-if/c predicate then-ctc else-ctc)] + [else + (impersonator-if/c predicate then-ctc else-ctc)])) + +(define (if/c-first-order ctc) + (define predicate (base-if/c-predicate ctc)) + (define thn (contract-first-order (base-if/c-thn ctc))) + (define els (contract-first-order (base-if/c-els ctc))) + (λ (x) (if (predicate x) (thn x) (els x)))) + +(define (if/c-name ctc) + (define predicate (base-if/c-predicate ctc)) + (define thn (contract-name (base-if/c-thn ctc))) + (define els (contract-name (base-if/c-els ctc))) + `(if/c ,(object-name predicate) ,thn ,els)) + +(define (if/c-late-neg-proj ctc) + (define predicate (base-if/c-predicate ctc)) + (define thn (contract-late-neg-projection (base-if/c-thn ctc))) + (define els (contract-late-neg-projection (base-if/c-els ctc))) + (λ (blame) + (define thn-proj (thn blame)) + (define els-proj (els blame)) + (λ (val neg-party) + (if (predicate val) + (thn-proj val neg-party) + (els-proj val neg-party))))) + +(define-struct base-if/c (predicate thn els) + #:property prop:custom-write custom-write-property-proc) +(define-struct (chaperone-if/c base-if/c) () + #:property prop:chaperone-contract + (build-chaperone-contract-property + #:late-neg-projection if/c-late-neg-proj + #:first-order if/c-first-order + #:name if/c-name)) + +(define-struct (impersonator-if/c base-if/c) () + #:property prop:contract + (build-contract-property + #:late-neg-projection if/c-late-neg-proj + #:first-order if/c-first-order + #:name if/c-name)) From 261a5cb1f40ed1e97cbadfc48719692ff84cd5d1 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 21 Dec 2015 09:31:34 -0600 Subject: [PATCH 213/369] port rename-contract to late-neg projection and add some tests --- .../tests/racket/contract/rename.rkt | 70 +++++++++++++++++++ .../collects/racket/contract/private/misc.rkt | 2 +- 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 pkgs/racket-test/tests/racket/contract/rename.rkt diff --git a/pkgs/racket-test/tests/racket/contract/rename.rkt b/pkgs/racket-test/tests/racket/contract/rename.rkt new file mode 100644 index 0000000000..2c6488a8d0 --- /dev/null +++ b/pkgs/racket-test/tests/racket/contract/rename.rkt @@ -0,0 +1,70 @@ +#lang racket/base +(require "test-util.rkt") + +(parameterize ([current-contract-namespace + (make-basic-contract-namespace + 'racket/contract/parametric)]) + + (test/spec-passed/result + 'rename1 + '(contract-name + (rename-contract (-> integer? integer?) + 'another-name)) + 'another-name) + + (test/spec-passed/result + 'rename2 + '(chaperone-contract? + (rename-contract (-> integer? integer?) + 'another-name)) + #t) + + (test/spec-passed/result + 'rename3 + '(contract-name + (rename-contract integer? 'another-name)) + 'another-name) + + (test/spec-passed/result + 'rename4 + '(flat-contract? + (rename-contract integer? 'another-name)) + #t) + + (test/spec-passed/result + 'rename5 + '(contract-name + (rename-contract integer? 'another-name)) + 'another-name) + + (test/spec-passed/result + 'rename6 + '(flat-contract? + (rename-contract (new-∀/c 'alpha) 'α)) + #f) + + (test/spec-passed/result + 'rename7 + '(chaperone-contract? + (rename-contract (new-∀/c 'alpha) 'α)) + #f) + + (test/spec-passed/result + 'rename8 + '(contract? + (rename-contract (new-∀/c 'alpha) 'α)) + #t) + + (test/pos-blame + 'rename9 + '((contract (rename-contract (-> integer? integer?) 'whatever) + (λ (x) #f) + 'pos 'neg) + 1)) + + (test/neg-blame + 'rename10 + '((contract (rename-contract (-> integer? integer?) 'whatever) + (λ (x) x) + 'pos 'neg) + #f))) diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index 301f086a6c..5afebeb255 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -1994,7 +1994,7 @@ (define (stronger? this other) (contract-stronger? ctc other)) (make-contract #:name name - #:projection (contract-projection ctc) + #:late-neg-projection (contract-late-neg-projection ctc) #:first-order (contract-first-order ctc) #:stronger stronger? #:list-contract? (list-contract? ctc)))))) From 3a4ba9a1ca31a83dcb9704ac8e464e15f505e579 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 21 Dec 2015 10:32:08 -0600 Subject: [PATCH 214/369] fix parametric->/c for the keyword case --- .../racket-test/tests/racket/contract/parametric.rkt | 12 +++++++++++- .../collects/racket/contract/private/parametric.rkt | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-test/tests/racket/contract/parametric.rkt b/pkgs/racket-test/tests/racket/contract/parametric.rkt index 819d9a761d..1a3b065d65 100644 --- a/pkgs/racket-test/tests/racket/contract/parametric.rkt +++ b/pkgs/racket-test/tests/racket/contract/parametric.rkt @@ -70,4 +70,14 @@ (λ (x) (unless c (set! c x)) c) 'pos 'neg)]) (f 1) - (f 2)))) + (f 2))) + + (test/spec-passed/result + 'parametric->/c8 + '((contract + (parametric->/c (x) (-> #:x x x)) + (λ (#:x x) x) + 'pos 'neg) + #:x 11) + 11)) + diff --git a/racket/collects/racket/contract/private/parametric.rkt b/racket/collects/racket/contract/private/parametric.rkt index a599a51276..2fa504c15b 100644 --- a/racket/collects/racket/contract/private/parametric.rkt +++ b/racket/collects/racket/contract/private/parametric.rkt @@ -76,7 +76,7 @@ (raise-blame-error blame #:missing-party neg-party p '(expected "a procedure" given: "~e") p)) (make-keyword-procedure - (lambda (keys vals . args) (keyword-apply (wrap p) keys vals args)) + (lambda (keys vals . args) (keyword-apply (wrap p neg-party) keys vals args)) (case-lambda [() ((wrap p neg-party))] [(a) ((wrap p neg-party) a)] From 99d7ad56d954fff40b68066cca666f4486e0b3aa Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 21 Dec 2015 09:35:39 -0600 Subject: [PATCH 215/369] clean up exports of racket/contract/combinator It used to have a (provide (except-out (all-from-out ) ...)) and various private functions leaked to the outside over the years. None of the ones removed in this commit were documented, so hopefully they weren't being used. But this is definitely not backwards compatible, so this commit is mostly about testing the waters --- racket/collects/racket/async-channel.rkt | 4 +- .../collects/racket/contract/combinator.rkt | 116 +++++++++++++----- .../collects/racket/private/class-c-old.rkt | 6 +- racket/collects/racket/stream.rkt | 4 +- 4 files changed, 94 insertions(+), 36 deletions(-) diff --git a/racket/collects/racket/async-channel.rkt b/racket/collects/racket/async-channel.rkt index 5c8b419d34..3216a69043 100644 --- a/racket/collects/racket/async-channel.rkt +++ b/racket/collects/racket/async-channel.rkt @@ -245,7 +245,7 @@ (struct base-async-channel/c (content)) (struct chaperone-async-channel/c base-async-channel/c () - #:property prop:custom-write custom-write-property-proc + #:property prop:custom-write contract-custom-write-property-proc #:property prop:chaperone-contract (build-chaperone-contract-property #:name async-channel/c-name @@ -255,7 +255,7 @@ #:projection (ho-projection chaperone-async-channel))) (struct impersonator-async-channel/c base-async-channel/c () - #:property prop:custom-write custom-write-property-proc + #:property prop:custom-write contract-custom-write-property-proc #:property prop:contract (build-contract-property #:name async-channel/c-name diff --git a/racket/collects/racket/contract/combinator.rkt b/racket/collects/racket/contract/combinator.rkt index 5072060024..4d7e43f5be 100644 --- a/racket/collects/racket/contract/combinator.rkt +++ b/racket/collects/racket/contract/combinator.rkt @@ -4,34 +4,93 @@ "private/guts.rkt" "private/blame.rkt") -(provide - (except-out (all-from-out "private/prop.rkt") - contract-struct-name - contract-struct-first-order - contract-struct-projection - contract-struct-val-first-projection - contract-struct-stronger? - contract-struct? - chaperone-contract-struct? - flat-contract-struct? - make-chaperone-contract - make-flat-contract - build-chaperone-contract-property - build-flat-contract-property) - - (except-out (all-from-out "private/guts.rkt") - check-flat-contract - check-flat-named-contract - make-predicate-contract - has-contract? - value-contract) - - (except-out (all-from-out "private/blame.rkt") make-blame) - (rename-out [-make-chaperone-contract make-chaperone-contract] - [-make-flat-contract make-flat-contract] - [-build-chaperone-contract-property build-chaperone-contract-property] - [-build-flat-contract-property build-flat-contract-property]) - skip-projection-wrapper?) +(provide prop:contract + prop:flat-contract + prop:chaperone-contract + + contract-property? + build-contract-property + + chaperone-contract-property? + + flat-contract-property? + + make-contract + + prop:opt-chaperone-contract + prop:opt-chaperone-contract? + prop:opt-chaperone-contract-get-test + + prop:orc-contract + prop:orc-contract? + prop:orc-contract-get-subcontracts + + prop:recursive-contract + prop:recursive-contract? + prop:recursive-contract-unroll + + prop:arrow-contract + prop:arrow-contract? + prop:arrow-contract-get-info + + coerce-contract + coerce-contracts + coerce-flat-contract + coerce-flat-contracts + coerce-chaperone-contract + coerce-chaperone-contracts + coerce-contract/f + + build-compound-type-name + + contract-stronger? + list-contract? + + contract-first-order + contract-first-order-passes? + + prop:contracted prop:blame + impersonator-prop:contracted impersonator-prop:blame + has-blame? value-blame + + ;; helpers for adding properties that check syntax uses + define/final-prop + define/subexpression-pos-prop + define/subexpression-pos-prop/name + + contract-continuation-mark-key + + (struct-out wrapped-extra-arg-arrow) + + blame? + blame-source + blame-positive + blame-negative + blame-contract + blame-value + blame-original? + blame-swapped? + blame-swap + blame-replace-negative ;; used for indy blame + blame-update ;; used for option contract transfers + blame-add-context + blame-add-unknown-context + blame-context + blame-add-missing-party + blame-missing-party? + raise-blame-error + current-blame-format + (struct-out exn:fail:contract:blame) + + (rename-out [custom-write-property-proc contract-custom-write-property-proc]) + + (rename-out [-make-chaperone-contract make-chaperone-contract] + [-make-flat-contract make-flat-contract] + [-build-chaperone-contract-property build-chaperone-contract-property] + [-build-flat-contract-property build-flat-contract-property]) + skip-projection-wrapper? + + blame-fmt->-string) (define skip-projection-wrapper? (make-parameter #f)) @@ -199,4 +258,3 @@ (λ (x) (x-acceptor x) x)))) - diff --git a/racket/collects/racket/private/class-c-old.rkt b/racket/collects/racket/private/class-c-old.rkt index 22e31cf62d..def3f5412e 100644 --- a/racket/collects/racket/private/class-c-old.rkt +++ b/racket/collects/racket/private/class-c-old.rkt @@ -947,7 +947,7 @@ absents absent-fields internal opaque? name) #:omit-define-syntaxes - #:property prop:custom-write custom-write-property-proc + #:property prop:custom-write contract-custom-write-property-proc #:property prop:contract (build-contract-property #:late-neg-projection class/c-late-neg-proj @@ -1382,7 +1382,7 @@ (base-instanceof/c-class-ctc that)))) (define-struct base-instanceof/c (class-ctc) - #:property prop:custom-write custom-write-property-proc + #:property prop:custom-write contract-custom-write-property-proc #:property prop:contract (build-contract-property #:late-neg-projection instanceof/c-late-neg-proj @@ -1484,7 +1484,7 @@ (contract-stronger? this-ctc that-ctc)))))) (define-struct base-object/c (methods method-contracts fields field-contracts) - #:property prop:custom-write custom-write-property-proc + #:property prop:custom-write contract-custom-write-property-proc #:property prop:contract (build-contract-property #:late-neg-projection instanceof/c-late-neg-proj diff --git a/racket/collects/racket/stream.rkt b/racket/collects/racket/stream.rkt index 18d0b17bf7..a34edf6071 100644 --- a/racket/collects/racket/stream.rkt +++ b/racket/collects/racket/stream.rkt @@ -272,7 +272,7 @@ (struct base-stream/c (content)) (struct chaperone-stream/c base-stream/c () - #:property prop:custom-write custom-write-property-proc + #:property prop:custom-write contract-custom-write-property-proc #:property prop:chaperone-contract (build-chaperone-contract-property #:name stream/c-name @@ -281,7 +281,7 @@ #:projection (ho-projection chaperone-stream))) (struct impersonator-stream/c base-stream/c () - #:property prop:custom-write custom-write-property-proc + #:property prop:custom-write contract-custom-write-property-proc #:property prop:contract (build-contract-property #:name stream/c-name From aeb0509f3af5734e5f1121be30b254a5527109d8 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 21 Dec 2015 22:45:58 -0600 Subject: [PATCH 216/369] fix performance bug in late-neg projection for cons/c the first-order check and the projection itself can duplicate work (potentailly lots of work in a non-constant factor sort of a way when recursive-contract is involved) this seems also to be a potential problem for other uses of or/c too --- racket/collects/racket/contract/private/orc.rkt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/racket/collects/racket/contract/private/orc.rkt b/racket/collects/racket/contract/private/orc.rkt index 63b4a505b5..6fa24bfc7a 100644 --- a/racket/collects/racket/contract/private/orc.rkt +++ b/racket/collects/racket/contract/private/orc.rkt @@ -74,15 +74,13 @@ (define (single-or/c-late-neg-projection ctc) (define c-proj (get/build-late-neg-projection (single-or/c-ho-ctc ctc))) - (define c-first-order (contract-first-order (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 neg-party) (cond [(pred val) val] - [(c-first-order val) (p-app val neg-party)] - [else (raise-none-or-matched blame val neg-party)])))) + [else (p-app val neg-party)])))) (define (blame-add-or-context blame) (blame-add-context blame "a part of the or/c of")) From b221e0093711028e0a11c6431688ea7fcc43f5f4 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 21 Dec 2015 22:56:34 -0600 Subject: [PATCH 217/369] Revert " clean up exports of racket/contract/combinator" I didn't intend to push that commit --- racket/collects/racket/async-channel.rkt | 4 +- .../collects/racket/contract/combinator.rkt | 116 +++++------------- .../collects/racket/private/class-c-old.rkt | 6 +- racket/collects/racket/stream.rkt | 4 +- 4 files changed, 36 insertions(+), 94 deletions(-) diff --git a/racket/collects/racket/async-channel.rkt b/racket/collects/racket/async-channel.rkt index 3216a69043..5c8b419d34 100644 --- a/racket/collects/racket/async-channel.rkt +++ b/racket/collects/racket/async-channel.rkt @@ -245,7 +245,7 @@ (struct base-async-channel/c (content)) (struct chaperone-async-channel/c base-async-channel/c () - #:property prop:custom-write contract-custom-write-property-proc + #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract (build-chaperone-contract-property #:name async-channel/c-name @@ -255,7 +255,7 @@ #:projection (ho-projection chaperone-async-channel))) (struct impersonator-async-channel/c base-async-channel/c () - #:property prop:custom-write contract-custom-write-property-proc + #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property #:name async-channel/c-name diff --git a/racket/collects/racket/contract/combinator.rkt b/racket/collects/racket/contract/combinator.rkt index 4d7e43f5be..5072060024 100644 --- a/racket/collects/racket/contract/combinator.rkt +++ b/racket/collects/racket/contract/combinator.rkt @@ -4,93 +4,34 @@ "private/guts.rkt" "private/blame.rkt") -(provide prop:contract - prop:flat-contract - prop:chaperone-contract - - contract-property? - build-contract-property - - chaperone-contract-property? - - flat-contract-property? - - make-contract - - prop:opt-chaperone-contract - prop:opt-chaperone-contract? - prop:opt-chaperone-contract-get-test - - prop:orc-contract - prop:orc-contract? - prop:orc-contract-get-subcontracts - - prop:recursive-contract - prop:recursive-contract? - prop:recursive-contract-unroll - - prop:arrow-contract - prop:arrow-contract? - prop:arrow-contract-get-info - - coerce-contract - coerce-contracts - coerce-flat-contract - coerce-flat-contracts - coerce-chaperone-contract - coerce-chaperone-contracts - coerce-contract/f - - build-compound-type-name - - contract-stronger? - list-contract? - - contract-first-order - contract-first-order-passes? - - prop:contracted prop:blame - impersonator-prop:contracted impersonator-prop:blame - has-blame? value-blame - - ;; helpers for adding properties that check syntax uses - define/final-prop - define/subexpression-pos-prop - define/subexpression-pos-prop/name - - contract-continuation-mark-key - - (struct-out wrapped-extra-arg-arrow) - - blame? - blame-source - blame-positive - blame-negative - blame-contract - blame-value - blame-original? - blame-swapped? - blame-swap - blame-replace-negative ;; used for indy blame - blame-update ;; used for option contract transfers - blame-add-context - blame-add-unknown-context - blame-context - blame-add-missing-party - blame-missing-party? - raise-blame-error - current-blame-format - (struct-out exn:fail:contract:blame) - - (rename-out [custom-write-property-proc contract-custom-write-property-proc]) - - (rename-out [-make-chaperone-contract make-chaperone-contract] - [-make-flat-contract make-flat-contract] - [-build-chaperone-contract-property build-chaperone-contract-property] - [-build-flat-contract-property build-flat-contract-property]) - skip-projection-wrapper? - - blame-fmt->-string) +(provide + (except-out (all-from-out "private/prop.rkt") + contract-struct-name + contract-struct-first-order + contract-struct-projection + contract-struct-val-first-projection + contract-struct-stronger? + contract-struct? + chaperone-contract-struct? + flat-contract-struct? + make-chaperone-contract + make-flat-contract + build-chaperone-contract-property + build-flat-contract-property) + + (except-out (all-from-out "private/guts.rkt") + check-flat-contract + check-flat-named-contract + make-predicate-contract + has-contract? + value-contract) + + (except-out (all-from-out "private/blame.rkt") make-blame) + (rename-out [-make-chaperone-contract make-chaperone-contract] + [-make-flat-contract make-flat-contract] + [-build-chaperone-contract-property build-chaperone-contract-property] + [-build-flat-contract-property build-flat-contract-property]) + skip-projection-wrapper?) (define skip-projection-wrapper? (make-parameter #f)) @@ -258,3 +199,4 @@ (λ (x) (x-acceptor x) x)))) + diff --git a/racket/collects/racket/private/class-c-old.rkt b/racket/collects/racket/private/class-c-old.rkt index def3f5412e..22e31cf62d 100644 --- a/racket/collects/racket/private/class-c-old.rkt +++ b/racket/collects/racket/private/class-c-old.rkt @@ -947,7 +947,7 @@ absents absent-fields internal opaque? name) #:omit-define-syntaxes - #:property prop:custom-write contract-custom-write-property-proc + #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property #:late-neg-projection class/c-late-neg-proj @@ -1382,7 +1382,7 @@ (base-instanceof/c-class-ctc that)))) (define-struct base-instanceof/c (class-ctc) - #:property prop:custom-write contract-custom-write-property-proc + #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property #:late-neg-projection instanceof/c-late-neg-proj @@ -1484,7 +1484,7 @@ (contract-stronger? this-ctc that-ctc)))))) (define-struct base-object/c (methods method-contracts fields field-contracts) - #:property prop:custom-write contract-custom-write-property-proc + #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property #:late-neg-projection instanceof/c-late-neg-proj diff --git a/racket/collects/racket/stream.rkt b/racket/collects/racket/stream.rkt index a34edf6071..18d0b17bf7 100644 --- a/racket/collects/racket/stream.rkt +++ b/racket/collects/racket/stream.rkt @@ -272,7 +272,7 @@ (struct base-stream/c (content)) (struct chaperone-stream/c base-stream/c () - #:property prop:custom-write contract-custom-write-property-proc + #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract (build-chaperone-contract-property #:name stream/c-name @@ -281,7 +281,7 @@ #:projection (ho-projection chaperone-stream))) (struct impersonator-stream/c base-stream/c () - #:property prop:custom-write contract-custom-write-property-proc + #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property #:name stream/c-name From c01ced6e1dcb15cda55052b51db95a1923b87b06 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 21 Dec 2015 13:47:39 -0700 Subject: [PATCH 218/369] add `syntax-transforming-with-lifts?` --- .../scribblings/reference/stx-trans.scrbl | 19 +- racket/src/racket/src/cstartup.inc | 1585 ++++++++--------- racket/src/racket/src/env.c | 20 + racket/src/racket/src/schminc.h | 2 +- racket/src/racket/src/schvers.h | 4 +- 5 files changed, 833 insertions(+), 797 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl index 3eca603e50..ae05333533 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl @@ -651,7 +651,9 @@ Other syntactic forms can capture lifts by using @racket[local-expand/capture-lifts] or @racket[local-transformer-expand/capture-lifts]. -@transform-time[]} +@transform-time[] In addition, this procedure can be called only when +a lift target is available, as indicated by +@racket[syntax-transforming-with-lifts?].} @defproc[(syntax-local-lift-values-expression [n exact-nonnegative-integer?] [stx syntax?]) (listof identifier?)]{ @@ -877,6 +879,21 @@ transformer} application by the expander and while a module is being @tech{visit}ed, @racket[#f] otherwise.} +@defproc[(syntax-transforming-with-lifts?) boolean?]{ + +Returns @racket[#t] if @racket[(syntax-transforming?)] produces +@racket[#t] and a target context is available for lifting expressions +(via @racket[syntax-local-lift-expression]), @racket[#f] otherwise. + +For example, during an immedate macro expansion triggered by +@racket[local-expand], as opposed to +@racket[local-expand/capture-lifts], @racket[(syntax-transforming?)] +produces @racket[#t] while @racket[(syntax-transforming-with-lifts?)] +produces @racket[#f]. + +@history[#:added "6.3.0.9"]} + + @defproc[(syntax-transforming-module-expression?) boolean?]{ Returns @racket[#t] during the dynamic extent of a @tech{syntax diff --git a/racket/src/racket/src/cstartup.inc b/racket/src/racket/src/cstartup.inc index 498d29e8fc..f7d3ca6dff 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,7,54,46,51,46,48,46,53,84,0,0,0,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,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, @@ -29,50 +29,50 @@ 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,168,20,193,249,22, -157,4,80,143,42,39,251,22,90,2,19,248,22,168,20,199,249,22,80,2,4, -248,22,169,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,168, +20,14,144,40,39,40,28,248,22,88,248,22,82,194,248,22,169,20,193,249,22, +157,4,80,143,42,39,251,22,90,2,19,248,22,169,20,199,249,22,80,2,4, +248,22,170,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,169, 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,168,20,201,251,22,90,2,19,2,22,2,22,249,22, -80,2,11,248,22,169,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,169,20,195,27,248,22, +248,22,90,2,22,248,22,169,20,201,251,22,90,2,19,2,22,2,22,249,22, +80,2,11,248,22,170,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,170,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,168,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,168,20,23, +22,90,249,22,90,248,22,90,248,22,169,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,169,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,168,20,201,248,22, -169,20,198,27,248,22,164,4,194,249,22,80,248,22,90,248,22,81,196,248,22, -169,20,195,27,248,22,82,248,22,164,4,23,197,1,249,22,157,4,80,143,42, +148,8,36,40,50,11,9,222,33,44,248,22,164,4,248,22,169,20,201,248,22, +170,20,198,27,248,22,164,4,194,249,22,80,248,22,90,248,22,81,196,248,22, +170,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,169,20,198,27,248,22,82,248,22,164, +46,248,22,164,4,248,22,81,201,248,22,170,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,169,20,199,250,22,90,2,7,248,22, -90,248,22,81,199,250,22,91,2,8,248,22,169,20,201,248,22,169,20,202,27, +22,88,195,250,22,91,2,21,9,248,22,170,20,199,250,22,90,2,7,248,22, +90,248,22,81,199,250,22,91,2,8,248,22,170,20,201,248,22,170,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,169,20,199,250, -22,90,2,21,248,22,90,248,22,81,199,250,22,91,2,9,248,22,169,20,201, -248,22,169,20,202,27,248,22,82,248,22,164,4,23,197,1,27,249,22,1,22, +80,143,43,39,28,248,22,88,195,250,22,91,2,21,9,248,22,170,20,199,250, +22,90,2,21,248,22,90,248,22,81,199,250,22,91,2,9,248,22,170,20,201, +248,22,170,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,169,20,204,27,248,22,82,248,22,164,4,196,28,248,22,88,193,20,14,144, +22,170,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,168,20,199,250,22,91,2,5,249,22, -90,2,26,249,22,90,248,22,111,203,2,26,248,22,169,20,202,251,22,90,2, -19,28,249,22,169,9,248,22,158,4,248,22,168,20,200,66,101,108,115,101,10, -248,22,168,20,197,250,22,91,2,21,9,248,22,169,20,200,249,22,80,2,5, -248,22,169,20,202,18,143,94,10,66,118,111,105,100,2,28,27,248,22,82,248, +22,90,249,22,90,21,93,2,26,248,22,169,20,199,250,22,91,2,5,249,22, +90,2,26,249,22,90,248,22,111,203,2,26,248,22,170,20,202,251,22,90,2, +19,28,249,22,169,9,248,22,158,4,248,22,169,20,200,66,101,108,115,101,10, +248,22,169,20,197,250,22,91,2,21,9,248,22,170,20,200,249,22,80,2,5, +248,22,170,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,168,20,199,248,22,102,198,27, -248,22,158,4,248,22,168,20,197,250,22,90,2,27,248,22,90,248,22,81,197, -250,22,91,2,24,248,22,169,20,199,248,22,169,20,202,145,39,9,20,121,145, +22,81,197,250,22,90,2,27,248,22,90,248,22,169,20,199,248,22,102,198,27, +248,22,158,4,248,22,169,20,197,250,22,90,2,27,248,22,90,248,22,81,197, +250,22,91,2,24,248,22,170,20,199,248,22,170,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, @@ -102,7 +102,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 2090); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,48,46,53,84,0,0,0,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,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, @@ -113,16 +113,16 @@ 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,91,6,121,6,212,9,235,9, 252,9,176,11,23,12,37,12,241,12,217,14,226,14,235,14,249,14,3,15,23, -16,126,16,251,16,68,17,141,17,245,17,18,18,89,18,227,18,42,19,255,19, -117,20,130,20,248,20,5,21,112,21,179,21,192,21,203,21,99,22,217,22,5, -23,116,23,194,25,218,25,80,26,162,27,169,27,221,27,234,27,224,28,240,28, -95,29,254,29,5,30,138,31,215,31,232,31,132,32,152,32,212,32,219,32,79, -33,133,33,152,33,103,34,119,34,80,35,81,36,118,36,127,36,214,37,59,40, -75,40,142,40,163,40,183,40,203,40,4,41,233,43,199,44,215,44,186,45,244, -45,21,46,153,46,56,47,72,47,169,47,186,47,8,50,59,52,75,52,49,54, -237,54,239,54,10,55,26,55,42,55,139,55,206,56,138,57,154,57,163,57,170, -57,236,58,46,60,164,60,210,63,84,64,216,64,161,66,111,67,153,67,5,68, -0,0,209,75,0,0,3,1,5,105,110,115,112,48,69,35,37,117,116,105,108, +16,126,16,251,16,68,17,141,17,243,17,16,18,87,18,221,18,36,19,243,19, +105,20,118,20,236,20,249,20,100,21,167,21,180,21,191,21,87,22,205,22,249, +22,104,23,182,25,206,25,68,26,150,27,157,27,209,27,222,27,212,28,228,28, +83,29,242,29,249,29,126,31,203,31,220,31,120,32,140,32,200,32,207,32,67, +33,121,33,140,33,91,34,107,34,68,35,69,36,106,36,115,36,202,37,47,40, +63,40,130,40,151,40,171,40,191,40,248,40,221,43,187,44,203,44,174,45,232, +45,9,46,141,46,44,47,60,47,157,47,174,47,252,49,47,52,63,52,37,54, +225,54,227,54,254,54,14,55,30,55,127,55,194,56,126,57,142,57,151,57,158, +57,224,58,34,60,152,60,198,63,72,64,204,64,149,66,99,67,141,67,249,67, +0,0,197,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, @@ -272,14 +272,14 @@ 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,132,16,248, 22,140,16,248,22,81,23,201,2,23,196,2,28,248,22,190,15,23,194,2,250, -2,86,197,198,195,86,94,23,193,1,27,248,22,169,20,23,199,1,28,248,22, +2,86,197,198,195,86,94,23,193,1,27,248,22,170,20,23,199,1,28,248,22, 88,23,194,2,11,27,249,22,132,16,248,22,140,16,248,22,81,23,198,2,23, 198,2,28,248,22,190,15,23,194,2,250,2,86,199,200,195,86,94,23,193,1, -27,248,22,169,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,132,16, +27,248,22,170,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,132,16, 248,22,140,16,248,22,81,23,198,2,23,200,2,28,248,22,190,15,23,194,2, -250,2,86,201,202,195,86,94,23,193,1,27,248,22,169,20,23,196,1,28,248, +250,2,86,201,202,195,86,94,23,193,1,27,248,22,170,20,23,196,1,28,248, 22,88,23,194,2,11,27,249,22,132,16,248,22,140,16,248,22,81,197,201,28, -248,22,190,15,193,250,2,86,203,204,195,251,2,90,203,204,205,248,22,169,20, +248,22,190,15,193,250,2,86,203,204,195,251,2,90,203,204,205,248,22,170,20, 198,86,95,28,28,248,22,178,15,23,195,2,10,28,248,22,153,7,23,195,2, 28,248,22,137,16,23,195,2,10,248,22,138,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,178,15,23,196, @@ -294,15 +294,15 @@ 27,28,249,22,169,9,247,22,180,8,2,43,249,22,80,248,22,187,15,5,1, 46,23,196,1,23,194,1,28,248,22,88,23,194,2,11,27,249,22,132,16,248, 22,140,16,248,22,81,23,198,2,23,200,2,28,248,22,190,15,23,194,2,250, -2,86,201,202,195,86,94,23,193,1,27,248,22,169,20,23,196,1,28,248,22, +2,86,201,202,195,86,94,23,193,1,27,248,22,170,20,23,196,1,28,248,22, 88,23,194,2,11,27,249,22,132,16,248,22,140,16,248,22,81,23,198,2,23, 202,2,28,248,22,190,15,23,194,2,250,2,86,203,204,195,86,94,23,193,1, -27,248,22,169,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,132,16, +27,248,22,170,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,132,16, 248,22,140,16,248,22,81,23,198,2,23,204,2,28,248,22,190,15,23,194,2, -250,2,86,205,206,195,86,94,23,193,1,27,248,22,169,20,23,196,1,28,248, +250,2,86,205,206,195,86,94,23,193,1,27,248,22,170,20,23,196,1,28,248, 22,88,23,194,2,11,27,249,22,132,16,248,22,140,16,248,22,81,197,205,28, 248,22,190,15,193,250,2,86,23,15,23,16,195,251,2,90,23,15,23,16,23, -17,248,22,169,20,198,27,248,22,140,16,23,196,1,28,248,22,190,15,193,250, +17,248,22,170,20,198,27,248,22,140,16,23,196,1,28,248,22,190,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,171,16,23,197,2,23,198,2,28,23,193,2, @@ -336,721 +336,720 @@ 22,178,15,23,195,2,10,28,248,22,153,7,23,195,2,28,248,22,137,16,23, 195,2,10,248,22,138,16,23,195,2,11,12,250,22,182,11,23,196,2,2,48, 23,197,2,28,248,22,137,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,178,15,23,195,2,10,28,248, -22,153,7,23,195,2,28,248,22,137,16,23,195,2,10,248,22,138,16,23,195, -2,11,12,250,22,182,11,23,196,2,2,48,23,197,2,28,248,22,137,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,182,11,23,196,1,2,54,23,197,1,86,94,28,28,248,22,178,15,23, -194,2,10,28,248,22,153,7,23,194,2,28,248,22,137,16,23,194,2,10,248, -22,138,16,23,194,2,11,12,250,22,182,11,2,15,2,48,23,196,2,28,248, -22,137,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,178,15,23,196,2,10,28,248,22,153,7,23, -196,2,28,248,22,137,16,23,196,2,10,248,22,138,16,23,196,2,11,12,250, -22,182,11,2,15,2,48,23,198,2,28,248,22,137,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,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,178,15,23,194, -2,10,28,248,22,153,7,23,194,2,28,248,22,137,16,23,194,2,10,248,22, -138,16,23,194,2,11,12,250,22,182,11,2,17,2,48,23,196,2,28,248,22, -137,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,178,15,23,197,2,10,28,248,22,153,7,23,197,2,28, -248,22,137,16,23,197,2,10,248,22,138,16,23,197,2,11,12,250,22,182,11, -2,17,2,48,23,199,2,28,248,22,137,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,178,15,23,198,2, -10,28,248,22,153,7,23,198,2,28,248,22,137,16,23,198,2,10,248,22,138, -16,23,198,2,11,12,250,22,182,11,2,17,2,48,23,200,2,28,248,22,137, -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,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,155,16,2,55,28,248,22,139,16,23,194,2,248,22,142,16,23, -194,1,28,248,22,138,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22, -135,16,249,22,140,16,250,80,144,49,43,42,248,22,155,16,2,56,11,11,248, -22,155,16,2,57,86,95,23,195,1,23,194,1,248,22,142,16,249,22,140,16, -23,199,1,23,196,1,27,250,80,144,44,43,42,248,22,155,16,2,56,23,197, -1,10,28,23,193,2,248,22,142,16,23,194,1,11,249,80,144,41,55,40,39, -80,144,41,8,40,42,27,248,22,155,16,2,58,28,248,22,139,16,23,194,2, -248,22,142,16,23,194,1,28,248,22,138,16,23,194,2,90,144,42,11,89,146, -42,39,11,248,22,135,16,249,22,140,16,250,80,144,49,43,42,248,22,155,16, -2,56,11,11,248,22,155,16,2,57,86,95,23,195,1,23,194,1,248,22,142, -16,249,22,140,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22,155, -16,2,56,23,197,1,10,28,23,193,2,248,22,142,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, -35,80,144,8,36,47,40,249,22,31,11,80,144,8,38,46,40,22,145,15,10, -22,146,15,10,22,147,15,10,22,148,15,11,22,149,15,11,22,153,15,10,22, -152,15,11,22,154,15,10,22,151,15,10,22,155,15,10,22,150,15,11,22,156, -15,10,22,157,15,10,22,158,15,10,22,159,15,11,22,160,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,132, -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,190,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,186,15,23,196,1,28,248,22,139,16,23, -194,2,192,249,22,140,16,23,195,1,27,247,80,144,43,54,42,28,23,193,2, -192,86,94,23,193,1,247,22,156,16,28,248,22,142,8,23,195,2,27,248,22, -187,15,23,196,1,28,248,22,139,16,23,194,2,192,249,22,140,16,23,195,1, -27,247,80,144,43,54,42,28,23,193,2,192,86,94,23,193,1,247,22,156,16, -28,248,22,178,15,23,195,2,28,248,22,139,16,23,195,2,193,249,22,140,16, -23,196,1,27,247,80,144,42,54,42,28,23,193,2,192,86,94,23,193,1,247, -22,156,16,193,27,248,22,155,16,2,55,28,248,22,139,16,23,194,2,248,22, -142,16,23,194,1,28,248,22,138,16,23,194,2,90,144,42,11,89,146,42,39, -11,248,22,135,16,249,22,140,16,250,80,144,49,43,42,248,22,155,16,2,56, -11,11,248,22,155,16,2,57,86,95,23,195,1,23,194,1,248,22,142,16,249, -22,140,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22,155,16,2, -56,23,197,1,10,28,23,193,2,248,22,142,16,23,194,1,11,28,248,22,139, -16,23,195,2,193,249,22,140,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,156,16,28,248, -22,139,16,23,195,2,248,22,142,16,23,195,1,28,248,22,138,16,23,195,2, -90,144,42,11,89,146,42,39,11,248,22,135,16,249,22,140,16,250,80,144,48, -43,42,248,22,155,16,2,56,11,11,248,22,155,16,2,57,86,95,23,195,1, -23,194,1,248,22,142,16,249,22,140,16,23,200,1,23,196,1,27,250,80,144, -43,43,42,248,22,155,16,2,56,23,198,1,10,28,23,193,2,248,22,142,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,168,20,23,199,2,28,248,22,153,7,23,194,2,27,248,22,186, -15,23,195,1,28,248,22,139,16,23,194,2,192,249,22,140,16,23,195,1,27, -247,80,144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22,156,16,28, -248,22,142,8,23,194,2,27,248,22,187,15,23,195,1,28,248,22,139,16,23, -194,2,192,249,22,140,16,23,195,1,27,247,80,144,46,54,42,28,23,193,2, -192,86,94,23,193,1,247,22,156,16,28,248,22,178,15,23,194,2,28,248,22, -139,16,23,194,2,192,249,22,140,16,23,195,1,27,247,80,144,45,54,42,28, -23,193,2,192,86,94,23,193,1,247,22,156,16,192,27,248,22,169,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,168,20,23,197,2,27,248,22,169,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,168,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22,169, -20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1,248, -22,169,20,23,198,1,249,22,94,23,199,2,27,248,22,169,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,168,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22, -169,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1, -248,22,169,20,23,198,1,249,22,94,23,196,2,27,248,22,169,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,168,20,23,197,2,27,248,22,169,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,168,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22,169,20, -23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1,248,22, -169,20,23,198,1,249,22,94,23,199,2,27,248,22,169,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,168,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22,169, -20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1,248, -22,169,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,155,16,2,58,28,248,22,139,16, -23,194,2,248,22,142,16,23,194,1,28,248,22,138,16,23,194,2,90,144,42, -11,89,146,42,39,11,248,22,135,16,249,22,140,16,250,80,144,49,43,42,248, -22,155,16,2,56,11,11,248,22,155,16,2,57,86,95,23,195,1,23,194,1, -248,22,142,16,249,22,140,16,23,199,1,23,196,1,27,250,80,144,44,43,42, -248,22,155,16,2,56,23,197,1,10,28,23,193,2,248,22,142,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,132,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,132, -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,186,15,23,195,1,28,248,22,139,16,23,194,2,192,249,22,140, -16,23,195,1,27,247,80,144,47,54,42,28,23,193,2,192,86,94,23,193,1, -247,22,156,16,28,248,22,142,8,23,194,2,27,248,22,187,15,23,195,1,28, -248,22,139,16,23,194,2,192,249,22,140,16,23,195,1,27,247,80,144,47,54, -42,28,23,193,2,192,86,94,23,193,1,247,22,156,16,28,248,22,178,15,23, -194,2,28,248,22,139,16,23,194,2,192,249,22,140,16,23,195,1,27,247,80, -144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22,156,16,192,250,22, -94,248,22,90,11,28,247,22,163,16,28,247,22,164,16,248,22,90,250,22,132, -16,248,22,155,16,2,61,250,22,158,2,23,204,2,2,59,247,22,171,8,2, -60,9,9,28,247,22,164,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,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,135,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,178,15,23, -194,2,28,248,22,191,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,135,16, -23,197,1,86,95,23,195,1,23,194,1,28,248,22,178,15,23,194,2,28,248, -22,191,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,135,16,23,197,1,86, -95,23,195,1,23,194,1,28,248,22,178,15,23,194,2,28,248,22,191,15,23, -194,2,249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11,9,222,11, +2,46,23,198,1,86,95,28,28,248,22,178,15,23,195,2,10,28,248,22,153, +7,23,195,2,28,248,22,137,16,23,195,2,10,248,22,138,16,23,195,2,11, +12,250,22,182,11,23,196,2,2,48,23,197,2,28,248,22,137,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, +182,11,23,196,1,2,54,23,197,1,86,94,28,28,248,22,178,15,23,194,2, +10,28,248,22,153,7,23,194,2,28,248,22,137,16,23,194,2,10,248,22,138, +16,23,194,2,11,12,250,22,182,11,2,15,2,48,23,196,2,28,248,22,137, +16,23,194,2,12,251,22,184,11,2,15,2,53,2,46,23,197,1,86,97,28, +28,248,22,178,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248,22,137, +16,23,196,2,10,248,22,138,16,23,196,2,11,12,250,22,182,11,2,15,2, +48,23,198,2,28,248,22,137,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,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,178,15,23,194,2,10,28,248,22,153, +7,23,194,2,28,248,22,137,16,23,194,2,10,248,22,138,16,23,194,2,11, +12,250,22,182,11,2,17,2,48,23,196,2,28,248,22,137,16,23,194,2,12, +251,22,184,11,2,17,2,53,2,46,23,197,1,86,99,28,28,248,22,178,15, +23,197,2,10,28,248,22,153,7,23,197,2,28,248,22,137,16,23,197,2,10, +248,22,138,16,23,197,2,11,12,250,22,182,11,2,17,2,48,23,199,2,28, +248,22,137,16,23,197,2,12,251,22,184,11,2,17,2,53,2,46,23,200,2, +28,28,248,22,178,15,23,198,2,10,28,248,22,153,7,23,198,2,28,248,22, +137,16,23,198,2,10,248,22,138,16,23,198,2,11,12,250,22,182,11,2,17, +2,48,23,200,2,28,248,22,137,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,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,155,16,2,55,28,248,22,139, +16,23,194,2,248,22,142,16,23,194,1,28,248,22,138,16,23,194,2,90,144, +42,11,89,146,42,39,11,248,22,135,16,249,22,140,16,250,80,144,49,43,42, +248,22,155,16,2,56,11,11,248,22,155,16,2,57,86,95,23,195,1,23,194, +1,248,22,142,16,249,22,140,16,23,199,1,23,196,1,27,250,80,144,44,43, +42,248,22,155,16,2,56,23,197,1,10,28,23,193,2,248,22,142,16,23,194, +1,11,249,80,144,41,55,40,39,80,144,41,8,40,42,27,248,22,155,16,2, +58,28,248,22,139,16,23,194,2,248,22,142,16,23,194,1,28,248,22,138,16, +23,194,2,90,144,42,11,89,146,42,39,11,248,22,135,16,249,22,140,16,250, +80,144,49,43,42,248,22,155,16,2,56,11,11,248,22,155,16,2,57,86,95, +23,195,1,23,194,1,248,22,142,16,249,22,140,16,23,199,1,23,196,1,27, +250,80,144,44,43,42,248,22,155,16,2,56,23,197,1,10,28,23,193,2,248, +22,142,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,35,80,144,8,36,47,40,249,22,31,11,80, +144,8,38,46,40,22,145,15,10,22,146,15,10,22,147,15,10,22,148,15,11, +22,149,15,11,22,153,15,10,22,152,15,11,22,154,15,10,22,151,15,10,22, +155,15,10,22,150,15,11,22,156,15,10,22,157,15,10,22,158,15,10,22,159, +15,11,22,160,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,132,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,190, +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,186,15, +23,196,1,28,248,22,139,16,23,194,2,192,249,22,140,16,23,195,1,27,247, +80,144,43,54,42,28,23,193,2,192,86,94,23,193,1,247,22,156,16,28,248, +22,142,8,23,195,2,27,248,22,187,15,23,196,1,28,248,22,139,16,23,194, +2,192,249,22,140,16,23,195,1,27,247,80,144,43,54,42,28,23,193,2,192, +86,94,23,193,1,247,22,156,16,28,248,22,178,15,23,195,2,28,248,22,139, +16,23,195,2,193,249,22,140,16,23,196,1,27,247,80,144,42,54,42,28,23, +193,2,192,86,94,23,193,1,247,22,156,16,193,27,248,22,155,16,2,55,28, +248,22,139,16,23,194,2,248,22,142,16,23,194,1,28,248,22,138,16,23,194, +2,90,144,42,11,89,146,42,39,11,248,22,135,16,249,22,140,16,250,80,144, +49,43,42,248,22,155,16,2,56,11,11,248,22,155,16,2,57,86,95,23,195, +1,23,194,1,248,22,142,16,249,22,140,16,23,199,1,23,196,1,27,250,80, +144,44,43,42,248,22,155,16,2,56,23,197,1,10,28,23,193,2,248,22,142, +16,23,194,1,11,28,248,22,139,16,23,195,2,193,249,22,140,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,156,16,28,248,22,139,16,23,195,2,248,22,142,16,23,195, +1,28,248,22,138,16,23,195,2,90,144,42,11,89,146,42,39,11,248,22,135, +16,249,22,140,16,250,80,144,48,43,42,248,22,155,16,2,56,11,11,248,22, +155,16,2,57,86,95,23,195,1,23,194,1,248,22,142,16,249,22,140,16,23, +200,1,23,196,1,27,250,80,144,43,43,42,248,22,155,16,2,56,23,198,1, +10,28,23,193,2,248,22,142,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,169,20,23,199,2,28,248,22, +153,7,23,194,2,27,248,22,186,15,23,195,1,28,248,22,139,16,23,194,2, +192,249,22,140,16,23,195,1,27,247,80,144,46,54,42,28,23,193,2,192,86, +94,23,193,1,247,22,156,16,28,248,22,142,8,23,194,2,27,248,22,187,15, +23,195,1,28,248,22,139,16,23,194,2,192,249,22,140,16,23,195,1,27,247, +80,144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22,156,16,28,248, +22,178,15,23,194,2,28,248,22,139,16,23,194,2,192,249,22,140,16,23,195, +1,27,247,80,144,45,54,42,28,23,193,2,192,86,94,23,193,1,247,22,156, +16,192,27,248,22,170,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,169,20,23,197,2,27, +248,22,170,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,169,20,23,197,2,249,80,144,49, +8,44,42,23,204,1,248,22,170,20,23,198,1,249,22,94,23,202,2,249,80, +144,49,8,44,42,23,204,1,248,22,170,20,23,198,1,249,22,94,23,199,2, +27,248,22,170,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,169,20,23,197,2,249,80,144, +49,8,44,42,23,204,1,248,22,170,20,23,198,1,249,22,94,23,202,2,249, +80,144,49,8,44,42,23,204,1,248,22,170,20,23,198,1,249,22,94,23,196, +2,27,248,22,170,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,169,20,23,197,2,27,248, +22,170,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,169,20,23,197,2,249,80,144,49,8, +44,42,23,204,1,248,22,170,20,23,198,1,249,22,94,23,202,2,249,80,144, +49,8,44,42,23,204,1,248,22,170,20,23,198,1,249,22,94,23,199,2,27, +248,22,170,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,169,20,23,197,2,249,80,144,49, +8,44,42,23,204,1,248,22,170,20,23,198,1,249,22,94,23,202,2,249,80, +144,49,8,44,42,23,204,1,248,22,170,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, +155,16,2,58,28,248,22,139,16,23,194,2,248,22,142,16,23,194,1,28,248, +22,138,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,135,16,249,22, +140,16,250,80,144,49,43,42,248,22,155,16,2,56,11,11,248,22,155,16,2, +57,86,95,23,195,1,23,194,1,248,22,142,16,249,22,140,16,23,199,1,23, +196,1,27,250,80,144,44,43,42,248,22,155,16,2,56,23,197,1,10,28,23, +193,2,248,22,142,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,132,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,132,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,186,15,23,195,1,28,248,22, +139,16,23,194,2,192,249,22,140,16,23,195,1,27,247,80,144,47,54,42,28, +23,193,2,192,86,94,23,193,1,247,22,156,16,28,248,22,142,8,23,194,2, +27,248,22,187,15,23,195,1,28,248,22,139,16,23,194,2,192,249,22,140,16, +23,195,1,27,247,80,144,47,54,42,28,23,193,2,192,86,94,23,193,1,247, +22,156,16,28,248,22,178,15,23,194,2,28,248,22,139,16,23,194,2,192,249, +22,140,16,23,195,1,27,247,80,144,46,54,42,28,23,193,2,192,86,94,23, +193,1,247,22,156,16,192,250,22,94,248,22,90,11,28,247,22,163,16,28,247, +22,164,16,248,22,90,250,22,132,16,248,22,155,16,2,61,250,22,158,2,23, +204,2,2,59,247,22,171,8,2,60,9,9,28,247,22,164,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,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,135,16,23,197,1,86,95,23,195,1, 23,194,1,28,248,22,178,15,23,194,2,28,248,22,191,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,135,16,23,198,2,86,95,23,195,1,23,194,1,28,248,22,178,15,23, -194,2,28,248,22,191,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,135,16, -23,197,1,86,95,23,195,1,23,194,1,28,248,22,178,15,23,194,2,28,248, -22,191,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,135,16,23,197,1,86, -95,23,195,1,23,194,1,28,248,22,178,15,23,194,2,28,248,22,191,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,135,16,23,197,1,86,95,23,195,1, +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,135,16,23,197,1,86,95,23,195,1,23,194,1,28, +248,22,178,15,23,194,2,28,248,22,191,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,135,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,178,15, +23,194,2,28,248,22,191,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,135, +16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,178,15,23,194,2,28, +248,22,191,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,135,16,23,198,2,86,95,23,195,1, 23,194,1,28,248,22,178,15,23,194,2,28,248,22,191,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,190,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,176,14,39,248,22,169,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,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,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,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,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, -168,20,195,10,249,22,169,9,2,65,248,22,168,20,195,28,27,248,22,102,194, -28,248,22,178,15,193,10,28,248,22,153,7,193,28,248,22,137,16,193,10,248, -22,138,16,193,11,27,248,22,88,248,22,104,195,28,192,192,248,22,184,16,248, -22,111,195,11,11,11,11,28,248,22,191,15,249,22,132,16,23,196,2,23,198, -2,27,248,22,68,248,22,182,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,175,16,248,22,111,23,198,2,247,22,171, -8,27,248,22,142,16,249,22,140,16,248,22,102,23,200,2,23,198,1,28,249, -22,169,9,248,22,168,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, -145,16,23,196,1,28,249,22,169,9,248,22,168,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,168,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,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,135,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,169,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,35,80,144,8,40,47,40,249,22,31,11,80,144,8,42,46, -40,22,145,15,10,22,146,15,10,22,147,15,10,22,148,15,11,22,149,15,11, -22,153,15,10,22,152,15,11,22,154,15,10,22,151,15,10,22,155,15,10,22, -150,15,11,22,156,15,10,22,157,15,10,22,158,15,10,22,159,15,11,22,160, -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,49,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,173,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, -86,94,23,193,1,249,22,7,23,197,1,23,198,1,90,144,42,11,89,146,42, -39,11,248,22,135,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,173,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,86,94,23,193,1,249,22,7,23,197,1,23,196,1,90,144,42,11,89, -146,42,39,11,248,22,135,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,168,20,23,197,2,250,22,94,249, -22,2,22,129,2,250,22,158,2,248,22,168,20,23,204,2,23,202,2,9,250, -22,158,2,248,22,168,20,23,202,2,11,9,27,248,22,169,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, -168,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22,168, -20,23,202,2,23,206,2,9,250,22,158,2,248,22,168,20,23,200,2,11,9, -249,80,144,48,8,48,42,23,203,1,248,22,169,20,23,199,1,27,248,80,144, -45,8,30,42,248,22,168,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,169,20,23,200,1,249,22,94,247,22,159,16,249,80,144,47,8, -48,42,23,202,1,248,22,169,20,23,198,1,27,248,80,144,41,8,30,42,248, -22,168,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,169,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,168,20,23,195, -2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22,168,20,23,202,2, -23,207,2,9,250,22,158,2,248,22,168,20,23,200,2,11,9,249,80,144,49, -8,48,42,23,204,1,248,22,169,20,23,199,1,27,248,80,144,46,8,30,42, -248,22,168,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, -169,20,23,200,1,249,22,94,247,22,159,16,249,80,144,48,8,48,42,23,203, -1,248,22,169,20,23,198,1,249,22,94,247,22,159,16,27,248,22,169,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,168,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2, -248,22,168,20,23,202,2,23,205,2,9,250,22,158,2,248,22,168,20,23,200, -2,11,9,249,80,144,47,8,48,42,23,202,1,248,22,169,20,23,199,1,27, -248,80,144,44,8,30,42,248,22,168,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,169,20,23,200,1,249,22,94,247,22,159,16,249,80, -144,46,8,48,42,23,201,1,248,22,169,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,168,20,195,28,248,22,178,15,193,248,22,182,15,193,192,250, -22,91,27,248,22,168,20,23,198,2,28,248,22,178,15,193,248,22,182,15,193, -192,2,67,248,2,150,2,248,22,169,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,168,20,23,197,2,249, -2,154,2,23,197,1,248,22,169,20,23,199,1,249,2,154,2,23,195,1,248, -22,169,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,132,16,202,199,200,86,95,23,201,1,23,198,1, -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,178,15,23,202,2,248,22,182,15,23,202,1, -23,201,1,250,22,176,7,28,248,22,178,15,23,205,2,248,22,182,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,159,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,159,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,178,15,23,195,2,249,22, -132,16,23,196,1,23,199,2,248,22,132,2,23,195,1,28,28,248,22,178,15, -248,22,168,20,23,204,2,248,22,191,15,23,194,2,10,27,250,22,1,22,132, -16,23,197,1,23,202,2,28,28,248,22,88,23,200,2,10,248,22,191,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,178,15,202,248,22,182,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,86,94,23,195,1,11,28,23,193,2,250,80,144,48,8,32,42, -198,23,196,1,23,15,11,2,28,200,249,22,132,16,194,202,192,26,8,80,144, -50,8,49,42,204,205,206,23,15,23,16,23,17,248,22,169,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,169,20,23,19,23,19,26,8,80,144,49,8,49,42,203,204,205,206, -23,15,23,16,248,22,169,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,178, -15,195,248,22,182,15,195,194,27,27,247,22,160,16,28,248,22,88,23,194,2, -9,28,248,22,81,23,194,2,28,248,22,149,2,248,22,168,20,23,195,2,250, -22,94,249,22,2,22,129,2,250,22,158,2,248,22,168,20,23,202,2,23,203, -2,9,250,22,158,2,248,22,168,20,23,200,2,11,9,249,80,144,49,8,48, -42,23,200,1,248,22,169,20,23,199,1,27,248,80,144,46,8,30,42,248,22, -168,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,169,20, -23,200,1,249,22,94,247,22,159,16,249,80,144,48,8,48,42,23,199,1,248, -22,169,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,188,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, +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,135,16,23,197,1,86,95,23,195,1,23,194,1,28, +248,22,178,15,23,194,2,28,248,22,191,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,135,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,178,15, +23,194,2,28,248,22,191,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,135, +16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,178,15,23,194,2,28, +248,22,191,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,190,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,176,14,39,248,22,170,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,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,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,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,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,169,20,195,10,249,22,169,9,2,65,248,22, +169,20,195,28,27,248,22,102,194,28,248,22,178,15,193,10,28,248,22,153,7, +193,28,248,22,137,16,193,10,248,22,138,16,193,11,27,248,22,88,248,22,104, +195,28,192,192,248,22,184,16,248,22,111,195,11,11,11,11,28,248,22,191,15, +249,22,132,16,23,196,2,23,198,2,27,248,22,68,248,22,182,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,175,16, +248,22,111,23,198,2,247,22,171,8,27,248,22,142,16,249,22,140,16,248,22, +102,23,200,2,23,198,1,28,249,22,169,9,248,22,169,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,145,16,23,196,1,28,249,22,169,9,248,22, +169,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,169,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,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,135,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,170,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,35,80,144,8,40,47,40, +249,22,31,11,80,144,8,42,46,40,22,145,15,10,22,146,15,10,22,147,15, +10,22,148,15,11,22,149,15,11,22,153,15,10,22,152,15,11,22,154,15,10, +22,151,15,10,22,155,15,10,22,150,15,11,22,156,15,10,22,157,15,10,22, +158,15,10,22,159,15,11,22,160,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,49, +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,173,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,86,94,23,193,1,249,22,7,23,197,1,23, +198,1,90,144,42,11,89,146,42,39,11,248,22,135,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,173,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,86,94,23,193,1,249,22,7,23,197, +1,23,196,1,90,144,42,11,89,146,42,39,11,248,22,135,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, +169,20,23,197,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22,169, +20,23,204,2,23,202,2,9,250,22,158,2,248,22,169,20,23,202,2,11,9, +27,248,22,170,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,169,20,23,195,2,250,22,94,249,22,2,22, +129,2,250,22,158,2,248,22,169,20,23,202,2,23,206,2,9,250,22,158,2, +248,22,169,20,23,200,2,11,9,249,80,144,48,8,48,42,23,203,1,248,22, +170,20,23,199,1,27,248,80,144,45,8,30,42,248,22,169,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,170,20,23,200,1,249,22,94, +247,22,159,16,249,80,144,47,8,48,42,23,202,1,248,22,170,20,23,198,1, +27,248,80,144,41,8,30,42,248,22,169,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,170, +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,169,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22, +158,2,248,22,169,20,23,202,2,23,207,2,9,250,22,158,2,248,22,169,20, +23,200,2,11,9,249,80,144,49,8,48,42,23,204,1,248,22,170,20,23,199, +1,27,248,80,144,46,8,30,42,248,22,169,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,170,20,23,200,1,249,22,94,247,22,159,16, +249,80,144,48,8,48,42,23,203,1,248,22,170,20,23,198,1,249,22,94,247, +22,159,16,27,248,22,170,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,169,20,23,195,2,250,22,94,249, +22,2,22,129,2,250,22,158,2,248,22,169,20,23,202,2,23,205,2,9,250, +22,158,2,248,22,169,20,23,200,2,11,9,249,80,144,47,8,48,42,23,202, +1,248,22,170,20,23,199,1,27,248,80,144,44,8,30,42,248,22,169,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,170,20,23,200,1, +249,22,94,247,22,159,16,249,80,144,46,8,48,42,23,201,1,248,22,170,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,169,20,195,28,248,22,178, +15,193,248,22,182,15,193,192,250,22,91,27,248,22,169,20,23,198,2,28,248, +22,178,15,193,248,22,182,15,193,192,2,67,248,2,150,2,248,22,170,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,169,20,23,197,2,249,2,154,2,23,197,1,248,22,170,20,23,199, +1,249,2,154,2,23,195,1,248,22,170,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,132,16,202,199, +200,86,95,23,201,1,23,198,1,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,178,15,23, +202,2,248,22,182,15,23,202,1,23,201,1,250,22,176,7,28,248,22,178,15, +23,205,2,248,22,182,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,159,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,159,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,178,15,23,195,2,249,22,132,16,23,196,1,23,199,2,248,22,132,2, +23,195,1,28,28,248,22,178,15,248,22,169,20,23,204,2,248,22,191,15,23, +194,2,10,27,250,22,1,22,132,16,23,197,1,23,202,2,28,28,248,22,88, +23,200,2,10,248,22,191,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,178,15,202,248,22,182,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,86,94,23,195,1,11,28,23, +193,2,250,80,144,48,8,32,42,198,23,196,1,23,15,11,2,28,200,249,22, +132,16,194,202,192,26,8,80,144,50,8,49,42,204,205,206,23,15,23,16,23, +17,248,22,170,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,170,20,23,19,23,19,26,8,80, +144,49,8,49,42,203,204,205,206,23,15,23,16,248,22,170,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,178,15,195,248,22,182,15,195,194,27,27,247,22, +160,16,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248,22,149, +2,248,22,169,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2, +248,22,169,20,23,202,2,23,203,2,9,250,22,158,2,248,22,169,20,23,200, +2,11,9,249,80,144,49,8,48,42,23,200,1,248,22,170,20,23,199,1,27, +248,80,144,46,8,30,42,248,22,169,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,170,20,23,200,1,249,22,94,247,22,159,16,249,80, +144,48,8,48,42,23,199,1,248,22,170,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,188,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,184,11,2,37,2,69,2,70,202,192,28,248,22,179,15,198, +248,22,180,15,198,247,22,181,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,188,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,184,11,2,37,2,69,2,70, +202,192,28,248,22,179,15,198,248,22,180,15,198,247,22,181,15,250,2,158,2, +196,197,195,248,22,190,15,27,250,22,132,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,137,16,23,196, +2,249,22,132,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,190,15,249,22,132,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,184,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,179,15,195,249,22,132,16,196,194,192,27,247,22, +161,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,162,16,11,86,95,28,28,248, +22,179,15,23,194,2,10,28,248,22,178,15,23,194,2,10,28,248,22,153,7, +23,194,2,28,248,22,137,16,23,194,2,10,248,22,138,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,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,135,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,188,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,184,11,2,37,2,69,2,70,201,192, +28,248,22,179,15,197,248,22,180,15,197,247,22,181,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,188,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,184,11,2,37,2,69,2,70,204,192,28,248, +22,179,15,200,248,22,180,15,200,247,22,181,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,188,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,184,11,2,37,2,69, +2,70,204,192,28,248,22,179,15,200,248,22,180,15,200,247,22,181,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,188,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,184,11,2,37, -2,69,2,70,202,192,28,248,22,179,15,198,248,22,180,15,198,247,22,181,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,188,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,184,11,2,37,2,69,2,70,202,192,28,248,22,179,15,198,248, -22,180,15,198,247,22,181,15,250,2,158,2,196,197,195,248,22,190,15,27,250, -22,132,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,137,16,23,196,2,249,22,132,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,190,15,249,22,132,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,184,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,179, -15,195,249,22,132,16,196,194,192,27,247,22,161,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,162,16,11,86,95,28,28,248,22,179,15,23,194,2,10,28,248, -22,178,15,23,194,2,10,28,248,22,153,7,23,194,2,28,248,22,137,16,23, -194,2,10,248,22,138,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,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,135,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,188,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,184,11,2,37,2,69,2,70,201,192,28,248,22,179,15,197,248,22,180, -15,197,247,22,181,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,188,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, -184,11,2,37,2,69,2,70,204,192,28,248,22,179,15,200,248,22,180,15,200, -247,22,181,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,188, -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,184,11,2,37,2,69,2,70,204,192,28,248,22,179,15, -200,248,22,180,15,200,247,22,181,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,188,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,184,11,2,37,2,69,2,70,205,192,28,248,22, -179,15,201,248,22,180,15,201,247,22,181,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,188,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,184,11,2,37,2,69,2, -70,205,192,28,248,22,179,15,201,248,22,180,15,201,247,22,181,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,179,15, -23,199,2,10,28,248,22,178,15,23,199,2,10,28,248,22,153,7,23,199,2, -28,248,22,137,16,23,199,2,10,248,22,138,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,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,135,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,184,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,188,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,184,11,2, -37,2,69,2,70,23,17,192,28,248,22,179,15,205,248,22,180,15,205,247,22, -181,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,188,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,184,11,2,37,2,69,2,70,23,17,192,28,248,22,179,15,205, -248,22,180,15,205,247,22,181,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,179,15,195,249,22,132,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,188,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,184,11,2,37,2,69,2,70,202,192,28,248,22,179,15,198,248,22, -180,15,198,247,22,181,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,188,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,184, -11,2,37,2,69,2,70,202,192,28,248,22,179,15,198,248,22,180,15,198,247, -22,181,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,188,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,184,11,2,37,2,69,2,70,203,192, -28,248,22,179,15,199,248,22,180,15,199,247,22,181,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,188,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,184,11,2,37,2,69,2,70,203,192,28,248,22,179, -15,199,248,22,180,15,199,247,22,181,15,251,2,169,2,198,199,200,196,90,144, -41,11,89,146,41,39,11,86,95,28,28,248,22,179,15,23,196,2,10,28,248, -22,178,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248,22,137,16,23, -196,2,10,248,22,138,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,135,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, -184,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,179,15,195,249,22,132,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,188,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,184,11,2,37,2,69,2,70,200,192,28,248,22,179,15,196,248, -22,180,15,196,247,22,181,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,188,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,184,11,2,37,2,69,2,70,202,192,28,248,22,179,15,198,248,22, -180,15,198,247,22,181,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,188,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, +2,69,2,70,205,192,28,248,22,179,15,201,248,22,180,15,201,247,22,181,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,188,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,184,11,2,37,2,69,2,70,205,192,28,248,22,179,15,201,248,22,180, +15,201,247,22,181,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,179,15,23,199,2,10,28,248,22,178,15,23,199,2, +10,28,248,22,153,7,23,199,2,28,248,22,137,16,23,199,2,10,248,22,138, +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, +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,135,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,184,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, +188,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,184,11,2,37,2,69,2,70,23,17,192,28,248,22,179, +15,205,248,22,180,15,205,247,22,181,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,188,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,184,11,2,37,2,69,2,70, +23,17,192,28,248,22,179,15,205,248,22,180,15,205,247,22,181,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,179, +15,195,249,22,132,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,188,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,184,11,2,37,2,69,2,70,202, +192,28,248,22,179,15,198,248,22,180,15,198,247,22,181,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,188,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,184,11,2,37,2,69,2,70,202,192,28,248,22, -179,15,198,248,22,180,15,198,247,22,181,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,179,15,23,196,2,10,28,248,22,178,15, -23,196,2,10,28,248,22,153,7,23,196,2,28,248,22,137,16,23,196,2,10, -248,22,138,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,135,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,184,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,179,15,195,249,22,132,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,139,16,23,194,2,248,22,142,16,23,194,1,28,248,22,138,16,23, -194,2,90,144,42,11,89,146,42,39,11,248,22,135,16,249,22,140,16,250,80, -144,50,43,42,248,22,155,16,2,56,11,11,248,22,155,16,2,57,86,95,23, -195,1,23,194,1,248,22,142,16,249,22,140,16,23,199,1,23,196,1,27,250, -80,144,45,43,42,248,22,155,16,2,56,23,197,1,10,28,23,193,2,248,22, -142,16,23,194,1,11,28,23,193,2,249,22,80,248,22,142,16,249,22,140,16, -23,198,1,247,22,156,16,27,248,22,169,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,142,16,249,22,140,16,23,198,1,247,22,156,16,248,80,144,47,8, -50,42,248,22,169,20,23,198,1,86,94,23,193,1,248,80,144,45,8,50,42, -248,22,169,20,23,196,1,86,94,23,193,1,27,248,22,169,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,142,16,249,22,140,16,23,198,1,247,22,156,16, -248,80,144,45,8,50,42,248,22,169,20,23,198,1,86,94,23,193,1,248,80, -144,43,8,50,42,248,22,169,20,23,196,1,28,248,22,88,23,195,2,9,27, -27,248,22,81,23,197,2,28,248,22,139,16,23,194,2,248,22,142,16,23,194, -1,28,248,22,138,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,135, -16,249,22,140,16,250,80,144,50,43,42,248,22,155,16,2,56,11,11,248,22, -155,16,2,57,86,95,23,195,1,23,194,1,248,22,142,16,249,22,140,16,23, -199,1,23,196,1,27,250,80,144,45,43,42,248,22,155,16,2,56,23,197,1, -10,28,23,193,2,248,22,142,16,23,194,1,11,28,23,193,2,249,22,80,248, -22,142,16,249,22,140,16,23,198,1,247,22,156,16,27,248,22,169,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,142,16,249,22,140,16,23,198,1,247,22, -156,16,248,80,144,47,8,51,42,248,22,169,20,23,198,1,86,94,23,193,1, -248,80,144,45,8,51,42,248,22,169,20,23,196,1,86,94,23,193,1,27,248, -22,169,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,142,16,249,22,140,16, -23,198,1,247,22,156,16,248,80,144,45,8,51,42,248,22,169,20,23,198,1, -86,94,23,193,1,248,80,144,43,8,51,42,248,22,169,20,23,196,1,27,248, -22,155,16,2,58,28,248,22,139,16,23,194,2,248,22,142,16,23,194,1,28, -248,22,138,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,135,16,249, -22,140,16,250,80,144,49,43,42,248,22,155,16,2,56,11,11,248,22,155,16, -2,57,86,95,23,195,1,23,194,1,248,22,142,16,249,22,140,16,23,199,1, -23,196,1,27,250,80,144,44,43,42,248,22,155,16,2,56,23,197,1,10,28, -23,193,2,248,22,142,16,23,194,1,11,28,248,22,88,23,195,2,9,27,27, -248,22,81,23,197,2,28,248,22,139,16,23,194,2,248,22,142,16,23,194,1, -28,248,22,138,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,135,16, -249,22,140,16,250,80,144,50,43,42,248,22,155,16,2,56,11,11,248,22,155, -16,2,57,86,95,23,195,1,23,194,1,248,22,142,16,249,22,140,16,23,199, -1,23,196,1,27,250,80,144,45,43,42,248,22,155,16,2,56,23,197,1,10, -28,23,193,2,248,22,142,16,23,194,1,11,28,23,193,2,249,22,80,248,22, -142,16,249,22,140,16,23,198,1,247,22,156,16,27,248,22,169,20,23,199,1, -28,248,22,88,23,194,2,9,27,27,248,22,81,23,196,2,28,248,22,139,16, +179,15,198,248,22,180,15,198,247,22,181,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,188,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,184, +11,2,37,2,69,2,70,203,192,28,248,22,179,15,199,248,22,180,15,199,247, +22,181,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,188,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,184,11,2,37,2, +69,2,70,203,192,28,248,22,179,15,199,248,22,180,15,199,247,22,181,15,251, +2,169,2,198,199,200,196,90,144,41,11,89,146,41,39,11,86,95,28,28,248, +22,179,15,23,196,2,10,28,248,22,178,15,23,196,2,10,28,248,22,153,7, +23,196,2,28,248,22,137,16,23,196,2,10,248,22,138,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,135,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,184,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,179,15,195,249, +22,132,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,188,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,184,11,2,37,2,69,2,70, +200,192,28,248,22,179,15,196,248,22,180,15,196,247,22,181,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,188,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,184,11,2,37,2,69,2,70,202, +192,28,248,22,179,15,198,248,22,180,15,198,247,22,181,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,188,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,184,11,2,37, +2,69,2,70,202,192,28,248,22,179,15,198,248,22,180,15,198,247,22,181,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,179,15, +23,196,2,10,28,248,22,178,15,23,196,2,10,28,248,22,153,7,23,196,2, +28,248,22,137,16,23,196,2,10,248,22,138,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,135,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,184,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,179,15,195,249,22,132,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,139,16,23,194,2,248,22,142,16, +23,194,1,28,248,22,138,16,23,194,2,90,144,42,11,89,146,42,39,11,248, +22,135,16,249,22,140,16,250,80,144,50,43,42,248,22,155,16,2,56,11,11, +248,22,155,16,2,57,86,95,23,195,1,23,194,1,248,22,142,16,249,22,140, +16,23,199,1,23,196,1,27,250,80,144,45,43,42,248,22,155,16,2,56,23, +197,1,10,28,23,193,2,248,22,142,16,23,194,1,11,28,23,193,2,249,22, +80,248,22,142,16,249,22,140,16,23,198,1,247,22,156,16,27,248,22,170,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,142,16,249,22,140,16,23,198,1, +247,22,156,16,248,80,144,47,8,50,42,248,22,170,20,23,198,1,86,94,23, +193,1,248,80,144,45,8,50,42,248,22,170,20,23,196,1,86,94,23,193,1, +27,248,22,170,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,142,16,249,22, +140,16,23,198,1,247,22,156,16,248,80,144,45,8,50,42,248,22,170,20,23, +198,1,86,94,23,193,1,248,80,144,43,8,50,42,248,22,170,20,23,196,1, +28,248,22,88,23,195,2,9,27,27,248,22,81,23,197,2,28,248,22,139,16, 23,194,2,248,22,142,16,23,194,1,28,248,22,138,16,23,194,2,90,144,42, -11,89,146,42,39,11,248,22,135,16,249,22,140,16,250,80,144,54,43,42,248, +11,89,146,42,39,11,248,22,135,16,249,22,140,16,250,80,144,50,43,42,248, 22,155,16,2,56,11,11,248,22,155,16,2,57,86,95,23,195,1,23,194,1, -248,22,142,16,249,22,140,16,23,199,1,23,196,1,27,250,80,144,49,43,42, +248,22,142,16,249,22,140,16,23,199,1,23,196,1,27,250,80,144,45,43,42, 248,22,155,16,2,56,23,197,1,10,28,23,193,2,248,22,142,16,23,194,1, 11,28,23,193,2,249,22,80,248,22,142,16,249,22,140,16,23,198,1,247,22, -156,16,27,248,22,169,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,142,16, -249,22,140,16,23,198,1,247,22,156,16,248,80,144,51,8,53,42,248,22,169, -20,23,198,1,86,94,23,193,1,248,80,144,49,8,53,42,248,22,169,20,23, -196,1,86,94,23,193,1,27,248,22,169,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,142,16,249,22,140,16,23,198,1,247,22,156,16,248,80,144,49,8, -53,42,248,22,169,20,23,198,1,86,94,23,193,1,248,80,144,47,8,53,42, -248,22,169,20,23,196,1,86,94,23,193,1,27,248,22,169,20,23,197,1,28, -248,22,88,23,194,2,9,27,27,248,22,81,23,196,2,28,248,22,139,16,23, +156,16,27,248,22,170,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,142,16, +249,22,140,16,23,198,1,247,22,156,16,248,80,144,47,8,51,42,248,22,170, +20,23,198,1,86,94,23,193,1,248,80,144,45,8,51,42,248,22,170,20,23, +196,1,86,94,23,193,1,27,248,22,170,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,142,16,249,22,140,16,23,198,1,247,22,156,16,248,80,144,45,8, +51,42,248,22,170,20,23,198,1,86,94,23,193,1,248,80,144,43,8,51,42, +248,22,170,20,23,196,1,27,248,22,155,16,2,58,28,248,22,139,16,23,194, +2,248,22,142,16,23,194,1,28,248,22,138,16,23,194,2,90,144,42,11,89, +146,42,39,11,248,22,135,16,249,22,140,16,250,80,144,49,43,42,248,22,155, +16,2,56,11,11,248,22,155,16,2,57,86,95,23,195,1,23,194,1,248,22, +142,16,249,22,140,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22, +155,16,2,56,23,197,1,10,28,23,193,2,248,22,142,16,23,194,1,11,28, +248,22,88,23,195,2,9,27,27,248,22,81,23,197,2,28,248,22,139,16,23, 194,2,248,22,142,16,23,194,1,28,248,22,138,16,23,194,2,90,144,42,11, -89,146,42,39,11,248,22,135,16,249,22,140,16,250,80,144,52,43,42,248,22, +89,146,42,39,11,248,22,135,16,249,22,140,16,250,80,144,50,43,42,248,22, 155,16,2,56,11,11,248,22,155,16,2,57,86,95,23,195,1,23,194,1,248, -22,142,16,249,22,140,16,23,199,1,23,196,1,27,250,80,144,47,43,42,248, +22,142,16,249,22,140,16,23,199,1,23,196,1,27,250,80,144,45,43,42,248, 22,155,16,2,56,23,197,1,10,28,23,193,2,248,22,142,16,23,194,1,11, 28,23,193,2,249,22,80,248,22,142,16,249,22,140,16,23,198,1,247,22,156, -16,27,248,22,169,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,142,16,249, -22,140,16,23,198,1,247,22,156,16,248,80,144,49,8,53,42,248,22,169,20, -23,198,1,86,94,23,193,1,248,80,144,47,8,53,42,248,22,169,20,23,196, -1,86,94,23,193,1,27,248,22,169,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,142,16,249,22,140,16,23,198,1,247,22,156,16,248,80,144,47,8,53, -42,248,22,169,20,23,198,1,86,94,23,193,1,248,80,144,45,8,53,42,248, -22,169,20,23,196,1,27,247,22,163,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,132,16,248,22,155,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,155,16,2, -55,9,28,193,249,22,80,195,194,192,27,247,22,163,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,132,16,248, -22,155,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,155,16,2,55,9,28,193,249,22,80,195,194,192,27,247,22,163,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,132,16,248,22,155,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,155,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,139,16,23,194,2,248, -22,142,16,23,194,1,28,248,22,138,16,23,194,2,90,144,42,11,89,146,42, -39,11,248,22,135,16,249,22,140,16,250,80,144,60,43,42,248,22,155,16,2, -56,11,11,248,22,155,16,2,57,86,95,23,195,1,23,194,1,248,22,142,16, -249,22,140,16,23,199,1,23,196,1,27,250,80,144,55,43,42,248,22,155,16, -2,56,23,197,1,10,28,23,193,2,248,22,142,16,23,194,1,11,28,23,193, -2,249,22,80,248,22,142,16,249,22,140,16,23,198,1,247,22,156,16,27,248, -22,169,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,142,16,249,22,140,16, -23,198,1,247,22,156,16,248,80,144,57,8,53,42,248,22,169,20,23,198,1, -86,94,23,193,1,248,80,144,55,8,53,42,248,22,169,20,23,196,1,86,94, -23,193,1,27,248,22,169,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,142, -16,249,22,140,16,23,198,1,247,22,156,16,248,80,144,55,8,53,42,248,22, -169,20,23,198,1,86,94,23,193,1,248,80,144,53,8,53,42,248,22,169,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,152,15,10,22,159, -15,10,22,160,15,10,22,161,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,152,15, -10,22,159,15,10,22,160,15,10,22,161,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,152,15,10,22,159,15,10,22,160,15,10,22,161,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,155, -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,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,167,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,44,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,44,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, 19835); +16,27,248,22,170,20,23,199,1,28,248,22,88,23,194,2,9,27,27,248,22, +81,23,196,2,28,248,22,139,16,23,194,2,248,22,142,16,23,194,1,28,248, +22,138,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,135,16,249,22, +140,16,250,80,144,54,43,42,248,22,155,16,2,56,11,11,248,22,155,16,2, +57,86,95,23,195,1,23,194,1,248,22,142,16,249,22,140,16,23,199,1,23, +196,1,27,250,80,144,49,43,42,248,22,155,16,2,56,23,197,1,10,28,23, +193,2,248,22,142,16,23,194,1,11,28,23,193,2,249,22,80,248,22,142,16, +249,22,140,16,23,198,1,247,22,156,16,27,248,22,170,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,142,16,249,22,140,16,23,198,1,247,22,156,16,248, +80,144,51,8,53,42,248,22,170,20,23,198,1,86,94,23,193,1,248,80,144, +49,8,53,42,248,22,170,20,23,196,1,86,94,23,193,1,27,248,22,170,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,142,16,249,22,140,16,23,198,1, +247,22,156,16,248,80,144,49,8,53,42,248,22,170,20,23,198,1,86,94,23, +193,1,248,80,144,47,8,53,42,248,22,170,20,23,196,1,86,94,23,193,1, +27,248,22,170,20,23,197,1,28,248,22,88,23,194,2,9,27,27,248,22,81, +23,196,2,28,248,22,139,16,23,194,2,248,22,142,16,23,194,1,28,248,22, +138,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,135,16,249,22,140, +16,250,80,144,52,43,42,248,22,155,16,2,56,11,11,248,22,155,16,2,57, +86,95,23,195,1,23,194,1,248,22,142,16,249,22,140,16,23,199,1,23,196, +1,27,250,80,144,47,43,42,248,22,155,16,2,56,23,197,1,10,28,23,193, +2,248,22,142,16,23,194,1,11,28,23,193,2,249,22,80,248,22,142,16,249, +22,140,16,23,198,1,247,22,156,16,27,248,22,170,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,142,16,249,22,140,16,23,198,1,247,22,156,16,248,80, +144,49,8,53,42,248,22,170,20,23,198,1,86,94,23,193,1,248,80,144,47, +8,53,42,248,22,170,20,23,196,1,86,94,23,193,1,27,248,22,170,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,142,16,249,22,140,16,23,198,1,247, +22,156,16,248,80,144,47,8,53,42,248,22,170,20,23,198,1,86,94,23,193, +1,248,80,144,45,8,53,42,248,22,170,20,23,196,1,27,247,22,163,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,132,16,248,22,155,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,155,16,2,55,9,28,193,249,22,80,195,194,192,27,247, +22,163,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,132,16,248,22,155,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,155,16,2,55,9,28,193,249,22, +80,195,194,192,27,247,22,163,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,132,16, +248,22,155,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,155,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,139,16,23,194,2,248,22,142,16,23,194,1,28,248,22,138,16,23, +194,2,90,144,42,11,89,146,42,39,11,248,22,135,16,249,22,140,16,250,80, +144,60,43,42,248,22,155,16,2,56,11,11,248,22,155,16,2,57,86,95,23, +195,1,23,194,1,248,22,142,16,249,22,140,16,23,199,1,23,196,1,27,250, +80,144,55,43,42,248,22,155,16,2,56,23,197,1,10,28,23,193,2,248,22, +142,16,23,194,1,11,28,23,193,2,249,22,80,248,22,142,16,249,22,140,16, +23,198,1,247,22,156,16,27,248,22,170,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,142,16,249,22,140,16,23,198,1,247,22,156,16,248,80,144,57,8, +53,42,248,22,170,20,23,198,1,86,94,23,193,1,248,80,144,55,8,53,42, +248,22,170,20,23,196,1,86,94,23,193,1,27,248,22,170,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,142,16,249,22,140,16,23,198,1,247,22,156,16, +248,80,144,55,8,53,42,248,22,170,20,23,198,1,86,94,23,193,1,248,80, +144,53,8,53,42,248,22,170,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,152,15,10,22,159,15,10,22,160,15,10,22,161,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,152,15,10,22,159,15,10,22,160,15,10,22,161,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,152,15,10,22,159,15,10,22,160,15,10, +22,161,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,155,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,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,167, +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,44,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,44,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, 19823); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,48,46,53,84,0,0,0,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,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,248,1,0,0,3,1,5,105,110,115,112,48,76,35,37,112, @@ -1081,7 +1080,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 576); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,48,46,53,84,0,0,0,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,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, @@ -1145,8 +1144,8 @@ 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,168,20,23,197,2,249, -22,4,22,64,248,22,169,20,23,198,2,11,11,11,10,12,250,22,182,11,2, +22,64,248,22,81,23,197,2,10,248,22,167,9,248,22,169,20,23,197,2,249, +22,4,22,64,248,22,170,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, @@ -1158,7 +1157,7 @@ 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,178,15,23,197,2,23,196,1,86,94,23,196,1,247,22,156,16, -249,247,22,175,5,248,22,168,20,23,197,1,23,201,1,86,94,23,193,1,27, +249,247,22,175,5,248,22,169,20,23,197,1,23,201,1,86,94,23,193,1,27, 28,248,22,139,16,23,199,2,23,198,2,27,247,22,177,5,28,192,249,22,140, 16,23,201,2,194,23,199,2,90,144,42,11,89,146,42,39,11,248,22,135,16, 23,202,1,86,94,23,195,1,90,144,41,11,89,146,41,39,11,28,23,204,2, @@ -1208,7 +1207,7 @@ 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,178,15,23, 208,2,23,207,1,86,94,23,207,1,247,22,156,16,249,247,22,175,5,248,22, -168,20,23,196,1,23,220,1,86,94,23,193,1,27,28,23,197,1,27,249,22, +169,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,97,23, @@ -1219,8 +1218,8 @@ 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,178,15,23,209,2,23,208,1,86,94,23,208,1,247,22,156,16,249,247,22, -175,5,248,22,168,20,23,196,1,23,221,1,86,96,23,216,1,23,215,1,23, -193,1,28,28,248,22,78,23,220,2,248,22,168,20,23,220,2,10,27,28,23, +175,5,248,22,169,20,23,196,1,23,221,1,86,96,23,216,1,23,215,1,23, +193,1,28,28,248,22,78,23,220,2,248,22,169,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,190,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, @@ -1291,21 +1290,21 @@ 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,168,20,23,196,1,90,144,41,11,89,146,41,39,11,27,248,22,169,20,23, -197,2,28,248,22,88,248,22,82,23,195,2,249,22,7,9,248,22,168,20,195, -90,144,41,11,89,146,41,39,11,27,248,22,169,20,196,28,248,22,88,248,22, -82,23,195,2,249,22,7,9,248,22,168,20,195,90,144,41,11,89,146,41,39, -11,248,2,70,248,22,169,20,196,249,22,7,249,22,80,248,22,168,20,199,196, -195,249,22,7,249,22,80,248,22,168,20,199,196,195,249,22,7,249,22,80,248, -22,168,20,23,200,1,23,197,1,23,196,1,27,19,248,22,156,7,23,196,2, +22,169,20,23,196,1,90,144,41,11,89,146,41,39,11,27,248,22,170,20,23, +197,2,28,248,22,88,248,22,82,23,195,2,249,22,7,9,248,22,169,20,195, +90,144,41,11,89,146,41,39,11,27,248,22,170,20,196,28,248,22,88,248,22, +82,23,195,2,249,22,7,9,248,22,169,20,195,90,144,41,11,89,146,41,39, +11,248,2,70,248,22,170,20,196,249,22,7,249,22,80,248,22,169,20,199,196, +195,249,22,7,249,22,80,248,22,169,20,199,196,195,249,22,7,249,22,80,248, +22,169,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,168,20,23,196,1,27,248,22,169,20, +22,82,23,195,2,249,22,7,9,248,22,169,20,23,196,1,27,248,22,170,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,168,20,23,198,1,27,248,22,169,20,23,197,2,90, +2,249,22,7,9,248,22,169,20,23,198,1,27,248,22,170,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,168,20,197,90,144,41,11,89,146,41,39,11,248,2,70,248,22,169, -20,198,249,22,7,249,22,80,248,22,168,20,201,196,195,249,22,7,249,22,80, -248,22,168,20,23,203,1,196,195,249,22,7,249,22,80,248,22,168,20,23,201, +9,248,22,169,20,197,90,144,41,11,89,146,41,39,11,248,2,70,248,22,170, +20,198,249,22,7,249,22,80,248,22,169,20,201,196,195,249,22,7,249,22,80, +248,22,169,20,23,203,1,196,195,249,22,7,249,22,80,248,22,169,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, @@ -1314,7 +1313,7 @@ 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,168,20,23,195,1,23,194,1,28,248,22,178,15, +248,22,78,23,195,2,248,22,169,20,23,195,1,23,194,1,28,248,22,178,15, 23,194,2,90,144,42,11,89,146,42,39,11,248,22,135,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,86, 94,23,195,1,11,28,23,193,2,192,86,94,23,193,1,27,247,22,177,5,28, @@ -1335,7 +1334,7 @@ 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,132,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,169,20,23,200,1,23,198,1,23, +2,11,28,23,193,2,250,22,156,2,248,22,170,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, @@ -1350,8 +1349,8 @@ 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,178,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,169,20,200,251,2,82,196,197,249,22,80, -248,22,168,20,202,200,248,22,169,20,200,251,2,82,196,197,9,197,27,250,22, +2,82,196,197,248,22,82,199,248,22,170,20,200,251,2,82,196,197,249,22,80, +248,22,169,20,202,200,248,22,170,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, @@ -1368,9 +1367,9 @@ 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,182,15,248,22,103,23,198,2,248,2,90,248,22,169, +4,10,32,32,32,248,22,182,15,248,22,103,23,198,2,248,2,90,248,22,170, 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,168,20,23,200,1,23,196,1,251,22,178,11,2,22,6,41,41, +169,9,248,22,169,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, @@ -1379,11 +1378,11 @@ 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,168,20,23,209,2,2,32,11, +28,248,22,78,23,207,2,249,22,169,9,248,22,169,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,182,15,23,202,1,28,23,204,2,28, -250,22,158,2,248,22,168,20,23,202,1,23,202,1,11,249,22,80,11,205,249, +250,22,158,2,248,22,169,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,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, @@ -1392,44 +1391,44 @@ 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,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,168,20,23,198,2,2,5,11,86,97,23,198,1,23, +2,249,22,169,9,248,22,169,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,168,20,23,198,2,2,34,28,248, +22,78,23,196,2,28,249,22,169,9,248,22,169,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,168,20,23,198,2,2,34,28,28,249,22,171,9, +2,28,249,22,169,9,248,22,169,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,168,20,194,11,11,11,11,11,86,96,23,198,1,23, +78,193,248,22,64,248,22,169,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,168,20,23,197,2,23,196,2,27,28,249,22,171, -9,248,22,102,23,203,2,2,35,248,22,169,20,200,248,22,104,200,28,248,22, -78,23,198,2,249,22,94,248,22,169,20,199,194,192,28,28,248,22,78,23,196, -2,249,22,169,9,248,22,168,20,23,198,2,2,38,11,86,94,248,80,144,41, +248,22,78,23,197,2,248,22,169,20,23,197,2,23,196,2,27,28,249,22,171, +9,248,22,102,23,203,2,2,35,248,22,170,20,200,248,22,104,200,28,248,22, +78,23,198,2,249,22,94,248,22,170,20,199,194,192,28,28,248,22,78,23,196, +2,249,22,169,9,248,22,169,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, -168,20,23,198,2,2,34,28,248,22,78,248,22,102,23,197,2,249,22,169,9, +169,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,168,20,23,200,2,27,248,22,102,23,199,2, +28,249,22,169,9,2,34,248,22,169,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,168,20,193,192,250,22,178,11,2,22,6,45,45,110,111,32,98,97, +193,248,22,169,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,168,20,23,201,2,27,28,28,28,249,22,171,9,248,22,102,23, +2,34,248,22,169,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,169,20,23,202,1,248,22,104,23,202,1,28,248,22,78,23,195,2, -249,2,81,248,22,168,20,23,197,2,249,22,94,248,22,169,20,23,199,1,23, +35,248,22,170,20,23,202,1,248,22,104,23,202,1,28,248,22,78,23,195,2, +249,2,81,248,22,169,20,23,197,2,249,22,94,248,22,170,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,169,20,23,202,1,248,22,104,23,202,1, -28,248,22,78,193,248,22,169,20,193,11,86,94,23,198,1,11,86,94,23,198, +248,22,102,23,204,2,2,35,248,22,170,20,23,202,1,248,22,104,23,202,1, +28,248,22,78,193,248,22,170,20,193,11,86,94,23,198,1,11,86,94,23,198, 1,11,27,28,248,22,64,23,196,2,27,248,80,144,46,51,42,249,22,80,23, 199,2,248,22,132,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, @@ -1456,8 +1455,8 @@ 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,169,20,23,199,1, -23,199,1,10,86,94,23,196,1,28,249,22,169,9,248,22,168,20,23,198,2, +144,55,8,23,42,23,207,1,248,22,81,23,199,2,248,22,170,20,23,199,1, +23,199,1,10,86,94,23,196,1,28,249,22,169,9,248,22,169,20,23,198,2, 2,37,248,80,144,45,8,30,42,248,22,142,16,249,22,140,16,248,22,144,16, 248,22,102,23,201,2,248,80,144,49,8,29,42,23,205,2,12,86,94,28,28, 248,22,178,15,23,194,2,10,248,22,184,8,23,194,2,12,28,23,201,2,250, @@ -1486,7 +1485,7 @@ 23,197,1,23,207,1,23,214,1,86,96,23,211,1,23,204,1,23,194,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,168,20,23,208,2,2,32,11,11,249,80,144,56,52, +2,249,22,169,9,248,22,169,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,132,17,247,22, 145,14,252,22,186,8,23,209,1,23,208,1,23,206,1,23,204,1,23,203,1, @@ -1550,7 +1549,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 9765); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,48,46,53,84,0,0,0,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,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,199,1,0,0,3,1,5,105,110,115,112,48, diff --git a/racket/src/racket/src/env.c b/racket/src/racket/src/env.c index 2cdffe3023..6c4a9730b8 100644 --- a/racket/src/racket/src/env.c +++ b/racket/src/racket/src/env.c @@ -92,6 +92,7 @@ static Scheme_Object *variable_base_phase(int, Scheme_Object *[]); static Scheme_Object *variable_inspector(int, Scheme_Object *[]); static Scheme_Object *variable_const_p(int, Scheme_Object *[]); static Scheme_Object *now_transforming(int argc, Scheme_Object *argv[]); +static Scheme_Object *now_transforming_with_lifts(int argc, Scheme_Object *argv[]); static Scheme_Object *now_transforming_module(int argc, Scheme_Object *argv[]); static Scheme_Object *local_exp_time_value(int argc, Scheme_Object *argv[]); static Scheme_Object *local_exp_time_value_one(int argc, Scheme_Object *argv[]); @@ -772,6 +773,7 @@ static void make_kernel_env(void) scheme_add_global_constant("variable-reference-constant?", scheme_varref_const_p_proc, env); GLOBAL_PRIM_W_ARITY("syntax-transforming?", now_transforming, 0, 0, env); + GLOBAL_PRIM_W_ARITY("syntax-transforming-with-lifts?", now_transforming_with_lifts, 0, 0, env); GLOBAL_PRIM_W_ARITY("syntax-transforming-module-expression?", now_transforming_module, 0, 0, env); GLOBAL_PRIM_W_ARITY("syntax-local-value", local_exp_time_value, 1, 3, env); GLOBAL_PRIM_W_ARITY("syntax-local-value/immediate", local_exp_time_value_one, 1, 3, env); @@ -2242,6 +2244,24 @@ now_transforming(int argc, Scheme_Object *argv[]) : scheme_false); } +static Scheme_Object * +now_transforming_with_lifts(int argc, Scheme_Object *argv[]) +{ + Scheme_Comp_Env *env = scheme_current_thread->current_local_env; + + while (env && !env->lifts) { + env = env->next; + } + + if (env) + if (SCHEME_FALSEP(SCHEME_VEC_ELS(env->lifts)[0])) + env = NULL; + + return (env + ? scheme_true + : scheme_false); +} + static Scheme_Object * now_transforming_module(int argc, Scheme_Object *argv[]) { diff --git a/racket/src/racket/src/schminc.h b/racket/src/racket/src/schminc.h index ff4ac468f9..4e010a8f14 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 1139 +#define EXPECTED_PRIM_COUNT 1140 #define EXPECTED_UNSAFE_COUNT 106 #define EXPECTED_FLFXNUM_COUNT 69 #define EXPECTED_EXTFL_COUNT 45 diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 5ba3ed5f84..5fd088b00f 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.8" +#define MZSCHEME_VERSION "6.3.0.9" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 3 #define MZSCHEME_VERSION_Z 0 -#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) From 9bdbd14b960351fc74dbdf15fd0ae5ec7285f25a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 22 Dec 2015 08:03:26 -0700 Subject: [PATCH 219/369] sync version numbers --- 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 3b2945611d..fb0415ec89 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.3.0.8") +(define version "6.3.0.9") (define deps `("racket-lib" ["racket" #:version ,version])) From 2b10262258d0cf4636dcb4bbd26b01a512dff956 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 22 Dec 2015 11:02:54 -0700 Subject: [PATCH 220/369] get-module-suffixes: put "rkt" first Putting "rkt" first in the list makes it likely to act as a default, such as for a `put-file` dialog. --- racket/collects/compiler/module-suffix.rkt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/racket/collects/compiler/module-suffix.rkt b/racket/collects/compiler/module-suffix.rkt index f600ef7967..c89edcb07d 100644 --- a/racket/collects/compiler/module-suffix.rkt +++ b/racket/collects/compiler/module-suffix.rkt @@ -44,7 +44,14 @@ (cond [(bytes? suffix) (hash-set ht suffix #t)] [else ht]))])))) - (sort (hash-keys ht) bytes Date: Tue, 22 Dec 2015 10:27:36 -0600 Subject: [PATCH 221/369] use the correct accessor for subcontracts --- racket/collects/racket/contract/private/arr-i.rkt | 12 ++++++------ racket/collects/racket/contract/private/base.rkt | 4 ++-- .../racket/contract/private/case-arrow.rkt | 6 +++--- racket/collects/racket/contract/private/hash.rkt | 4 ++-- racket/collects/racket/contract/private/misc.rkt | 6 +++--- .../racket/contract/private/parametric.rkt | 2 +- .../collects/racket/contract/private/struct-dc.rkt | 14 +++++++------- .../racket/contract/private/struct-prop.rkt | 2 +- racket/collects/racket/contract/private/vector.rkt | 6 +++--- 9 files changed, 28 insertions(+), 28 deletions(-) diff --git a/racket/collects/racket/contract/private/arr-i.rkt b/racket/collects/racket/contract/private/arr-i.rkt index ba5eddfa20..bd04b22e2e 100644 --- a/racket/collects/racket/contract/private/arr-i.rkt +++ b/racket/collects/racket/contract/private/arr-i.rkt @@ -28,12 +28,12 @@ (provide (rename-out [->i/m ->i])) (define (build-??-args c-or-i-procedure ctc blame) - (define arg-ctc-projs (map (λ (x) (contract-late-neg-projection (->i-arg-contract x))) + (define arg-ctc-projs (map (λ (x) (get/build-late-neg-projection (->i-arg-contract x))) (->i-arg-ctcs ctc))) - (define indy-arg-ctc-projs (map (λ (x) (contract-late-neg-projection (cdr x))) + (define indy-arg-ctc-projs (map (λ (x) (get/build-late-neg-projection (cdr x))) (->i-indy-arg-ctcs ctc))) - (define rng-ctc-projs (map (λ (x) (contract-late-neg-projection (cdr x))) (->i-rng-ctcs ctc))) - (define indy-rng-ctc-projs (map (λ (x) (contract-late-neg-projection (cdr x))) + (define rng-ctc-projs (map (λ (x) (get/build-late-neg-projection (cdr x))) (->i-rng-ctcs ctc))) + (define indy-rng-ctc-projs (map (λ (x) (get/build-late-neg-projection (cdr x))) (->i-indy-rng-ctcs ctc))) (define has-rest (->i-rest ctc)) (define here (->i-here ctc)) @@ -1094,12 +1094,12 @@ evaluted left-to-right.) (raise-argument-error '->i "chaperone-contract?" orig-ctc)) - (((contract-late-neg-projection ctc) blame) obj neg-party)))) + (((get/build-late-neg-projection ctc) blame) obj neg-party)))) (begin-encourage-inline (define (un-dep orig-ctc obj blame neg-party) (let ([ctc (coerce-contract '->i orig-ctc)]) - (((contract-late-neg-projection ctc) blame) obj neg-party)))) + (((get/build-late-neg-projection ctc) blame) obj neg-party)))) (define-for-syntax (mk-used-indy-vars an-istx) (let ([vars (make-free-identifier-mapping)]) diff --git a/racket/collects/racket/contract/private/base.rkt b/racket/collects/racket/contract/private/base.rkt index 3cdac2fe97..ac36fcb5cb 100644 --- a/racket/collects/racket/contract/private/base.rkt +++ b/racket/collects/racket/contract/private/base.rkt @@ -145,7 +145,7 @@ [(recursive-contract-list-contract? ctc) (λ (blame) (define r-ctc (force-recursive-contract ctc)) - (define f (contract-late-neg-projection r-ctc)) + (define f (get/build-late-neg-projection r-ctc)) (define blame-known (blame-add-context blame #f)) (λ (val neg-party) (unless (list? val) @@ -157,7 +157,7 @@ [else (λ (blame) (define r-ctc (force-recursive-contract ctc)) - (define f (contract-late-neg-projection r-ctc)) + (define f (get/build-late-neg-projection r-ctc)) (define blame-known (blame-add-context blame #f)) (λ (val neg-party) ((f blame-known) val neg-party)))])) diff --git a/racket/collects/racket/contract/private/case-arrow.rkt b/racket/collects/racket/contract/private/case-arrow.rkt index f96510c608..83eca5e086 100644 --- a/racket/collects/racket/contract/private/case-arrow.rkt +++ b/racket/collects/racket/contract/private/case-arrow.rkt @@ -184,7 +184,7 @@ (define (case->-proj wrapper) (λ (ctc) (define dom-ctcs+case-nums (get-case->-dom-ctcs+case-nums ctc)) - (define rng-late-neg-ctcs (map contract-late-neg-projection (get-case->-rng-ctcs ctc))) + (define rng-late-neg-ctcs (map get/build-late-neg-projection (get-case->-rng-ctcs ctc))) (define rst-ctcs (base-case->-rst-ctcs ctc)) (define specs (base-case->-specs ctc)) (λ (blame) @@ -294,11 +294,11 @@ [rst (in-list (base-case->-rst-ctcs ctc))] [i (in-naturals)]) (define dom+case-nums - (map (λ (dom) (cons i (contract-late-neg-projection dom))) doms)) + (map (λ (dom) (cons i (get/build-late-neg-projection dom))) doms)) (append acc (if rst (append dom+case-nums - (list (cons i (contract-late-neg-projection rst)))) + (list (cons i (get/build-late-neg-projection rst)))) dom+case-nums)))) (define (get-case->-rng-ctcs ctc) diff --git a/racket/collects/racket/contract/private/hash.rkt b/racket/collects/racket/contract/private/hash.rkt index 1ea2d680a6..3f3369fb9d 100644 --- a/racket/collects/racket/contract/private/hash.rkt +++ b/racket/collects/racket/contract/private/hash.rkt @@ -194,9 +194,9 @@ (define immutable (base-hash/c-immutable ctc)) (define flat? (flat-hash/c? ctc)) (λ (blame) - (define dom-proj ((contract-late-neg-projection (base-hash/c-dom ctc)) + (define dom-proj ((get/build-late-neg-projection (base-hash/c-dom ctc)) (blame-add-key-context blame #f))) - (define rng-proj ((contract-late-neg-projection (base-hash/c-rng ctc)) + (define rng-proj ((get/build-late-neg-projection (base-hash/c-rng ctc)) (blame-add-value-context blame #f))) (λ (val neg-party) (cond diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index 5afebeb255..1b18727990 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -1994,7 +1994,7 @@ (define (stronger? this other) (contract-stronger? ctc other)) (make-contract #:name name - #:late-neg-projection (contract-late-neg-projection ctc) + #:late-neg-projection (get/build-late-neg-projection ctc) #:first-order (contract-first-order ctc) #:stronger stronger? #:list-contract? (list-contract? ctc)))))) @@ -2037,8 +2037,8 @@ (define (if/c-late-neg-proj ctc) (define predicate (base-if/c-predicate ctc)) - (define thn (contract-late-neg-projection (base-if/c-thn ctc))) - (define els (contract-late-neg-projection (base-if/c-els ctc))) + (define thn (get/build-late-neg-projection (base-if/c-thn ctc))) + (define els (get/build-late-neg-projection (base-if/c-els ctc))) (λ (blame) (define thn-proj (thn blame)) (define els-proj (els blame)) diff --git a/racket/collects/racket/contract/private/parametric.rkt b/racket/collects/racket/contract/private/parametric.rkt index 2fa504c15b..727ae8e344 100644 --- a/racket/collects/racket/contract/private/parametric.rkt +++ b/racket/collects/racket/contract/private/parametric.rkt @@ -69,7 +69,7 @@ (barrier/c negative? var))) (define protector (apply (polymorphic-contract-body c) instances)) - (((contract-late-neg-projection protector) blame) p neg-party)) + (((get/build-late-neg-projection protector) blame) p neg-party)) (lambda (p neg-party) (unless (procedure? p) diff --git a/racket/collects/racket/contract/private/struct-dc.rkt b/racket/collects/racket/contract/private/struct-dc.rkt index 6c13d96a31..624ba27869 100644 --- a/racket/collects/racket/contract/private/struct-dc.rkt +++ b/racket/collects/racket/contract/private/struct-dc.rkt @@ -260,7 +260,7 @@ (cond [(indep? subcontract) (define sub-ctc (indep-ctc subcontract)) - ((contract-late-neg-projection sub-ctc) blame+ctxt)] + ((get/build-late-neg-projection sub-ctc) blame+ctxt)] [else #f]))) (define mut-projs (for/list ([subcontract (in-list (base-struct/dc-subcontracts ctc))] @@ -268,7 +268,7 @@ (cond [(and (indep? subcontract) (mutable? subcontract)) (define sub-ctc (indep-ctc subcontract)) - ((contract-late-neg-projection sub-ctc) blame+ctxt)] + ((get/build-late-neg-projection sub-ctc) blame+ctxt)] [else #f]))) (define orig-indy-projs (for/list ([subcontract (in-list (base-struct/dc-subcontracts ctc))] @@ -276,7 +276,7 @@ (cond [(indep? subcontract) (define sub-ctc (indep-ctc subcontract)) - ((contract-late-neg-projection sub-ctc) blame+ctxt)] + ((get/build-late-neg-projection sub-ctc) blame+ctxt)] [else #f]))) (define orig-mut-indy-projs (for/list ([subcontract (in-list (base-struct/dc-subcontracts ctc))] @@ -284,7 +284,7 @@ (cond [(indep? subcontract) (define sub-ctc (indep-ctc subcontract)) - ((contract-late-neg-projection sub-ctc) blame+ctxt)] + ((get/build-late-neg-projection sub-ctc) blame+ctxt)] [else #f]))) (λ (v neg-party) (cond @@ -339,7 +339,7 @@ 'struct/dc (apply (dep-dep-proc subcontract) dep-args)))) (when dep-ctc (check-flat/chaperone dep-ctc subcontract)) - (define dep-ctc-blame-proj (and dep-ctc (contract-late-neg-projection dep-ctc))) + (define dep-ctc-blame-proj (and dep-ctc (get/build-late-neg-projection dep-ctc))) (define-values (new-chaperone-args new-impersonate-args) (cond [(invariant? subcontract) @@ -589,7 +589,7 @@ (define the-ctc (coerce-contract 'struct/dc (apply (dep-dep-proc this-subcontract) dep-args))) (check-flat/chaperone the-ctc subcontract) - (((contract-late-neg-projection the-ctc) blame) val neg-party)] + (((get/build-late-neg-projection the-ctc) blame) val neg-party)] [else (define indy-blame (car blames)) (define proj (car projs)) @@ -598,7 +598,7 @@ (coerce-contract 'struct/dc (apply (dep-dep-proc subcontract) dep-args)))) - (define dep-ctc-blame-proj (and dep-ctc (contract-late-neg-projection dep-ctc))) + (define dep-ctc-blame-proj (and dep-ctc (get/build-late-neg-projection dep-ctc))) (when (dep? subcontract) (check-flat/chaperone dep-ctc subcontract)) diff --git a/racket/collects/racket/contract/private/struct-prop.rkt b/racket/collects/racket/contract/private/struct-prop.rkt index 24f096d8c2..10edb1961e 100644 --- a/racket/collects/racket/contract/private/struct-prop.rkt +++ b/racket/collects/racket/contract/private/struct-prop.rkt @@ -7,7 +7,7 @@ (define (get-stpc-late-neg-proj stpc) (define get-late-neg-proj - (contract-late-neg-projection + (get/build-late-neg-projection (struct-type-property/c-value-contract stpc))) (λ (input-blame) (define blame (blame-add-context input-blame "the struct property value of" #:swap? #t)) diff --git a/racket/collects/racket/contract/private/vector.rkt b/racket/collects/racket/contract/private/vector.rkt index 9274738fe1..d87920bd7e 100644 --- a/racket/collects/racket/contract/private/vector.rkt +++ b/racket/collects/racket/contract/private/vector.rkt @@ -358,7 +358,7 @@ (define blame+ctxt (blame-add-element-of-context blame)) (define val+np-acceptors (for/list ([c (in-list (base-vector/c-elems ctc))]) - ((contract-late-neg-projection c) blame+ctxt))) + ((get/build-late-neg-projection c) blame+ctxt))) (λ (val neg-party) (with-contract-continuation-mark (cons blame neg-party) @@ -377,12 +377,12 @@ (let ([elem-pos-projs (for/vector #:length (length elem-ctcs) ([c (in-list elem-ctcs)] [i (in-naturals)]) - ((contract-late-neg-projection c) + ((get/build-late-neg-projection c) (blame-add-context blame (format "the ~a element of" (n->th i)))))] [elem-neg-projs (for/vector #:length (length elem-ctcs) ([c (in-list elem-ctcs)] [i (in-naturals)]) - ((contract-late-neg-projection c) + ((get/build-late-neg-projection c) (blame-add-context blame (format "the ~a element of" (n->th i)) #:swap? #t)))]) (λ (val neg-party) From 31cf0bdbc38b6172a4c8cafffbe1069f14ed624f Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 22 Dec 2015 14:27:47 -0600 Subject: [PATCH 222/369] remove the error-prone except-out's from racket/contract and take the opportunity to move some things around internally to more reasonable places --- racket/collects/racket/contract/base.rkt | 123 ++++++++++++---- .../collects/racket/contract/combinator.rkt | 123 +++++++++++++--- .../collects/racket/contract/parametric.rkt | 4 +- .../collects/racket/contract/private/guts.rkt | 131 ++++++++++++++++++ .../racket/contract/private/legacy.rkt | 2 +- .../collects/racket/contract/private/misc.rkt | 126 +---------------- .../collects/racket/contract/private/prop.rkt | 2 +- 7 files changed, 331 insertions(+), 180 deletions(-) diff --git a/racket/collects/racket/contract/base.rkt b/racket/collects/racket/contract/base.rkt index dec48b2016..6354928697 100644 --- a/racket/collects/racket/contract/base.rkt +++ b/racket/collects/racket/contract/base.rkt @@ -20,37 +20,88 @@ "private/orc.rkt") (provide - (except-out (all-from-out "private/arrow.rkt") - making-a-method - procedure-accepts-and-more? - check-procedure - check-procedure/more - - contract-key - - ;; these two are provided for-syntax - ;check-tail-contract - ;make-this-parameters - - -> ->*) + base->? + ->d + base->-rngs/c + base->-doms/c + unconstrained-domain-> + the-unsupplied-arg + unsupplied-arg? + method-contract? + matches-arity-exactly? + keywords-match + bad-number-of-results + (for-syntax check-tail-contract + make-this-parameters + parse-leftover->*) + tail-marks-match? + values/drop + arity-checking-wrapper + unspecified-dom + blame-add-range-context + blame-add-nth-arg-context + (rename-out [->2 ->] [->*2 ->*]) dynamic->* predicate/c + + ->i + box-immutable/c + box/c + hash/c + hash/dc + vectorof + vector/c + vector-immutable/c + vector-immutableof + struct/dc + struct/c + struct-type-property/c + + contract + recursive-contract + invariant-assertion + + flat-murec-contract + and/c + not/c + =/c >=/c <=/c /c between/c + integer-in + char-in + real-in + natural-number/c + string-len/c + false/c + printable/c + listof list*of non-empty-listof cons/c list/c cons/dc + promise/c + syntax/c + + parameter/c + procedure-arity-includes/c + + any/c + any + none/c + make-none/c + + prompt-tag/c + continuation-mark-key/c + + channel/c + evt/c + + flat-contract + flat-contract-predicate + flat-named-contract + + blame-add-car-context + blame-add-cdr-context + raise-not-cons-blame-error + + rename-contract + if/c - (all-from-out "private/arr-i.rkt" - "private/box.rkt" - "private/hash.rkt" - "private/vector.rkt" - "private/struct-dc.rkt" - "private/struct-prop.rkt") - (except-out (all-from-out "private/base.rkt") - 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 - random-any/c - maybe-warn-about-val-first) symbols or/c first-or/c one-of/c flat-rec-contract provide/contract @@ -74,7 +125,23 @@ case-> ;; from here (needs `->`, so can't be deeper) - failure-result/c) + failure-result/c + + contract? + chaperone-contract? + impersonator-contract? + flat-contract? + + contract-late-neg-projection + contract-name + contract-projection + contract-val-first-projection + get/build-late-neg-projection + get/build-val-first-projection + + ;; not documented.... (ie unintentional export) + n->th) + ;; failure-result/c : contract ;; Describes the optional failure argument passed to hash-ref, for example. diff --git a/racket/collects/racket/contract/combinator.rkt b/racket/collects/racket/contract/combinator.rkt index 5072060024..587adc2825 100644 --- a/racket/collects/racket/contract/combinator.rkt +++ b/racket/collects/racket/contract/combinator.rkt @@ -1,32 +1,112 @@ #lang racket/base (require "private/prop.rkt" - (prefix-in : "private/prop.rkt") + (prefix-in : (only-in "private/prop.rkt" + build-chaperone-contract-property + build-flat-contract-property + make-chaperone-contract + make-flat-contract)) "private/guts.rkt" "private/blame.rkt") (provide - (except-out (all-from-out "private/prop.rkt") - contract-struct-name - contract-struct-first-order - contract-struct-projection - contract-struct-val-first-projection - contract-struct-stronger? - contract-struct? - chaperone-contract-struct? - flat-contract-struct? - make-chaperone-contract - make-flat-contract - build-chaperone-contract-property - build-flat-contract-property) + prop:contract + contract-struct-late-neg-projection + contract-struct-generate + contract-struct-exercise + contract-struct-list-contract? - (except-out (all-from-out "private/guts.rkt") - check-flat-contract - check-flat-named-contract - make-predicate-contract - has-contract? - value-contract) + prop:flat-contract + prop:chaperone-contract + + contract-property? + build-contract-property + + chaperone-contract-property? + + flat-contract-property? + + make-contract + + prop:opt-chaperone-contract + prop:opt-chaperone-contract? + prop:opt-chaperone-contract-get-test + + prop:orc-contract + prop:orc-contract? + prop:orc-contract-get-subcontracts + + prop:recursive-contract + prop:recursive-contract? + prop:recursive-contract-unroll + + prop:arrow-contract + prop:arrow-contract? + prop:arrow-contract-get-info + (struct-out arrow-contract-info) + + coerce-contract + coerce-contracts + coerce-flat-contract + coerce-flat-contracts + coerce-chaperone-contract + coerce-chaperone-contracts + coerce-contract/f + + build-compound-type-name + + contract-stronger? + list-contract? + + contract-first-order + contract-first-order-passes? + + prop:contracted prop:blame + impersonator-prop:contracted impersonator-prop:blame + has-blame? value-blame + + ;; helpers for adding properties that check syntax uses + define/final-prop + define/subexpression-pos-prop + define/subexpression-pos-prop/name + + eq-contract? + eq-contract-val + equal-contract? + equal-contract-val + char-in/c + + contract-continuation-mark-key + with-contract-continuation-mark + + (struct-out wrapped-extra-arg-arrow) + contract-custom-write-property-proc + (rename-out [contract-custom-write-property-proc custom-write-property-proc]) + + set-some-basic-contracts! + + blame? + blame-source + blame-positive + blame-negative + blame-contract + blame-value + blame-original? + blame-swapped? + blame-swap + blame-replace-negative ;; used for indy blame + blame-update ;; used for option contract transfers + blame-add-context + blame-add-unknown-context + blame-context + + blame-add-missing-party + blame-missing-party? + + raise-blame-error + current-blame-format + (struct-out exn:fail:contract:blame) + blame-fmt->-string - (except-out (all-from-out "private/blame.rkt") make-blame) (rename-out [-make-chaperone-contract make-chaperone-contract] [-make-flat-contract make-flat-contract] [-build-chaperone-contract-property build-chaperone-contract-property] @@ -199,4 +279,3 @@ (λ (x) (x-acceptor x) x)))) - diff --git a/racket/collects/racket/contract/parametric.rkt b/racket/collects/racket/contract/parametric.rkt index fc0fb30b74..1c6a321ab0 100644 --- a/racket/collects/racket/contract/parametric.rkt +++ b/racket/collects/racket/contract/parametric.rkt @@ -1,6 +1,4 @@ #lang racket/base (require "private/exists.rkt" "private/parametric.rkt") -(provide (all-from-out "private/parametric.rkt") - (except-out (all-from-out "private/exists.rkt") - ∀∃?)) +(provide new-∃/c new-∀/c parametric->/c) diff --git a/racket/collects/racket/contract/private/guts.rkt b/racket/collects/racket/contract/private/guts.rkt index df3f78f627..fbd88499d9 100644 --- a/racket/collects/racket/contract/private/guts.rkt +++ b/racket/collects/racket/contract/private/guts.rkt @@ -48,12 +48,27 @@ equal-contract-val char-in/c + contract? + chaperone-contract? + impersonator-contract? + flat-contract? + contract-continuation-mark-key with-contract-continuation-mark (struct-out wrapped-extra-arg-arrow) contract-custom-write-property-proc (rename-out [contract-custom-write-property-proc custom-write-property-proc]) + + 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 + warn-about-val-first? + + contract-name + maybe-warn-about-val-first set-some-basic-contracts!) @@ -80,6 +95,27 @@ (print (contract-struct-name stct) port 1) (write-suffix)])])) +(define (contract? x) (and (coerce-contract/f x) #t)) + +(define (flat-contract? x) + (let ([c (coerce-contract/f x)]) + (and c + (flat-contract-struct? c)))) + +(define (chaperone-contract? x) + (let ([c (coerce-contract/f x)]) + (and c + (or (chaperone-contract-struct? c) + (and (prop:opt-chaperone-contract? c) + ((prop:opt-chaperone-contract-get-test c) c)))))) + +(define (impersonator-contract? x) + (let ([c (coerce-contract/f x)]) + (and c + (not (flat-contract-struct? c)) + (not (chaperone-contract-struct? c))))) + + (define (has-contract? v) (or (has-prop:contracted? v) (has-impersonator-prop:contracted? v))) @@ -600,6 +636,100 @@ (make-predicate-contract name pred generate #f)) + +(define (contract-name ctc) + (contract-struct-name + (coerce-contract 'contract-name ctc))) + +(define (contract-projection ctc) + (get/build-projection + (coerce-contract 'contract-projection ctc))) +(define (contract-val-first-projection ctc) + (get/build-val-first-projection + (coerce-contract 'contract-projection ctc))) +(define (contract-late-neg-projection ctc) + (get/build-late-neg-projection + (coerce-contract 'contract-projection ctc))) + +(define-logger racket/contract) + +(define (get/build-late-neg-projection ctc) + (cond + [(contract-struct-late-neg-projection ctc) => values] + [else + (log-racket/contract-warning "no late-neg-projection for ~s" ctc) + (cond + [(contract-struct-projection ctc) + => + (λ (projection) + (projection->late-neg-projection projection))] + [(contract-struct-val-first-projection ctc) + => + (λ (val-first-projection) + (val-first-projection->late-neg-projection val-first-projection))] + [else + (first-order->late-neg-projection (contract-struct-first-order ctc) + (contract-struct-name ctc))])])) + +(define (projection->late-neg-projection proj) + (λ (b) + (λ (x neg-party) + ((proj (blame-add-missing-party b neg-party)) x)))) +(define (val-first-projection->late-neg-projection vf-proj) + (λ (b) + (define vf-val-accepter (vf-proj b)) + (λ (x neg-party) + ((vf-val-accepter x) neg-party)))) +(define (first-order->late-neg-projection p? name) + (λ (b) + (λ (x neg-party) + (if (p? x) + x + (raise-blame-error + b x #:missing-party neg-party + '(expected: "~a" given: "~e") + name + x))))) + +(define warn-about-val-first? (make-parameter #t)) +(define (maybe-warn-about-val-first ctc) + (when (warn-about-val-first?) + (log-racket/contract-warning + "building val-first-projection of contract ~s for~a" + ctc + (build-context)))) + +(define (get/build-val-first-projection ctc) + (cond + [(contract-struct-val-first-projection ctc) => values] + [else + (maybe-warn-about-val-first ctc) + (late-neg-projection->val-first-projection + (get/build-late-neg-projection ctc))])) +(define (late-neg-projection->val-first-projection lnp) + (λ (b) + (define val+neg-party-accepter (lnp b)) + (λ (x) + (λ (neg-party) + (val+neg-party-accepter x neg-party))))) + +(define (get/build-projection ctc) + (cond + [(contract-struct-projection ctc) => values] + [else + (log-racket/contract-warning + "building projection of contract ~s for~a" + ctc + (build-context)) + (late-neg-projection->projection + (get/build-late-neg-projection ctc))])) +(define (late-neg-projection->projection lnp) + (λ (b) + (define val+np-acceptor (lnp b)) + (λ (x) + (val+np-acceptor x #f)))) + + ;; Key used by the continuation mark that holds blame information for the current contract. ;; That information is consumed by the contract profiler. (define contract-continuation-mark-key @@ -612,3 +742,4 @@ ;; (unless (or (pair? payload) (not (blame-missing-party? payload))) ;; (error "internal error: missing blame party" payload)) (with-continuation-mark contract-continuation-mark-key payload code))) + diff --git a/racket/collects/racket/contract/private/legacy.rkt b/racket/collects/racket/contract/private/legacy.rkt index 4ebdb5b4d3..2b7817f6ca 100644 --- a/racket/collects/racket/contract/private/legacy.rkt +++ b/racket/collects/racket/contract/private/legacy.rkt @@ -1,6 +1,6 @@ #lang racket/base -(require "blame.rkt" "prop.rkt" "misc.rkt" syntax/srcloc) +(require "blame.rkt" "prop.rkt" "guts.rkt" syntax/srcloc) (provide make-proj-contract raise-contract-error diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index 1b18727990..6025b72e96 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -43,22 +43,10 @@ channel/c evt/c - chaperone-contract? - impersonator-contract? - flat-contract? - contract? - flat-contract flat-contract-predicate flat-named-contract - 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 - warn-about-val-first? - contract-name n->th blame-add-car-context @@ -68,9 +56,7 @@ random-any/c rename-contract - if/c - - maybe-warn-about-val-first) + if/c) (define-syntax (flat-murec-contract stx) (syntax-case stx () @@ -1804,116 +1790,6 @@ (contract-struct-first-order (coerce-flat-contract 'flat-contract-predicate x))) -(define (flat-contract? x) - (let ([c (coerce-contract/f x)]) - (and c - (flat-contract-struct? c)))) - -(define (chaperone-contract? x) - (let ([c (coerce-contract/f x)]) - (and c - (or (chaperone-contract-struct? c) - (and (prop:opt-chaperone-contract? c) - ((prop:opt-chaperone-contract-get-test c) c)))))) - -(define (impersonator-contract? x) - (let ([c (coerce-contract/f x)]) - (and c - (not (flat-contract-struct? c)) - (not (chaperone-contract-struct? c))))) - -(define (contract-name ctc) - (contract-struct-name - (coerce-contract 'contract-name ctc))) - -(define (contract? x) (and (coerce-contract/f x) #t)) -(define (contract-projection ctc) - (get/build-projection - (coerce-contract 'contract-projection ctc))) -(define (contract-val-first-projection ctc) - (get/build-val-first-projection - (coerce-contract 'contract-projection ctc))) -(define (contract-late-neg-projection ctc) - (get/build-late-neg-projection - (coerce-contract 'contract-projection ctc))) - -(define-logger racket/contract) -(define (get/build-late-neg-projection ctc) - (cond - [(contract-struct-late-neg-projection ctc) => values] - [else - (log-racket/contract-warning "no late-neg-projection for ~s" ctc) - (cond - [(contract-struct-projection ctc) - => - (λ (projection) - (projection->late-neg-projection projection))] - [(contract-struct-val-first-projection ctc) - => - (λ (val-first-projection) - (val-first-projection->late-neg-projection val-first-projection))] - [else - (first-order->late-neg-projection (contract-struct-first-order ctc) - (contract-struct-name ctc))])])) - -(define (projection->late-neg-projection proj) - (λ (b) - (λ (x neg-party) - ((proj (blame-add-missing-party b neg-party)) x)))) -(define (val-first-projection->late-neg-projection vf-proj) - (λ (b) - (define vf-val-accepter (vf-proj b)) - (λ (x neg-party) - ((vf-val-accepter x) neg-party)))) -(define (first-order->late-neg-projection p? name) - (λ (b) - (λ (x neg-party) - (if (p? x) - x - (raise-blame-error - b x #:missing-party neg-party - '(expected: "~a" given: "~e") - name - x))))) - -(define warn-about-val-first? (make-parameter #t)) -(define (maybe-warn-about-val-first ctc) - (when (warn-about-val-first?) - (log-racket/contract-warning - "building val-first-projection of contract ~s for~a" - ctc - (build-context)))) - -(define (get/build-val-first-projection ctc) - (cond - [(contract-struct-val-first-projection ctc) => values] - [else - (maybe-warn-about-val-first ctc) - (late-neg-projection->val-first-projection - (get/build-late-neg-projection ctc))])) -(define (late-neg-projection->val-first-projection lnp) - (λ (b) - (define val+neg-party-accepter (lnp b)) - (λ (x) - (λ (neg-party) - (val+neg-party-accepter x neg-party))))) - -(define (get/build-projection ctc) - (cond - [(contract-struct-projection ctc) => values] - [else - (log-racket/contract-warning - "building projection of contract ~s for~a" - ctc - (build-context)) - (late-neg-projection->projection - (get/build-late-neg-projection ctc))])) -(define (late-neg-projection->projection lnp) - (λ (b) - (define val+np-acceptor (lnp b)) - (λ (x) - (val+np-acceptor x #f)))) - (define (flat-contract predicate) (coerce-flat-contract 'flat-contract predicate)) (define (flat-named-contract name pre-contract [generate #f]) (cond diff --git a/racket/collects/racket/contract/private/prop.rkt b/racket/collects/racket/contract/private/prop.rkt index ea451a3e3b..4964594e3e 100644 --- a/racket/collects/racket/contract/private/prop.rkt +++ b/racket/collects/racket/contract/private/prop.rkt @@ -510,4 +510,4 @@ ;; raises a blame error if val doesn't satisfy the first-order checks for the function ;; accepts-arglist : (-> (listof keyword?)[sorted by keyword Date: Tue, 22 Dec 2015 15:40:31 -0600 Subject: [PATCH 223/369] have a better strategy for or/c to determine which clause to commit to in particular, when there is a recursive contract, then we check only some part of the first-order checks and see if that was enough to distinguish the branches. if it was, we don't continue and otherwise we do --- .../scribblings/reference/contracts.scrbl | 43 ++++++++++- .../racket/contract/recursive-contract.rkt | 21 +++++- .../collects/racket/contract/private/base.rkt | 7 +- .../collects/racket/contract/private/guts.rkt | 24 +++++- .../collects/racket/contract/private/orc.rkt | 74 +++++++++++-------- 5 files changed, 131 insertions(+), 38 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index b1ff992a28..487a0b3899 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -1978,9 +1978,11 @@ The first-order predicate @racket[test] can be used to determine which values the contract applies to; this must be the set of values for which the contract fails immediately without any higher-order wrapping. This test is used by @racket[contract-first-order-passes?], and indirectly by @racket[or/c] - and @racket[from-or/c] to determine which higher-order contract to wrap a - value with when there are multiple higher-order contracts to choose from. - The default test accepts any value. +and @racket[from-or/c] to determine which higher-order contract to wrap a +value with when there are multiple higher-order contracts to choose from. +The default test accepts any value. The predicate should be influenced by +the value of @racket[(contract-first-order-okay-to-give-up?)] (see it's documentation +for more explanation). 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 @@ -2745,7 +2747,11 @@ If it returns @racket[#f], the contract is guaranteed not to hold for that value; if it returns @racket[#t], the contract may or may not hold. If the contract is a first-order contract, a result of @racket[#t] guarantees that the -contract holds.} +contract holds. + +See also @racket[contract-first-order-okay-to-give-up?] and +@racket[contract-first-order-try-less-hard]. +} @defproc[(contract-first-order [c contract?]) (-> any/c boolean?)]{ Produces the first-order test used by @racket[or/c] to match values to @@ -2943,6 +2949,35 @@ currently being checked. @history[#:added "6.3"] } +@defform[(contract-first-order-okay-to-give-up?)]{ + This form returns a boolean that controls the result + of first-order contact checks. More specifically, if + it returns @racket[#t], then a first-order check may + return @racket[#t] even when the entire first-order + checks have not happened. If it returns @racket[#f] + then the first order checks must continue until a + definitive answer is returned. + + This will only return @racket[#t] in the dynamic + extent of @racket[or/c] or @racket[first-or/c]'s + checking to determine which branch to use. + + @history[#:added "6.3.0.9"] +} +@defform[(contract-first-order-try-less-hard e)]{ + Encourages first-order checks that happen in the + dynamic-extent of @racket[e] to be more likely to + give up. That is, makes it more likely that + @racket[contract-first-order-okay-to-give-up?] might + return @racket[#t]. + + If not in the dynamic-extent of @racket[or/c]'s or + @racket[first-or/c]'s checking to determine the branch, + then this form has no effect. + + @history[#:added "6.3.0.9"] +} + @defproc[(if/c [predicate (-> any/c any/c)] [then-contract contract?] [else-contract contract?]) diff --git a/pkgs/racket-test/tests/racket/contract/recursive-contract.rkt b/pkgs/racket-test/tests/racket/contract/recursive-contract.rkt index 523c688ee2..e22827a101 100644 --- a/pkgs/racket-test/tests/racket/contract/recursive-contract.rkt +++ b/pkgs/racket-test/tests/racket/contract/recursive-contract.rkt @@ -72,4 +72,23 @@ '(let () (struct doll (contents)) (letrec ([doll-ctc2 (or/c 'center (struct/c doll (recursive-contract doll-ctc2 #:flat)))]) - (contract doll-ctc2 (doll 4) 'pos 'neg))))) + (contract doll-ctc2 (doll 4) 'pos 'neg)))) + + + (test/spec-passed/result + 'recursive-contract-not-too-slow + '(let () + (define c + (recursive-contract + (or/c null? + (cons/c (-> integer? integer? integer?) c) + (cons/c (-> integer? integer?) (cons/c (-> integer? integer?) c))))) + + (define l (build-list 10000 (λ (x) (λ (x) x)))) + (define-values (_ cpu real gc) + (time-apply (λ () (contract c l 'pos 'neg)) '())) + ;; should be substantially less than 5 seconds. + ;; with the old implementation it is more like 20 seconds + ;; on my laptop and about .3 seconds with the new one + (< (- cpu gc) 5000)) + #t)) diff --git a/racket/collects/racket/contract/private/base.rkt b/racket/collects/racket/contract/private/base.rkt index ac36fcb5cb..f9e8242b21 100644 --- a/racket/collects/racket/contract/private/base.rkt +++ b/racket/collects/racket/contract/private/base.rkt @@ -165,8 +165,11 @@ (define (recursive-contract-stronger this that) (equal? this that)) (define ((recursive-contract-first-order ctc) val) - (contract-first-order-passes? (force-recursive-contract ctc) - val)) + (cond + [(contract-first-order-okay-to-give-up?) #t] + [else (contract-first-order-try-less-hard + (contract-first-order-passes? (force-recursive-contract ctc) + val))])) (define (recursive-contract-generate ctc) (λ (fuel) diff --git a/racket/collects/racket/contract/private/guts.rkt b/racket/collects/racket/contract/private/guts.rkt index fbd88499d9..dd2c556750 100644 --- a/racket/collects/racket/contract/private/guts.rkt +++ b/racket/collects/racket/contract/private/guts.rkt @@ -70,7 +70,11 @@ contract-name maybe-warn-about-val-first - set-some-basic-contracts!) + set-some-basic-contracts! + + contract-first-order-okay-to-give-up? + contract-first-order-try-less-hard + contract-first-order-only-try-so-hard) (define (contract-custom-write-property-proc stct port mode) (define (write-prefix) @@ -730,6 +734,24 @@ (val+np-acceptor x #f)))) +(define contract-first-order-okay-to-give-up-key (gensym 'contract-first-order-okay-to-give-up-key)) +(define (contract-first-order-okay-to-give-up?) + (zero? (continuation-mark-set-first #f + contract-first-order-okay-to-give-up-key + 1))) +(define-syntax-rule + (contract-first-order-try-less-hard e) + (contract-first-order-try-less-hard/proc (λ () e))) +(define (contract-first-order-try-less-hard/proc th) + (define cv (continuation-mark-set-first #f contract-first-order-okay-to-give-up-key)) + (if cv + (with-continuation-mark contract-first-order-okay-to-give-up-key (if (= cv 0) 0 (- cv 1)) + (th)) + (th))) +(define-syntax-rule + (contract-first-order-only-try-so-hard n e) + (with-continuation-mark contract-first-order-okay-to-give-up-key n e)) + ;; Key used by the continuation mark that holds blame information for the current contract. ;; That information is consumed by the contract profiler. (define contract-continuation-mark-key diff --git a/racket/collects/racket/contract/private/orc.rkt b/racket/collects/racket/contract/private/orc.rkt index 6fa24bfc7a..dcb8bfc566 100644 --- a/racket/collects/racket/contract/private/orc.rkt +++ b/racket/collects/racket/contract/private/orc.rkt @@ -243,38 +243,52 @@ (pred val)) val] [else - (let loop ([checks first-order-checks] - [c-projs c-projs+blame] - [contracts ho-contracts] - [candidate-c-proj #f] - [candidate-contract #f]) + (define (try) + (let loop ([checks first-order-checks] + [c-projs c-projs+blame] + [contracts ho-contracts] + [candidate-c-proj #f] + [candidate-contract #f]) + (cond + [(null? checks) + (cond + [candidate-c-proj + (values candidate-c-proj #f)] + [else + (raise-none-or-matched blame val neg-party)])] + [((car checks) val) + (if candidate-c-proj + (values candidate-contract (car contracts)) + (loop (cdr checks) + (cdr c-projs) + (cdr contracts) + (car c-projs) + (car contracts)))] + [else + (loop (cdr checks) + (cdr c-projs) + (cdr contracts) + candidate-c-proj + candidate-contract)]))) + + (let loop ([how-hard '(10 100)]) (cond - [(null? checks) - (cond - [candidate-c-proj - (candidate-c-proj val neg-party)] - [else - (raise-none-or-matched blame val neg-party)])] - [((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)))] + [(null? how-hard) + (define-values (last-try-first-one last-try-second-one) (try)) + (when (and last-try-first-one last-try-second-one) + (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 last-try-first-one) + (contract-name last-try-second-one) + val))] [else - (loop (cdr checks) - (cdr c-projs) - (cdr contracts) - candidate-c-proj - candidate-contract)]))])))) + (define-values (this-try-first-one this-try-second-one) + (contract-first-order-only-try-so-hard (car how-hard) (try))) + (cond + [(not this-try-second-one) (this-try-first-one val neg-party)] + [else (loop (cdr how-hard))])]))])))) (define (raise-none-or-matched blame val neg-party) (raise-blame-error blame val #:missing-party neg-party From d2233f95e2622cca20509d1d73fc8f8ba7331c7e Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 22 Dec 2015 15:49:44 -0600 Subject: [PATCH 224/369] make vectorof also try less hard during or/c checking --- racket/collects/racket/contract/private/vector.rkt | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/racket/collects/racket/contract/private/vector.rkt b/racket/collects/racket/contract/private/vector.rkt index d87920bd7e..648bc3c12e 100644 --- a/racket/collects/racket/contract/private/vector.rkt +++ b/racket/collects/racket/contract/private/vector.rkt @@ -62,10 +62,15 @@ (fail val '(expected "an mutable vector" given: "~e" val)))] [else (void)]) (when first-order? - (for ([e (in-vector val)] - [n (in-naturals)]) - (unless (contract-first-order-passes? elem-ctc e) - (fail val '(expected: "~s for element ~s" given: "~e") (contract-name elem-ctc) n e)))) + (let loop ([n 0]) + (cond + [(= n (vector-length val)) + (void)] + [else + (define e (vector-ref val n)) + (unless (contract-first-order-passes? elem-ctc e) + (fail val '(expected: "~s for element ~s" given: "~e") (contract-name elem-ctc) n e)) + (contract-first-order-try-less-hard (loop (+ n 1)))]))) #t))) (define (check-late-neg-vectorof c) From c73bcceafe570b0b573c23df893d95dc4e361b9f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 22 Dec 2015 14:15:11 -0700 Subject: [PATCH 225/369] avoid a string pointer needed only for error reporting --- racket/src/racket/src/fun.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/racket/src/racket/src/fun.c b/racket/src/racket/src/fun.c index 4e88cca8ac..7de6aba075 100644 --- a/racket/src/racket/src/fun.c +++ b/racket/src/racket/src/fun.c @@ -3696,11 +3696,12 @@ Scheme_Object *extract_impersonator_results(int c, int argc, Scheme_Object **arg /* must be at least 3: */ #define MAX_QUICK_CHAP_ARGV 5 +#define CHAPERONE_KIND_STR(px) (!(SCHEME_CHAPERONE_FLAGS(px) & SCHEME_CHAPERONE_IS_IMPERSONATOR) ? "chaperone" : "impersonator") + Scheme_Object *scheme_apply_chaperone(Scheme_Object *o, int argc, Scheme_Object **argv, Scheme_Object *auto_val, int checks) /* auto_val => no need to actually call the function (but handle further chaperoning); checks & 0x2 => no tail; checks == 0x3 => no tail or multiple */ { - const char *what; Scheme_Chaperone *px; Scheme_Object *v, *a[1], *a2[MAX_QUICK_CHAP_ARGV], **argv2, *post, *result_v, *orig_obj, *app_mark, *self_proc; int c, i, need_restore = 0; @@ -3743,15 +3744,10 @@ Scheme_Object *scheme_apply_chaperone(Scheme_Object *o, int argc, Scheme_Object self_proc = o; } - if (!(SCHEME_CHAPERONE_FLAGS(px) & SCHEME_CHAPERONE_IS_IMPERSONATOR)) - what = "chaperone"; - else - what = "impersonator"; - if (SCHEME_FALSEP(SCHEME_VEC_ELS(px->redirects)[0])) { /* no redirection procedure */ if (SCHEME_CHAPERONEP(px->prev)) { - /* commuincate `self_proc` to the next layer: */ + /* communicate `self_proc` to the next layer: */ scheme_current_thread->self_for_proc_chaperone = self_proc; } return _scheme_tail_apply(px->prev, argc, argv); @@ -3842,7 +3838,7 @@ Scheme_Object *scheme_apply_chaperone(Scheme_Object *o, int argc, Scheme_Object if (c >= argc) { int need_pop = 0; post = extract_impersonator_results(c, argc, argv2, - what, o, px, + CHAPERONE_KIND_STR(px), o, px, &cframe, &need_pop); need_pop_mark = need_pop; @@ -3871,7 +3867,7 @@ Scheme_Object *scheme_apply_chaperone(Scheme_Object *o, int argc, Scheme_Object " wrapper: %V\n" " expected: %d or more\n" " received: %d", - what, + CHAPERONE_KIND_STR(px), o, SCHEME_VEC_ELS(px->redirects)[0], argc, @@ -3985,7 +3981,7 @@ Scheme_Object *scheme_apply_chaperone(Scheme_Object *o, int argc, Scheme_Object " original: %V\n" " wrapper: %V\n" " number of values: %d", - what, + CHAPERONE_KIND_STR(px), o, post, c); @@ -4031,7 +4027,7 @@ Scheme_Object *scheme_apply_chaperone(Scheme_Object *o, int argc, Scheme_Object " wrapper: %V\n" " expected: %d\n" " received: %d", - what, + CHAPERONE_KIND_STR(px), o, post, c, argc); From e8073e699edbf6fd8c7dfff19e2a6921af92ce5c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 22 Dec 2015 14:15:28 -0700 Subject: [PATCH 226/369] restore a fast path for a procedure chaperone When the representation of a redirect changed, the fast path wasn't updated. --- racket/src/racket/src/fun.c | 15 ++++++++++++++- racket/src/racket/src/schnapp.inc | 5 +++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/racket/src/racket/src/fun.c b/racket/src/racket/src/fun.c index 7de6aba075..5053cb3115 100644 --- a/racket/src/racket/src/fun.c +++ b/racket/src/racket/src/fun.c @@ -3750,7 +3750,20 @@ Scheme_Object *scheme_apply_chaperone(Scheme_Object *o, int argc, Scheme_Object /* communicate `self_proc` to the next layer: */ scheme_current_thread->self_for_proc_chaperone = self_proc; } - return _scheme_tail_apply(px->prev, argc, argv); + if (checks) { + /* cannot return a tail call */ + MZ_CONT_MARK_POS -= 2; + if (checks & 0x1) { + v = _scheme_apply(px->prev, argc, argv); + } else if (SAME_TYPE(SCHEME_TYPE(px->prev), scheme_native_closure_type)) { + v = _apply_native(px->prev, argc, argv); + } else { + v = _scheme_apply_multi(px->prev, argc, argv); + } + MZ_CONT_MARK_POS += 2; + return v; + } else + return _scheme_tail_apply(px->prev, argc, argv); } /* Ensure that the original procedure accepts `argc' arguments: */ diff --git a/racket/src/racket/src/schnapp.inc b/racket/src/racket/src/schnapp.inc index 31a4fc6d82..a3d585406d 100644 --- a/racket/src/racket/src/schnapp.inc +++ b/racket/src/racket/src/schnapp.inc @@ -62,8 +62,9 @@ Scheme_Object *PRIM_APPLY_NAME(Scheme_Object *rator, if (t == scheme_prim_type) { return PRIM_APPLY_NAME_FAST(rator, argc, argv); - } if ((t == scheme_proc_chaperone_type) - && SCHEME_MPAIRP(((Scheme_Chaperone *)rator)->redirects)) { + } else if ((t == scheme_proc_chaperone_type) + && SCHEME_VECTORP(((Scheme_Chaperone *)rator)->redirects) + && (SCHEME_VEC_SIZE(((Scheme_Chaperone *)rator)->redirects) & 0x1)) { return scheme_apply_chaperone(rator, argc, argv, NULL, PRIM_CHECK_MULTI | (PRIM_CHECK_VALUE << 1)); } } From b794404333d44c419e08de40650316bac07e943c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 22 Dec 2015 14:33:39 -0700 Subject: [PATCH 227/369] faster path for a procedure impersonator w/o wrapper proc Make the call path faster when an impersontor is present on a procedure only to add impersonator properties. --- racket/src/racket/src/schnapp.inc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/racket/src/racket/src/schnapp.inc b/racket/src/racket/src/schnapp.inc index a3d585406d..c0d1e7f26e 100644 --- a/racket/src/racket/src/schnapp.inc +++ b/racket/src/racket/src/schnapp.inc @@ -60,12 +60,19 @@ Scheme_Object *PRIM_APPLY_NAME(Scheme_Object *rator, t = _SCHEME_TYPE(rator); + if ((t == scheme_proc_chaperone_type) + && SCHEME_VECTORP(((Scheme_Chaperone *)rator)->redirects) + && (SCHEME_VEC_SIZE(((Scheme_Chaperone *)rator)->redirects) & 0x1)) { + if (SCHEME_FALSEP(SCHEME_VEC_ELS(((Scheme_Chaperone *)rator)->redirects)[0])) { + /* No redirection proc (i.e, chaperone is just for properties) */ + rator = ((Scheme_Chaperone *)rator)->prev; + t = _SCHEME_TYPE(rator); + } else + return scheme_apply_chaperone(rator, argc, argv, NULL, PRIM_CHECK_MULTI | (PRIM_CHECK_VALUE << 1)); + } + if (t == scheme_prim_type) { return PRIM_APPLY_NAME_FAST(rator, argc, argv); - } else if ((t == scheme_proc_chaperone_type) - && SCHEME_VECTORP(((Scheme_Chaperone *)rator)->redirects) - && (SCHEME_VEC_SIZE(((Scheme_Chaperone *)rator)->redirects) & 0x1)) { - return scheme_apply_chaperone(rator, argc, argv, NULL, PRIM_CHECK_MULTI | (PRIM_CHECK_VALUE << 1)); } } From 592ae853e39934df17141fff5808d2798e4f3649 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 22 Dec 2015 15:03:49 -0700 Subject: [PATCH 228/369] JIT: fast path for procedure impersonator w/o wrapper proc Make the JIT-generated function-call dispatch recognize a call to an impersonator that wraps a procedure only to hold properties. This change also repairs handling for a arity-reducing wrapper on a primitive, where the fast path incorrecty treated the primitive as a JIT-generated function. --- racket/src/racket/src/jitcall.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/racket/src/racket/src/jitcall.c b/racket/src/racket/src/jitcall.c index 2951c232b7..44bc298bcf 100644 --- a/racket/src/racket/src/jitcall.c +++ b/racket/src/racket/src/jitcall.c @@ -66,6 +66,7 @@ static Scheme_Object *clear_runstack(Scheme_Object **rs, intptr_t amt, Scheme_Ob static jit_insn *generate_proc_struct_retry(mz_jit_state *jitter, int num_rands, GC_CAN_IGNORE jit_insn *refagain) { GC_CAN_IGNORE jit_insn *ref2, *refz1, *refz2, *refz3, *refz4, *refz5; + GC_CAN_IGNORE jit_insn *refz6, *refz7, *refz8; ref2 = jit_bnei_i(jit_forward(), JIT_R1, scheme_proc_struct_type); jit_ldxi_p(JIT_R1, JIT_V1, &((Scheme_Structure *)0x0)->stype); @@ -109,11 +110,27 @@ static jit_insn *generate_proc_struct_retry(mz_jit_state *jitter, int num_rands, (void)jit_jmpi(refagain); CHECK_LIMIT(); + mz_patch_branch(ref2); + /* check for a procedure impersonator that just keeps properties */ + ref2 = jit_bnei_i(jit_forward(), JIT_R1, scheme_proc_chaperone_type); + jit_ldxi_p(JIT_R1, JIT_V1, &((Scheme_Chaperone *)0x0)->redirects); + refz6 = mz_bnei_t(jit_forward(), JIT_R1, scheme_vector_type, JIT_R2); + (void)jit_ldxi_l(JIT_R2, JIT_R1, &SCHEME_VEC_SIZE(0x0)); + refz7 = jit_bmci_i(jit_forward(), JIT_R2, 0x1); + (void)jit_ldxi_l(JIT_R2, JIT_R1, &(SCHEME_VEC_ELS(0x0)[0])); + refz8 = jit_bnei_p(jit_forward(), JIT_R2, scheme_false); + /* Can extract the impersonated function and use it directly */ + jit_ldxi_p(JIT_V1, JIT_V1, &((Scheme_Chaperone *)0x0)->prev); + (void)jit_jmpi(refagain); + mz_patch_branch(refz1); mz_patch_branch(refz2); mz_patch_branch(refz3); mz_patch_branch(refz4); mz_patch_branch(refz5); + mz_patch_branch(refz6); + mz_patch_branch(refz7); + mz_patch_branch(refz8); return ref2; } @@ -347,10 +364,12 @@ int scheme_generate_tail_call(mz_jit_state *jitter, int num_rands, int direct_na must be >= 0 */ { int i, r2_has_runstack = 0; - GC_CAN_IGNORE jit_insn *refagain, *ref, *ref2, *ref4, *ref5; + GC_CAN_IGNORE jit_insn *top_refagain, *refagain, *ref, *ref2, *ref4, *ref5; __START_SHORT_JUMPS__(num_rands < 100); + top_refagain = jit_get_ip(); + /* First, try fast direct jump to native code: */ if (!direct_native) { ref = jit_bmsi_ul(jit_forward(), JIT_V1, 0x1); @@ -474,7 +493,7 @@ int scheme_generate_tail_call(mz_jit_state *jitter, int num_rands, int direct_na /* Handle simple applicable struct: */ mz_patch_branch(ref2); /* uses JIT_R1: */ - ref2 = generate_proc_struct_retry(jitter, num_rands, refagain); + ref2 = generate_proc_struct_retry(jitter, num_rands, top_refagain); CHECK_LIMIT(); } @@ -767,7 +786,7 @@ int scheme_generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direc if num_rands != -3, need to pop runstack before returning. If num_rands == -1 or -3, skip prolog. */ GC_CAN_IGNORE jit_insn *ref, *ref2, *ref4, *ref5, *ref6, *ref7, *ref8, *ref9; - GC_CAN_IGNORE jit_insn *ref10, *refagain; + GC_CAN_IGNORE jit_insn *ref10, *refagain, *top_refagain; GC_CAN_IGNORE jit_insn *refrts USED_ONLY_FOR_FUTURES; #ifndef FUEL_AUTODECEREMENTS GC_CAN_IGNORE jit_insn *ref11; @@ -785,6 +804,8 @@ int scheme_generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direc } } + top_refagain = jit_get_ip(); + /* Check for inlined native type */ if (!direct_native) { ref = jit_bmsi_ul(jit_forward(), JIT_V1, 0x1); @@ -1029,7 +1050,7 @@ int scheme_generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direc if (!is_inlined && (num_rands >= 0)) { mz_patch_branch(ref2); /* uses JIT_R1 */ - ref2 = generate_proc_struct_retry(jitter, num_rands, refagain); + ref2 = generate_proc_struct_retry(jitter, num_rands, top_refagain); CHECK_LIMIT(); } } else { From db0a6de1d2d5d3059ec971275b287860c5bda6e2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 23 Dec 2015 15:41:46 -0700 Subject: [PATCH 229/369] add `procedure-specialize` The `procedure-specialize` function is the identity function, but it provides a hint to the JIT to compile the body of a closure specifically for the values in the closure (as opposed to compiling the body generically for all closure instances). This hint is useful to the contract system, where a predicate is coerced to a projection with (lambda (p?) (procedure-specialize (lambda (v) (if (p? v) v ....)))) Specializing the projection to a given `p?` allows primitive predicates to be JIT-inlined in the projection's body. --- pkgs/base/info.rkt | 2 +- .../scribblings/reference/procedures.scrbl | 15 + .../contract/private/arrow-val-first.rkt | 3 +- .../collects/racket/contract/private/guts.rkt | 15 +- racket/src/racket/src/cstartup.inc | 3145 +++++++++-------- racket/src/racket/src/fun.c | 26 + racket/src/racket/src/jit.c | 188 +- racket/src/racket/src/jit.h | 7 +- racket/src/racket/src/jitcall.c | 7 +- racket/src/racket/src/jitinline.c | 17 +- racket/src/racket/src/jitstate.c | 13 +- racket/src/racket/src/schminc.h | 2 +- racket/src/racket/src/schpriv.h | 4 + racket/src/racket/src/schvers.h | 4 +- 14 files changed, 1805 insertions(+), 1643 deletions(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index fb0415ec89..61f22b809d 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.3.0.9") +(define version "6.3.0.10") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/pkgs/racket-doc/scribblings/reference/procedures.scrbl b/pkgs/racket-doc/scribblings/reference/procedures.scrbl index ac3ee93956..8e784b4852 100644 --- a/pkgs/racket-doc/scribblings/reference/procedures.scrbl +++ b/pkgs/racket-doc/scribblings/reference/procedures.scrbl @@ -487,6 +487,21 @@ field of @racket[v] applied to @racket[v1] and @racket[v2] produces and @racket[v2], and its result is returned by @racket[checked-procedure-check-and-extract].} + +@defproc[(procedure-specialize [proc procedure?]) + procedure?]{ + +Returns @racket[proc] or its equivalent, but provides a hint to the +run-time system that it should spend extra time and memory to +specialize the implementation of @racket[proc]. + +The hint is currently used when @racket[proc] is the value of a +@racket[lambda] or @racket[case-lambda] form that references variables +bound outside of the @racket[lambda] or @racket[case-lambda], and when +@racket[proc] has not been previously applied. + +@history[#:added "6.3.0.10"]} + @; ---------------------------------------------------------------------- @section{Reflecting on Primitives} diff --git a/racket/collects/racket/contract/private/arrow-val-first.rkt b/racket/collects/racket/contract/private/arrow-val-first.rkt index f8c0e94f40..8cd4477632 100644 --- a/racket/collects/racket/contract/private/arrow-val-first.rkt +++ b/racket/collects/racket/contract/private/arrow-val-first.rkt @@ -314,7 +314,8 @@ #,(if post post #'#f) #,(if rngs #'(list rb ...) #'#f))])) #`(λ (blame f regb ... optb ... kb ... okb ... rb ... #,@(if rest (list #'restb) '())) - #,body-proc))))) + (procedure-specialize + #,body-proc)))))) (define (make-checking-proc f blame pre original-mandatory-kwds kbs diff --git a/racket/collects/racket/contract/private/guts.rkt b/racket/collects/racket/contract/private/guts.rkt index dd2c556750..7a8f4ba1fc 100644 --- a/racket/collects/racket/contract/private/guts.rkt +++ b/racket/collects/racket/contract/private/guts.rkt @@ -613,13 +613,14 @@ (define p? (predicate-contract-pred ctc)) (define name (predicate-contract-name ctc)) (λ (blame) - (λ (v neg-party) - (if (p? v) - v - (raise-blame-error blame v #:missing-party neg-party - '(expected: "~s" given: "~e") - name - v))))) + (procedure-specialize + (λ (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/src/racket/src/cstartup.inc b/racket/src/racket/src/cstartup.inc index f7d3ca6dff..574a9b0113 100644 --- a/racket/src/racket/src/cstartup.inc +++ b/racket/src/racket/src/cstartup.inc @@ -1,1579 +1,1580 @@ { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,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,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,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,169,20,193,249,22, -157,4,80,143,42,39,251,22,90,2,19,248,22,169,20,199,249,22,80,2,4, -248,22,170,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,169, -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,169,20,201,251,22,90,2,19,2,22,2,22,249,22, -80,2,11,248,22,170,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,170,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,169,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,169,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,169,20,201,248,22, -170,20,198,27,248,22,164,4,194,249,22,80,248,22,90,248,22,81,196,248,22, -170,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,170,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,170,20,199,250,22,90,2,7,248,22, -90,248,22,81,199,250,22,91,2,8,248,22,170,20,201,248,22,170,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,170,20,199,250, -22,90,2,21,248,22,90,248,22,81,199,250,22,91,2,9,248,22,170,20,201, -248,22,170,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,170,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,169,20,199,250,22,91,2,5,249,22, -90,2,26,249,22,90,248,22,111,203,2,26,248,22,170,20,202,251,22,90,2, -19,28,249,22,169,9,248,22,158,4,248,22,169,20,200,66,101,108,115,101,10, -248,22,169,20,197,250,22,91,2,21,9,248,22,170,20,200,249,22,80,2,5, -248,22,170,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,169,20,199,248,22,102,198,27, -248,22,158,4,248,22,169,20,197,250,22,90,2,27,248,22,90,248,22,81,197, -250,22,91,2,24,248,22,170,20,199,248,22,170,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, 2090); + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,8,54,46,51,46,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, +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,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,165,4,195,249,22,158,4,80,143,42,39,251,22, +91,2,19,248,22,103,199,12,249,22,81,2,20,248,22,105,201,27,248,22,165, +4,195,249,22,158,4,80,143,42,39,251,22,91,2,19,248,22,103,199,249,22, +81,2,20,248,22,105,201,12,27,248,22,83,248,22,165,4,196,28,248,22,89, +193,20,14,144,40,39,40,28,248,22,89,248,22,83,194,248,22,170,20,193,249, +22,158,4,80,143,42,39,251,22,91,2,19,248,22,170,20,199,249,22,81,2, +4,248,22,171,20,201,11,18,143,10,2,28,27,248,22,83,248,22,165,4,196, +28,248,22,89,193,20,14,144,40,39,40,28,248,22,89,248,22,83,194,248,22, +170,20,193,249,22,158,4,80,143,42,39,250,22,91,2,21,248,22,91,249,22, +91,248,22,91,2,22,248,22,170,20,201,251,22,91,2,19,2,22,2,22,249, +22,81,2,11,248,22,171,20,204,18,143,11,2,28,248,22,165,4,193,27,248, +22,165,4,194,249,22,81,248,22,91,248,22,82,196,248,22,171,20,195,27,248, +22,83,248,22,165,4,23,197,1,249,22,158,4,80,143,42,39,28,248,22,65, +248,22,159,4,248,22,82,23,198,2,27,249,22,2,32,0,88,148,8,36,40, +46,11,9,222,33,43,248,22,165,4,248,22,103,23,200,2,250,22,91,2,23, +248,22,91,249,22,91,248,22,91,248,22,170,20,23,204,2,250,22,92,2,24, +249,22,2,22,82,23,204,2,248,22,105,23,206,2,249,22,81,248,22,170,20, +23,202,1,249,22,2,22,103,23,200,1,250,22,92,2,21,249,22,2,32,0, +88,148,8,36,40,50,11,9,222,33,44,248,22,165,4,248,22,170,20,201,248, +22,171,20,198,27,248,22,165,4,194,249,22,81,248,22,91,248,22,82,196,248, +22,171,20,195,27,248,22,83,248,22,165,4,23,197,1,249,22,158,4,80,143, +42,39,250,22,92,2,23,249,22,2,32,0,88,148,8,36,40,50,11,9,222, +33,46,248,22,165,4,248,22,82,201,248,22,171,20,198,27,248,22,83,248,22, +165,4,196,27,248,22,165,4,248,22,82,195,249,22,158,4,80,143,43,39,28, +248,22,89,195,250,22,92,2,21,9,248,22,171,20,199,250,22,91,2,7,248, +22,91,248,22,82,199,250,22,92,2,8,248,22,171,20,201,248,22,171,20,202, +27,248,22,83,248,22,165,4,196,27,248,22,165,4,248,22,82,195,249,22,158, +4,80,143,43,39,28,248,22,89,195,250,22,92,2,21,9,248,22,171,20,199, +250,22,91,2,21,248,22,91,248,22,82,199,250,22,92,2,9,248,22,171,20, +201,248,22,171,20,202,27,248,22,83,248,22,165,4,23,197,1,27,249,22,1, +22,95,249,22,2,22,165,4,248,22,165,4,248,22,82,199,248,22,186,4,249, +22,158,4,80,143,44,39,251,22,91,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,92,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,92,2,21,9, +248,22,171,20,204,27,248,22,83,248,22,165,4,196,28,248,22,89,193,20,14, +144,40,39,40,249,22,158,4,80,143,42,39,27,248,22,165,4,248,22,82,197, +28,249,22,170,9,64,61,62,248,22,159,4,248,22,103,196,250,22,91,2,21, +248,22,91,249,22,91,21,93,2,26,248,22,170,20,199,250,22,92,2,5,249, +22,91,2,26,249,22,91,248,22,112,203,2,26,248,22,171,20,202,251,22,91, +2,19,28,249,22,170,9,248,22,159,4,248,22,170,20,200,66,101,108,115,101, +10,248,22,170,20,197,250,22,92,2,21,9,248,22,171,20,200,249,22,81,2, +5,248,22,171,20,202,18,143,94,10,66,118,111,105,100,2,28,27,248,22,83, +248,22,165,4,196,249,22,158,4,80,143,42,39,28,248,22,65,248,22,159,4, +248,22,82,197,250,22,91,2,27,248,22,91,248,22,170,20,199,248,22,103,198, +27,248,22,159,4,248,22,170,20,197,250,22,91,2,27,248,22,91,248,22,82, +197,250,22,92,2,24,248,22,171,20,199,248,22,171,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, 2091); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,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,91,6,121,6,212,9,235,9, -252,9,176,11,23,12,37,12,241,12,217,14,226,14,235,14,249,14,3,15,23, -16,126,16,251,16,68,17,141,17,243,17,16,18,87,18,221,18,36,19,243,19, -105,20,118,20,236,20,249,20,100,21,167,21,180,21,191,21,87,22,205,22,249, -22,104,23,182,25,206,25,68,26,150,27,157,27,209,27,222,27,212,28,228,28, -83,29,242,29,249,29,126,31,203,31,220,31,120,32,140,32,200,32,207,32,67, -33,121,33,140,33,91,34,107,34,68,35,69,36,106,36,115,36,202,37,47,40, -63,40,130,40,151,40,171,40,191,40,248,40,221,43,187,44,203,44,174,45,232, -45,9,46,141,46,44,47,60,47,157,47,174,47,252,49,47,52,63,52,37,54, -225,54,227,54,254,54,14,55,30,55,127,55,194,56,126,57,142,57,151,57,158, -57,224,58,34,60,152,60,198,63,72,64,204,64,149,66,99,67,141,67,249,67, -0,0,197,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,178,15,194,28,192,192,28,248,22,153,7,194,27,248,22,137,16,195,28, -192,192,248,22,138,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,179,15,23,195,2,10,28,248,22,178,15,23,195,2,10, -28,248,22,153,7,23,195,2,28,248,22,137,16,23,195,2,10,248,22,138,16, -23,195,2,11,12,250,22,182,11,2,41,2,42,23,197,2,28,28,248,22,179, -15,23,195,2,249,22,169,9,248,22,180,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,183,15,23,197,2,28,249,22,175,16,2,79,23,195,2,28,248,22, -153,7,195,248,22,186,15,195,194,86,94,23,195,1,27,248,22,128,8,23,195, -1,249,22,187,15,248,22,168,8,250,22,183,16,2,80,28,249,22,175,16,2, -81,23,201,2,23,199,1,250,22,183,16,2,82,23,202,1,2,44,80,144,47, -40,41,2,43,28,248,22,153,7,194,248,22,186,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,178,15,23,195,2,10,28,248,22,153, -7,23,195,2,28,248,22,137,16,23,195,2,10,248,22,138,16,23,195,2,11, -10,248,22,179,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,178,15,23,196,2,10,28,248,22,153,7,23,196, -2,28,248,22,137,16,23,196,2,10,248,22,138,16,23,196,2,11,10,248,22, -179,15,23,196,2,12,252,22,182,11,2,6,2,45,40,23,199,2,23,200,2, -27,28,248,22,179,15,23,196,2,248,22,180,15,23,196,2,247,22,181,15,86, -95,28,28,248,22,139,16,23,196,2,10,249,22,169,9,247,22,181,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,181,15,28,249,22,169, -9,28,248,22,179,15,23,199,2,248,22,180,15,23,199,2,247,22,181,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,143,16,28,248,22,139,16,23,199,2,23, -198,1,248,22,140,16,23,199,1,86,94,28,28,248,22,179,15,23,194,2,10, -28,248,22,178,15,23,194,2,10,28,248,22,153,7,23,194,2,28,248,22,137, -16,23,194,2,10,248,22,138,16,23,194,2,11,12,250,22,182,11,2,41,2, -42,23,196,2,28,28,248,22,179,15,23,194,2,249,22,169,9,248,22,180,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,183,15,23,196,2,28,249,22,175, -16,2,79,23,195,2,28,248,22,153,7,194,248,22,186,15,194,193,86,94,23, -194,1,27,248,22,128,8,23,195,1,249,22,187,15,248,22,168,8,250,22,183, -16,2,80,28,249,22,175,16,2,81,23,201,2,23,199,1,250,22,183,16,2, -82,23,202,1,2,44,80,144,50,40,41,2,43,28,248,22,153,7,193,248,22, -186,15,193,192,27,248,22,183,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,179,15,198,197,248, -22,186,15,198,249,22,132,16,199,249,22,187,15,249,22,153,8,248,22,183,15, -200,40,198,86,94,23,194,1,28,249,22,169,9,23,197,2,2,43,249,22,132, -16,23,200,1,249,22,187,15,28,249,22,175,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,175,16,2,84,23,199,2,249,22,154,8,2,47,249, -22,153,8,200,43,28,249,22,175,16,2,84,23,199,2,249,22,154,8,2,47, -249,22,153,8,200,43,28,249,22,175,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,175,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,141,16,23,196,2,28,249,22,171,9,23,195,2,23,197,1,11,28, -248,22,137,16,23,194,2,27,249,22,132,16,23,197,1,23,196,1,28,23,197, -2,90,144,42,11,89,146,42,39,11,248,22,135,16,23,197,2,86,95,23,195, -1,23,194,1,27,28,23,202,2,27,248,22,141,16,23,199,2,28,249,22,171, -9,23,195,2,23,200,2,11,28,248,22,137,16,23,194,2,250,2,86,23,205, -2,23,206,2,249,22,132,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,178, -15,23,196,2,27,249,22,132,16,23,198,2,23,205,2,28,28,248,22,191,15, -193,10,248,22,190,15,193,192,11,11,28,23,193,2,192,86,94,23,193,1,28, -23,203,2,11,27,248,22,141,16,23,200,2,28,249,22,171,9,194,23,201,1, -11,28,248,22,137,16,193,250,2,86,205,206,249,22,132,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,135,16,23,197,2,86,95,23,195,1,23,194,1,27,28,23,201,2, -27,248,22,141,16,23,199,2,28,249,22,171,9,23,195,2,23,200,2,11,28, -248,22,137,16,23,194,2,250,2,86,23,204,2,23,205,2,249,22,132,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,178,15,23,196,2,27,249,22,132,16, -23,198,2,23,204,2,28,28,248,22,191,15,193,10,248,22,190,15,193,192,11, -11,28,23,193,2,192,86,94,23,193,1,28,23,202,2,11,27,248,22,141,16, -23,200,2,28,249,22,171,9,194,23,201,1,11,28,248,22,137,16,193,250,2, -86,204,205,249,22,132,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,135,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,178,15,195,27,249, -22,132,16,197,200,28,28,248,22,191,15,193,10,248,22,190,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,132,16,248, -22,140,16,248,22,81,23,201,2,23,196,2,28,248,22,190,15,23,194,2,250, -2,86,197,198,195,86,94,23,193,1,27,248,22,170,20,23,199,1,28,248,22, -88,23,194,2,11,27,249,22,132,16,248,22,140,16,248,22,81,23,198,2,23, -198,2,28,248,22,190,15,23,194,2,250,2,86,199,200,195,86,94,23,193,1, -27,248,22,170,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,132,16, -248,22,140,16,248,22,81,23,198,2,23,200,2,28,248,22,190,15,23,194,2, -250,2,86,201,202,195,86,94,23,193,1,27,248,22,170,20,23,196,1,28,248, -22,88,23,194,2,11,27,249,22,132,16,248,22,140,16,248,22,81,197,201,28, -248,22,190,15,193,250,2,86,203,204,195,251,2,90,203,204,205,248,22,170,20, -198,86,95,28,28,248,22,178,15,23,195,2,10,28,248,22,153,7,23,195,2, -28,248,22,137,16,23,195,2,10,248,22,138,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,178,15,23,196, -2,10,28,248,22,153,7,23,196,2,28,248,22,137,16,23,196,2,10,248,22, -138,16,23,196,2,11,248,22,137,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,137,16,23,195,2,90,144, -42,11,89,146,42,39,11,248,22,135,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,187,15,5,1, -46,23,196,1,23,194,1,28,248,22,88,23,194,2,11,27,249,22,132,16,248, -22,140,16,248,22,81,23,198,2,23,200,2,28,248,22,190,15,23,194,2,250, -2,86,201,202,195,86,94,23,193,1,27,248,22,170,20,23,196,1,28,248,22, -88,23,194,2,11,27,249,22,132,16,248,22,140,16,248,22,81,23,198,2,23, -202,2,28,248,22,190,15,23,194,2,250,2,86,203,204,195,86,94,23,193,1, -27,248,22,170,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,132,16, -248,22,140,16,248,22,81,23,198,2,23,204,2,28,248,22,190,15,23,194,2, -250,2,86,205,206,195,86,94,23,193,1,27,248,22,170,20,23,196,1,28,248, -22,88,23,194,2,11,27,249,22,132,16,248,22,140,16,248,22,81,197,205,28, -248,22,190,15,193,250,2,86,23,15,23,16,195,251,2,90,23,15,23,16,23, -17,248,22,170,20,198,27,248,22,140,16,23,196,1,28,248,22,190,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,171,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,171,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,183,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,187,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,183,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,187,15,195,9,27,28,249,22,169,9,247, -22,180,8,2,43,250,22,183,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,187,15,195,195,86,95,23, -195,1,23,193,1,27,28,249,22,169,9,247,22,180,8,2,43,250,22,183,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,187,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,178,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,35,80,144,8,35,47,40,249,22,31, -11,80,144,8,37,46,40,22,145,15,10,22,146,15,10,22,147,15,10,22,148, -15,11,22,149,15,11,22,153,15,10,22,152,15,11,22,154,15,10,22,151,15, -10,22,155,15,10,22,150,15,11,22,156,15,10,22,157,15,10,22,158,15,10, -22,159,15,11,22,160,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,178,15,23,195,2,10,28,248,22, -153,7,23,195,2,28,248,22,137,16,23,195,2,10,248,22,138,16,23,195,2, -11,12,250,22,182,11,23,196,2,2,48,23,197,2,28,248,22,137,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,178,15,23,195,2,10,28,248,22,153,7,23,195,2,28,248,22,137,16,23, -195,2,10,248,22,138,16,23,195,2,11,12,250,22,182,11,23,196,2,2,48, -23,197,2,28,248,22,137,16,23,195,2,12,251,22,184,11,23,197,1,2,53, -2,46,23,198,1,86,95,28,28,248,22,178,15,23,195,2,10,28,248,22,153, -7,23,195,2,28,248,22,137,16,23,195,2,10,248,22,138,16,23,195,2,11, -12,250,22,182,11,23,196,2,2,48,23,197,2,28,248,22,137,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, -182,11,23,196,1,2,54,23,197,1,86,94,28,28,248,22,178,15,23,194,2, -10,28,248,22,153,7,23,194,2,28,248,22,137,16,23,194,2,10,248,22,138, -16,23,194,2,11,12,250,22,182,11,2,15,2,48,23,196,2,28,248,22,137, -16,23,194,2,12,251,22,184,11,2,15,2,53,2,46,23,197,1,86,97,28, -28,248,22,178,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248,22,137, -16,23,196,2,10,248,22,138,16,23,196,2,11,12,250,22,182,11,2,15,2, -48,23,198,2,28,248,22,137,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,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,178,15,23,194,2,10,28,248,22,153, -7,23,194,2,28,248,22,137,16,23,194,2,10,248,22,138,16,23,194,2,11, -12,250,22,182,11,2,17,2,48,23,196,2,28,248,22,137,16,23,194,2,12, -251,22,184,11,2,17,2,53,2,46,23,197,1,86,99,28,28,248,22,178,15, -23,197,2,10,28,248,22,153,7,23,197,2,28,248,22,137,16,23,197,2,10, -248,22,138,16,23,197,2,11,12,250,22,182,11,2,17,2,48,23,199,2,28, -248,22,137,16,23,197,2,12,251,22,184,11,2,17,2,53,2,46,23,200,2, -28,28,248,22,178,15,23,198,2,10,28,248,22,153,7,23,198,2,28,248,22, -137,16,23,198,2,10,248,22,138,16,23,198,2,11,12,250,22,182,11,2,17, -2,48,23,200,2,28,248,22,137,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,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,155,16,2,55,28,248,22,139, -16,23,194,2,248,22,142,16,23,194,1,28,248,22,138,16,23,194,2,90,144, -42,11,89,146,42,39,11,248,22,135,16,249,22,140,16,250,80,144,49,43,42, -248,22,155,16,2,56,11,11,248,22,155,16,2,57,86,95,23,195,1,23,194, -1,248,22,142,16,249,22,140,16,23,199,1,23,196,1,27,250,80,144,44,43, -42,248,22,155,16,2,56,23,197,1,10,28,23,193,2,248,22,142,16,23,194, -1,11,249,80,144,41,55,40,39,80,144,41,8,40,42,27,248,22,155,16,2, -58,28,248,22,139,16,23,194,2,248,22,142,16,23,194,1,28,248,22,138,16, -23,194,2,90,144,42,11,89,146,42,39,11,248,22,135,16,249,22,140,16,250, -80,144,49,43,42,248,22,155,16,2,56,11,11,248,22,155,16,2,57,86,95, -23,195,1,23,194,1,248,22,142,16,249,22,140,16,23,199,1,23,196,1,27, -250,80,144,44,43,42,248,22,155,16,2,56,23,197,1,10,28,23,193,2,248, -22,142,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,35,80,144,8,36,47,40,249,22,31,11,80, -144,8,38,46,40,22,145,15,10,22,146,15,10,22,147,15,10,22,148,15,11, -22,149,15,11,22,153,15,10,22,152,15,11,22,154,15,10,22,151,15,10,22, -155,15,10,22,150,15,11,22,156,15,10,22,157,15,10,22,158,15,10,22,159, -15,11,22,160,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,132,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,190, -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,186,15, -23,196,1,28,248,22,139,16,23,194,2,192,249,22,140,16,23,195,1,27,247, -80,144,43,54,42,28,23,193,2,192,86,94,23,193,1,247,22,156,16,28,248, -22,142,8,23,195,2,27,248,22,187,15,23,196,1,28,248,22,139,16,23,194, -2,192,249,22,140,16,23,195,1,27,247,80,144,43,54,42,28,23,193,2,192, -86,94,23,193,1,247,22,156,16,28,248,22,178,15,23,195,2,28,248,22,139, -16,23,195,2,193,249,22,140,16,23,196,1,27,247,80,144,42,54,42,28,23, -193,2,192,86,94,23,193,1,247,22,156,16,193,27,248,22,155,16,2,55,28, -248,22,139,16,23,194,2,248,22,142,16,23,194,1,28,248,22,138,16,23,194, -2,90,144,42,11,89,146,42,39,11,248,22,135,16,249,22,140,16,250,80,144, -49,43,42,248,22,155,16,2,56,11,11,248,22,155,16,2,57,86,95,23,195, -1,23,194,1,248,22,142,16,249,22,140,16,23,199,1,23,196,1,27,250,80, -144,44,43,42,248,22,155,16,2,56,23,197,1,10,28,23,193,2,248,22,142, -16,23,194,1,11,28,248,22,139,16,23,195,2,193,249,22,140,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,156,16,28,248,22,139,16,23,195,2,248,22,142,16,23,195, -1,28,248,22,138,16,23,195,2,90,144,42,11,89,146,42,39,11,248,22,135, -16,249,22,140,16,250,80,144,48,43,42,248,22,155,16,2,56,11,11,248,22, -155,16,2,57,86,95,23,195,1,23,194,1,248,22,142,16,249,22,140,16,23, -200,1,23,196,1,27,250,80,144,43,43,42,248,22,155,16,2,56,23,198,1, -10,28,23,193,2,248,22,142,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,169,20,23,199,2,28,248,22, -153,7,23,194,2,27,248,22,186,15,23,195,1,28,248,22,139,16,23,194,2, -192,249,22,140,16,23,195,1,27,247,80,144,46,54,42,28,23,193,2,192,86, -94,23,193,1,247,22,156,16,28,248,22,142,8,23,194,2,27,248,22,187,15, -23,195,1,28,248,22,139,16,23,194,2,192,249,22,140,16,23,195,1,27,247, -80,144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22,156,16,28,248, -22,178,15,23,194,2,28,248,22,139,16,23,194,2,192,249,22,140,16,23,195, -1,27,247,80,144,45,54,42,28,23,193,2,192,86,94,23,193,1,247,22,156, -16,192,27,248,22,170,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,169,20,23,197,2,27, -248,22,170,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,169,20,23,197,2,249,80,144,49, -8,44,42,23,204,1,248,22,170,20,23,198,1,249,22,94,23,202,2,249,80, -144,49,8,44,42,23,204,1,248,22,170,20,23,198,1,249,22,94,23,199,2, -27,248,22,170,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,169,20,23,197,2,249,80,144, -49,8,44,42,23,204,1,248,22,170,20,23,198,1,249,22,94,23,202,2,249, -80,144,49,8,44,42,23,204,1,248,22,170,20,23,198,1,249,22,94,23,196, -2,27,248,22,170,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,169,20,23,197,2,27,248, -22,170,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,169,20,23,197,2,249,80,144,49,8, -44,42,23,204,1,248,22,170,20,23,198,1,249,22,94,23,202,2,249,80,144, -49,8,44,42,23,204,1,248,22,170,20,23,198,1,249,22,94,23,199,2,27, -248,22,170,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,169,20,23,197,2,249,80,144,49, -8,44,42,23,204,1,248,22,170,20,23,198,1,249,22,94,23,202,2,249,80, -144,49,8,44,42,23,204,1,248,22,170,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, -155,16,2,58,28,248,22,139,16,23,194,2,248,22,142,16,23,194,1,28,248, -22,138,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,135,16,249,22, -140,16,250,80,144,49,43,42,248,22,155,16,2,56,11,11,248,22,155,16,2, -57,86,95,23,195,1,23,194,1,248,22,142,16,249,22,140,16,23,199,1,23, -196,1,27,250,80,144,44,43,42,248,22,155,16,2,56,23,197,1,10,28,23, -193,2,248,22,142,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,132,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,132,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,186,15,23,195,1,28,248,22, -139,16,23,194,2,192,249,22,140,16,23,195,1,27,247,80,144,47,54,42,28, -23,193,2,192,86,94,23,193,1,247,22,156,16,28,248,22,142,8,23,194,2, -27,248,22,187,15,23,195,1,28,248,22,139,16,23,194,2,192,249,22,140,16, -23,195,1,27,247,80,144,47,54,42,28,23,193,2,192,86,94,23,193,1,247, -22,156,16,28,248,22,178,15,23,194,2,28,248,22,139,16,23,194,2,192,249, -22,140,16,23,195,1,27,247,80,144,46,54,42,28,23,193,2,192,86,94,23, -193,1,247,22,156,16,192,250,22,94,248,22,90,11,28,247,22,163,16,28,247, -22,164,16,248,22,90,250,22,132,16,248,22,155,16,2,61,250,22,158,2,23, -204,2,2,59,247,22,171,8,2,60,9,9,28,247,22,164,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,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,135,16,23,197,1,86,95,23,195,1, -23,194,1,28,248,22,178,15,23,194,2,28,248,22,191,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,135,16,23,197,1,86,95,23,195,1,23,194,1,28, -248,22,178,15,23,194,2,28,248,22,191,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,135,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,178,15, -23,194,2,28,248,22,191,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,135, -16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,178,15,23,194,2,28, -248,22,191,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,135,16,23,198,2,86,95,23,195,1, -23,194,1,28,248,22,178,15,23,194,2,28,248,22,191,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,135,16,23,197,1,86,95,23,195,1,23,194,1,28, -248,22,178,15,23,194,2,28,248,22,191,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,135,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,178,15, -23,194,2,28,248,22,191,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,135, -16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,178,15,23,194,2,28, -248,22,191,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,190,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,176,14,39,248,22,170,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,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,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,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,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,169,20,195,10,249,22,169,9,2,65,248,22, -169,20,195,28,27,248,22,102,194,28,248,22,178,15,193,10,28,248,22,153,7, -193,28,248,22,137,16,193,10,248,22,138,16,193,11,27,248,22,88,248,22,104, -195,28,192,192,248,22,184,16,248,22,111,195,11,11,11,11,28,248,22,191,15, -249,22,132,16,23,196,2,23,198,2,27,248,22,68,248,22,182,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,175,16, -248,22,111,23,198,2,247,22,171,8,27,248,22,142,16,249,22,140,16,248,22, -102,23,200,2,23,198,1,28,249,22,169,9,248,22,169,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,145,16,23,196,1,28,249,22,169,9,248,22, -169,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,169,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,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,135,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,170,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,35,80,144,8,40,47,40, -249,22,31,11,80,144,8,42,46,40,22,145,15,10,22,146,15,10,22,147,15, -10,22,148,15,11,22,149,15,11,22,153,15,10,22,152,15,11,22,154,15,10, -22,151,15,10,22,155,15,10,22,150,15,11,22,156,15,10,22,157,15,10,22, -158,15,10,22,159,15,11,22,160,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,49, -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,173,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,86,94,23,193,1,249,22,7,23,197,1,23, -198,1,90,144,42,11,89,146,42,39,11,248,22,135,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,173,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,86,94,23,193,1,249,22,7,23,197, -1,23,196,1,90,144,42,11,89,146,42,39,11,248,22,135,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, -169,20,23,197,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22,169, -20,23,204,2,23,202,2,9,250,22,158,2,248,22,169,20,23,202,2,11,9, -27,248,22,170,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,169,20,23,195,2,250,22,94,249,22,2,22, -129,2,250,22,158,2,248,22,169,20,23,202,2,23,206,2,9,250,22,158,2, -248,22,169,20,23,200,2,11,9,249,80,144,48,8,48,42,23,203,1,248,22, -170,20,23,199,1,27,248,80,144,45,8,30,42,248,22,169,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,170,20,23,200,1,249,22,94, -247,22,159,16,249,80,144,47,8,48,42,23,202,1,248,22,170,20,23,198,1, -27,248,80,144,41,8,30,42,248,22,169,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,170, -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,169,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22, -158,2,248,22,169,20,23,202,2,23,207,2,9,250,22,158,2,248,22,169,20, -23,200,2,11,9,249,80,144,49,8,48,42,23,204,1,248,22,170,20,23,199, -1,27,248,80,144,46,8,30,42,248,22,169,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,170,20,23,200,1,249,22,94,247,22,159,16, -249,80,144,48,8,48,42,23,203,1,248,22,170,20,23,198,1,249,22,94,247, -22,159,16,27,248,22,170,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,169,20,23,195,2,250,22,94,249, -22,2,22,129,2,250,22,158,2,248,22,169,20,23,202,2,23,205,2,9,250, -22,158,2,248,22,169,20,23,200,2,11,9,249,80,144,47,8,48,42,23,202, -1,248,22,170,20,23,199,1,27,248,80,144,44,8,30,42,248,22,169,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,170,20,23,200,1, -249,22,94,247,22,159,16,249,80,144,46,8,48,42,23,201,1,248,22,170,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,169,20,195,28,248,22,178, -15,193,248,22,182,15,193,192,250,22,91,27,248,22,169,20,23,198,2,28,248, -22,178,15,193,248,22,182,15,193,192,2,67,248,2,150,2,248,22,170,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,169,20,23,197,2,249,2,154,2,23,197,1,248,22,170,20,23,199, -1,249,2,154,2,23,195,1,248,22,170,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,132,16,202,199, -200,86,95,23,201,1,23,198,1,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,178,15,23, -202,2,248,22,182,15,23,202,1,23,201,1,250,22,176,7,28,248,22,178,15, -23,205,2,248,22,182,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,159,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,159,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,178,15,23,195,2,249,22,132,16,23,196,1,23,199,2,248,22,132,2, -23,195,1,28,28,248,22,178,15,248,22,169,20,23,204,2,248,22,191,15,23, -194,2,10,27,250,22,1,22,132,16,23,197,1,23,202,2,28,28,248,22,88, -23,200,2,10,248,22,191,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,178,15,202,248,22,182,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,86,94,23,195,1,11,28,23, -193,2,250,80,144,48,8,32,42,198,23,196,1,23,15,11,2,28,200,249,22, -132,16,194,202,192,26,8,80,144,50,8,49,42,204,205,206,23,15,23,16,23, -17,248,22,170,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,170,20,23,19,23,19,26,8,80, -144,49,8,49,42,203,204,205,206,23,15,23,16,248,22,170,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,178,15,195,248,22,182,15,195,194,27,27,247,22, -160,16,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248,22,149, -2,248,22,169,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2, -248,22,169,20,23,202,2,23,203,2,9,250,22,158,2,248,22,169,20,23,200, -2,11,9,249,80,144,49,8,48,42,23,200,1,248,22,170,20,23,199,1,27, -248,80,144,46,8,30,42,248,22,169,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,170,20,23,200,1,249,22,94,247,22,159,16,249,80, -144,48,8,48,42,23,199,1,248,22,170,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,188,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,184,11,2,37,2,69,2,70,202,192,28,248,22,179,15,198, -248,22,180,15,198,247,22,181,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,188,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,184,11,2,37,2,69,2,70, -202,192,28,248,22,179,15,198,248,22,180,15,198,247,22,181,15,250,2,158,2, -196,197,195,248,22,190,15,27,250,22,132,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,137,16,23,196, -2,249,22,132,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,190,15,249,22,132,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,184,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,179,15,195,249,22,132,16,196,194,192,27,247,22, -161,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,162,16,11,86,95,28,28,248, -22,179,15,23,194,2,10,28,248,22,178,15,23,194,2,10,28,248,22,153,7, -23,194,2,28,248,22,137,16,23,194,2,10,248,22,138,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,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,135,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,188,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,184,11,2,37,2,69,2,70,201,192, -28,248,22,179,15,197,248,22,180,15,197,247,22,181,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,188,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,184,11,2,37,2,69,2,70,204,192,28,248, -22,179,15,200,248,22,180,15,200,247,22,181,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,188,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,184,11,2,37,2,69, -2,70,204,192,28,248,22,179,15,200,248,22,180,15,200,247,22,181,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,188,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,184,11,2,37, -2,69,2,70,205,192,28,248,22,179,15,201,248,22,180,15,201,247,22,181,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,188,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,184,11,2,37,2,69,2,70,205,192,28,248,22,179,15,201,248,22,180, -15,201,247,22,181,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,179,15,23,199,2,10,28,248,22,178,15,23,199,2, -10,28,248,22,153,7,23,199,2,28,248,22,137,16,23,199,2,10,248,22,138, -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, -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,135,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,184,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, -188,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,184,11,2,37,2,69,2,70,23,17,192,28,248,22,179, -15,205,248,22,180,15,205,247,22,181,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,188,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,184,11,2,37,2,69,2,70, -23,17,192,28,248,22,179,15,205,248,22,180,15,205,247,22,181,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,179, -15,195,249,22,132,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,188,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,184,11,2,37,2,69,2,70,202, -192,28,248,22,179,15,198,248,22,180,15,198,247,22,181,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,188,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,184,11,2,37,2,69,2,70,202,192,28,248,22, -179,15,198,248,22,180,15,198,247,22,181,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,188,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,184, -11,2,37,2,69,2,70,203,192,28,248,22,179,15,199,248,22,180,15,199,247, -22,181,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,188,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,184,11,2,37,2, -69,2,70,203,192,28,248,22,179,15,199,248,22,180,15,199,247,22,181,15,251, -2,169,2,198,199,200,196,90,144,41,11,89,146,41,39,11,86,95,28,28,248, -22,179,15,23,196,2,10,28,248,22,178,15,23,196,2,10,28,248,22,153,7, -23,196,2,28,248,22,137,16,23,196,2,10,248,22,138,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,135,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,184,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,179,15,195,249, -22,132,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,188,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,184,11,2,37,2,69,2,70, -200,192,28,248,22,179,15,196,248,22,180,15,196,247,22,181,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,188,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,184,11,2,37,2,69,2,70,202, -192,28,248,22,179,15,198,248,22,180,15,198,247,22,181,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,188,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,184,11,2,37, -2,69,2,70,202,192,28,248,22,179,15,198,248,22,180,15,198,247,22,181,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,179,15, -23,196,2,10,28,248,22,178,15,23,196,2,10,28,248,22,153,7,23,196,2, -28,248,22,137,16,23,196,2,10,248,22,138,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,135,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,184,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,179,15,195,249,22,132,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,139,16,23,194,2,248,22,142,16, -23,194,1,28,248,22,138,16,23,194,2,90,144,42,11,89,146,42,39,11,248, -22,135,16,249,22,140,16,250,80,144,50,43,42,248,22,155,16,2,56,11,11, -248,22,155,16,2,57,86,95,23,195,1,23,194,1,248,22,142,16,249,22,140, -16,23,199,1,23,196,1,27,250,80,144,45,43,42,248,22,155,16,2,56,23, -197,1,10,28,23,193,2,248,22,142,16,23,194,1,11,28,23,193,2,249,22, -80,248,22,142,16,249,22,140,16,23,198,1,247,22,156,16,27,248,22,170,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,142,16,249,22,140,16,23,198,1, -247,22,156,16,248,80,144,47,8,50,42,248,22,170,20,23,198,1,86,94,23, -193,1,248,80,144,45,8,50,42,248,22,170,20,23,196,1,86,94,23,193,1, -27,248,22,170,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,142,16,249,22, -140,16,23,198,1,247,22,156,16,248,80,144,45,8,50,42,248,22,170,20,23, -198,1,86,94,23,193,1,248,80,144,43,8,50,42,248,22,170,20,23,196,1, -28,248,22,88,23,195,2,9,27,27,248,22,81,23,197,2,28,248,22,139,16, -23,194,2,248,22,142,16,23,194,1,28,248,22,138,16,23,194,2,90,144,42, -11,89,146,42,39,11,248,22,135,16,249,22,140,16,250,80,144,50,43,42,248, -22,155,16,2,56,11,11,248,22,155,16,2,57,86,95,23,195,1,23,194,1, -248,22,142,16,249,22,140,16,23,199,1,23,196,1,27,250,80,144,45,43,42, -248,22,155,16,2,56,23,197,1,10,28,23,193,2,248,22,142,16,23,194,1, -11,28,23,193,2,249,22,80,248,22,142,16,249,22,140,16,23,198,1,247,22, -156,16,27,248,22,170,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,142,16, -249,22,140,16,23,198,1,247,22,156,16,248,80,144,47,8,51,42,248,22,170, -20,23,198,1,86,94,23,193,1,248,80,144,45,8,51,42,248,22,170,20,23, -196,1,86,94,23,193,1,27,248,22,170,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,142,16,249,22,140,16,23,198,1,247,22,156,16,248,80,144,45,8, -51,42,248,22,170,20,23,198,1,86,94,23,193,1,248,80,144,43,8,51,42, -248,22,170,20,23,196,1,27,248,22,155,16,2,58,28,248,22,139,16,23,194, -2,248,22,142,16,23,194,1,28,248,22,138,16,23,194,2,90,144,42,11,89, -146,42,39,11,248,22,135,16,249,22,140,16,250,80,144,49,43,42,248,22,155, -16,2,56,11,11,248,22,155,16,2,57,86,95,23,195,1,23,194,1,248,22, -142,16,249,22,140,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22, -155,16,2,56,23,197,1,10,28,23,193,2,248,22,142,16,23,194,1,11,28, -248,22,88,23,195,2,9,27,27,248,22,81,23,197,2,28,248,22,139,16,23, -194,2,248,22,142,16,23,194,1,28,248,22,138,16,23,194,2,90,144,42,11, -89,146,42,39,11,248,22,135,16,249,22,140,16,250,80,144,50,43,42,248,22, -155,16,2,56,11,11,248,22,155,16,2,57,86,95,23,195,1,23,194,1,248, -22,142,16,249,22,140,16,23,199,1,23,196,1,27,250,80,144,45,43,42,248, -22,155,16,2,56,23,197,1,10,28,23,193,2,248,22,142,16,23,194,1,11, -28,23,193,2,249,22,80,248,22,142,16,249,22,140,16,23,198,1,247,22,156, -16,27,248,22,170,20,23,199,1,28,248,22,88,23,194,2,9,27,27,248,22, -81,23,196,2,28,248,22,139,16,23,194,2,248,22,142,16,23,194,1,28,248, -22,138,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,135,16,249,22, -140,16,250,80,144,54,43,42,248,22,155,16,2,56,11,11,248,22,155,16,2, -57,86,95,23,195,1,23,194,1,248,22,142,16,249,22,140,16,23,199,1,23, -196,1,27,250,80,144,49,43,42,248,22,155,16,2,56,23,197,1,10,28,23, -193,2,248,22,142,16,23,194,1,11,28,23,193,2,249,22,80,248,22,142,16, -249,22,140,16,23,198,1,247,22,156,16,27,248,22,170,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,142,16,249,22,140,16,23,198,1,247,22,156,16,248, -80,144,51,8,53,42,248,22,170,20,23,198,1,86,94,23,193,1,248,80,144, -49,8,53,42,248,22,170,20,23,196,1,86,94,23,193,1,27,248,22,170,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,142,16,249,22,140,16,23,198,1, -247,22,156,16,248,80,144,49,8,53,42,248,22,170,20,23,198,1,86,94,23, -193,1,248,80,144,47,8,53,42,248,22,170,20,23,196,1,86,94,23,193,1, -27,248,22,170,20,23,197,1,28,248,22,88,23,194,2,9,27,27,248,22,81, -23,196,2,28,248,22,139,16,23,194,2,248,22,142,16,23,194,1,28,248,22, -138,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,135,16,249,22,140, -16,250,80,144,52,43,42,248,22,155,16,2,56,11,11,248,22,155,16,2,57, -86,95,23,195,1,23,194,1,248,22,142,16,249,22,140,16,23,199,1,23,196, -1,27,250,80,144,47,43,42,248,22,155,16,2,56,23,197,1,10,28,23,193, -2,248,22,142,16,23,194,1,11,28,23,193,2,249,22,80,248,22,142,16,249, -22,140,16,23,198,1,247,22,156,16,27,248,22,170,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,142,16,249,22,140,16,23,198,1,247,22,156,16,248,80, -144,49,8,53,42,248,22,170,20,23,198,1,86,94,23,193,1,248,80,144,47, -8,53,42,248,22,170,20,23,196,1,86,94,23,193,1,27,248,22,170,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,142,16,249,22,140,16,23,198,1,247, -22,156,16,248,80,144,47,8,53,42,248,22,170,20,23,198,1,86,94,23,193, -1,248,80,144,45,8,53,42,248,22,170,20,23,196,1,27,247,22,163,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,132,16,248,22,155,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,155,16,2,55,9,28,193,249,22,80,195,194,192,27,247, -22,163,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,132,16,248,22,155,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,155,16,2,55,9,28,193,249,22, -80,195,194,192,27,247,22,163,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,132,16, -248,22,155,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,155,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,139,16,23,194,2,248,22,142,16,23,194,1,28,248,22,138,16,23, -194,2,90,144,42,11,89,146,42,39,11,248,22,135,16,249,22,140,16,250,80, -144,60,43,42,248,22,155,16,2,56,11,11,248,22,155,16,2,57,86,95,23, -195,1,23,194,1,248,22,142,16,249,22,140,16,23,199,1,23,196,1,27,250, -80,144,55,43,42,248,22,155,16,2,56,23,197,1,10,28,23,193,2,248,22, -142,16,23,194,1,11,28,23,193,2,249,22,80,248,22,142,16,249,22,140,16, -23,198,1,247,22,156,16,27,248,22,170,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,142,16,249,22,140,16,23,198,1,247,22,156,16,248,80,144,57,8, -53,42,248,22,170,20,23,198,1,86,94,23,193,1,248,80,144,55,8,53,42, -248,22,170,20,23,196,1,86,94,23,193,1,27,248,22,170,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,142,16,249,22,140,16,23,198,1,247,22,156,16, -248,80,144,55,8,53,42,248,22,170,20,23,198,1,86,94,23,193,1,248,80, -144,53,8,53,42,248,22,170,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,152,15,10,22,159,15,10,22,160,15,10,22,161,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,152,15,10,22,159,15,10,22,160,15,10,22,161,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,152,15,10,22,159,15,10,22,160,15,10, -22,161,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,155,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,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,167, -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,44,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,44,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, 19823); - } - { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,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,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,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,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, 576); - } - { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,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,29,11,59,11,110,11,185,11,201,11,217, -11,231,11,247,11,66,12,82,12,98,12,114,12,189,12,96,13,112,13,187,13, -182,14,62,15,137,15,44,16,57,16,210,16,138,17,181,17,7,18,140,18,201, -18,209,18,220,18,254,19,101,20,129,20,142,20,63,21,70,21,230,21,250,21, -94,22,116,22,126,22,140,22,178,22,21,23,25,23,32,23,238,23,157,32,210, -32,234,32,2,33,0,0,51,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,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,132,16,28,249,22,169,9,23,201,2,2,27,86,94,23, -199,1,23,200,1,28,248,22,137,16,23,200,2,249,22,132,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,150,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,132,16,28, -249,22,169,9,23,201,2,2,27,86,94,23,199,1,23,200,1,28,248,22,137, -16,23,200,2,249,22,132,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,150,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,132,16,28,249,22,169,9,23,199,2,2,27, -86,94,23,197,1,23,198,1,28,248,22,137,16,23,198,2,249,22,132,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,150,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,132,16,28,249,22,169,9,23,199, -2,2,27,86,94,23,197,1,23,198,1,28,248,22,137,16,23,198,2,249,22, -132,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,150,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,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,169,20,23,197,2,249, -22,4,22,64,248,22,170,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,132,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,178,15,23,197,2,23,196,1,86,94,23,196,1,247,22,156,16, -249,247,22,175,5,248,22,169,20,23,197,1,23,201,1,86,94,23,193,1,27, -28,248,22,139,16,23,199,2,23,198,2,27,247,22,177,5,28,192,249,22,140, -16,23,201,2,194,23,199,2,90,144,42,11,89,146,42,39,11,248,22,135,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,183,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,187,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,132,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,132,16,23,199, -2,23,198,2,86,95,23,200,1,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,161,16,27,247,22,162,16,27,250,22,150,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, -150,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,86,94,23,197,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,178, -15,23,206,2,23,205,1,86,94,23,205,1,247,22,156,16,249,247,22,166,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,86,94,23,198,1,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,178,15,23,207,2,23,206,1,86,94,23,206, -1,247,22,156,16,249,247,22,166,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,178,15,23, -208,2,23,207,1,86,94,23,207,1,247,22,156,16,249,247,22,175,5,248,22, -169,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,97,23, -209,1,23,204,1,23,203,1,23,199,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,178,15,23,209,2,23,208,1,86,94,23,208,1,247,22,156,16,249,247,22, -175,5,248,22,169,20,23,196,1,23,221,1,86,96,23,216,1,23,215,1,23, -193,1,28,28,248,22,78,23,220,2,248,22,169,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,190,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,178,15,23,210,2,23,209,1, -86,94,23,209,1,247,22,156,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,169,20,23,196,1,90,144,41,11,89,146,41,39,11,27,248,22,170,20,23, -197,2,28,248,22,88,248,22,82,23,195,2,249,22,7,9,248,22,169,20,195, -90,144,41,11,89,146,41,39,11,27,248,22,170,20,196,28,248,22,88,248,22, -82,23,195,2,249,22,7,9,248,22,169,20,195,90,144,41,11,89,146,41,39, -11,248,2,70,248,22,170,20,196,249,22,7,249,22,80,248,22,169,20,199,196, -195,249,22,7,249,22,80,248,22,169,20,199,196,195,249,22,7,249,22,80,248, -22,169,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,169,20,23,196,1,27,248,22,170,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,169,20,23,198,1,27,248,22,170,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,169,20,197,90,144,41,11,89,146,41,39,11,248,2,70,248,22,170, -20,198,249,22,7,249,22,80,248,22,169,20,201,196,195,249,22,7,249,22,80, -248,22,169,20,23,203,1,196,195,249,22,7,249,22,80,248,22,169,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,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,169,20,23,195,1,23,194,1,28,248,22,178,15, -23,194,2,90,144,42,11,89,146,42,39,11,248,22,135,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,86, -94,23,195,1,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,156,16,90,144,42,11,89,146,42,39, -11,248,22,135,16,23,198,2,86,95,23,195,1,23,193,1,28,249,22,171,16, -0,11,35,114,120,34,91,46,93,115,115,36,34,248,22,183,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,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,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,132,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,132,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,132,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,170,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,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,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,178,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,170,20,200,251,2,82,196,197,249,22,80, -248,22,169,20,202,200,248,22,170,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,182,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,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,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,182,15,248,22,103,23,198,2,248,2,90,248,22,170, -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,169,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,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,169,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,182,15,23,202,1,28,23,204,2,28, -250,22,158,2,248,22,169,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,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,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,169,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,169,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,169,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,169,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,169,20,23,197,2,23,196,2,27,28,249,22,171, -9,248,22,102,23,203,2,2,35,248,22,170,20,200,248,22,104,200,28,248,22, -78,23,198,2,249,22,94,248,22,170,20,199,194,192,28,28,248,22,78,23,196, -2,249,22,169,9,248,22,169,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, -169,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,169,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,169,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,169,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,170,20,23,202,1,248,22,104,23,202,1,28,248,22,78,23,195,2, -249,2,81,248,22,169,20,23,197,2,249,22,94,248,22,170,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,170,20,23,202,1,248,22,104,23,202,1, -28,248,22,78,193,248,22,170,20,193,11,86,94,23,198,1,11,86,94,23,198, -1,11,27,28,248,22,64,23,196,2,27,248,80,144,46,51,42,249,22,80,23, -199,2,248,22,132,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,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,132,16,23,198,1,248,2,86,23,197,1,250, -22,1,22,132,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, -178,15,23,196,2,86,94,23,196,1,248,80,144,45,8,30,42,248,22,142,16, -28,248,22,139,16,23,198,2,23,197,2,249,22,140,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,132,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,175,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,175, -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,170,20,23,199,1, -23,199,1,10,86,94,23,196,1,28,249,22,169,9,248,22,169,20,23,198,2, -2,37,248,80,144,45,8,30,42,248,22,142,16,249,22,140,16,248,22,144,16, -248,22,102,23,201,2,248,80,144,49,8,29,42,23,205,2,12,86,94,28,28, -248,22,178,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,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,142,16,248, -22,143,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,135,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,132,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,132,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,132,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,86,96,23,211,1,23,204,1,23,194,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,169,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,132,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,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,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, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,8,54,46,51,46,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,91,6,121,6,212,9,235, +9,252,9,176,11,23,12,37,12,241,12,217,14,226,14,235,14,249,14,3,15, +23,16,126,16,251,16,68,17,141,17,243,17,16,18,87,18,221,18,36,19,243, +19,105,20,118,20,236,20,249,20,100,21,167,21,180,21,191,21,87,22,205,22, +249,22,104,23,182,25,206,25,68,26,150,27,157,27,209,27,222,27,212,28,228, +28,83,29,242,29,249,29,126,31,203,31,220,31,120,32,140,32,200,32,207,32, +67,33,121,33,140,33,91,34,107,34,68,35,69,36,106,36,115,36,202,37,47, +40,63,40,130,40,151,40,171,40,191,40,248,40,221,43,187,44,203,44,174,45, +232,45,9,46,141,46,44,47,60,47,157,47,174,47,252,49,47,52,63,52,37, +54,225,54,227,54,254,54,14,55,30,55,127,55,194,56,126,57,142,57,151,57, +158,57,224,58,34,60,152,60,198,63,72,64,204,64,149,66,99,67,141,67,249, +67,0,0,197,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,179,15,194,28,192,192,28,248,22,154,7,194,27,248,22,138,16,195, +28,192,192,248,22,139,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,180,15,23,195,2,10,28,248,22,179,15,23,195,2, +10,28,248,22,154,7,23,195,2,28,248,22,138,16,23,195,2,10,248,22,139, +16,23,195,2,11,12,250,22,183,11,2,41,2,42,23,197,2,28,28,248,22, +180,15,23,195,2,249,22,170,9,248,22,181,15,23,197,2,2,43,249,22,170, +9,247,22,181,8,2,43,27,28,248,22,154,7,23,196,2,23,195,2,248,22, +166,8,248,22,184,15,23,197,2,28,249,22,176,16,2,79,23,195,2,28,248, +22,154,7,195,248,22,187,15,195,194,86,94,23,195,1,27,248,22,129,8,23, +195,1,249,22,188,15,248,22,169,8,250,22,184,16,2,80,28,249,22,176,16, +2,81,23,201,2,23,199,1,250,22,184,16,2,82,23,202,1,2,44,80,144, +47,40,41,2,43,28,248,22,154,7,194,248,22,187,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,179,15,23,195,2,10,28,248,22, +154,7,23,195,2,28,248,22,138,16,23,195,2,10,248,22,139,16,23,195,2, +11,10,248,22,180,15,23,195,2,12,252,22,183,11,2,6,2,45,39,23,199, +2,23,200,2,28,28,28,248,22,179,15,23,196,2,10,28,248,22,154,7,23, +196,2,28,248,22,138,16,23,196,2,10,248,22,139,16,23,196,2,11,10,248, +22,180,15,23,196,2,12,252,22,183,11,2,6,2,45,40,23,199,2,23,200, +2,27,28,248,22,180,15,23,196,2,248,22,181,15,23,196,2,247,22,182,15, +86,95,28,28,248,22,140,16,23,196,2,10,249,22,170,9,247,22,182,15,23, +195,2,12,253,22,185,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,182,15,28,249,22, +170,9,28,248,22,180,15,23,199,2,248,22,181,15,23,199,2,247,22,182,15, +23,195,2,12,253,22,185,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,144,16,28,248,22,140,16,23,199,2, +23,198,1,248,22,141,16,23,199,1,86,94,28,28,248,22,180,15,23,194,2, +10,28,248,22,179,15,23,194,2,10,28,248,22,154,7,23,194,2,28,248,22, +138,16,23,194,2,10,248,22,139,16,23,194,2,11,12,250,22,183,11,2,41, +2,42,23,196,2,28,28,248,22,180,15,23,194,2,249,22,170,9,248,22,181, +15,23,196,2,2,43,249,22,170,9,247,22,181,8,2,43,27,28,248,22,154, +7,23,195,2,23,194,2,248,22,166,8,248,22,184,15,23,196,2,28,249,22, +176,16,2,79,23,195,2,28,248,22,154,7,194,248,22,187,15,194,193,86,94, +23,194,1,27,248,22,129,8,23,195,1,249,22,188,15,248,22,169,8,250,22, +184,16,2,80,28,249,22,176,16,2,81,23,201,2,23,199,1,250,22,184,16, +2,82,23,202,1,2,44,80,144,50,40,41,2,43,28,248,22,154,7,193,248, +22,187,15,193,192,27,248,22,184,15,23,195,2,28,249,22,170,9,23,197,2, +66,117,110,105,120,28,249,22,151,8,194,5,1,47,28,248,22,180,15,198,197, +248,22,187,15,198,249,22,133,16,199,249,22,188,15,249,22,154,8,248,22,184, +15,200,40,198,86,94,23,194,1,28,249,22,170,9,23,197,2,2,43,249,22, +133,16,23,200,1,249,22,188,15,28,249,22,176,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,155,8,2,47,250,22,154,8,203,43,44,5,1,92,249, +22,154,8,202,45,28,249,22,176,16,2,84,23,199,2,249,22,155,8,2,47, +249,22,154,8,200,43,28,249,22,176,16,2,84,23,199,2,249,22,155,8,2, +47,249,22,154,8,200,43,28,249,22,176,16,0,14,35,114,120,34,94,92,92, +92,92,92,92,92,92,34,23,199,2,249,22,155,8,5,4,85,78,67,92,249, +22,154,8,200,41,28,249,22,176,16,0,12,35,114,120,34,94,91,97,45,122, +93,58,34,198,249,22,155,8,250,22,154,8,201,39,40,249,22,154,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,142,16,23,196,2,28,249,22,172,9,23,195,2,23,197,1,11, +28,248,22,138,16,23,194,2,27,249,22,133,16,23,197,1,23,196,1,28,23, +197,2,90,144,42,11,89,146,42,39,11,248,22,136,16,23,197,2,86,95,23, +195,1,23,194,1,27,28,23,202,2,27,248,22,142,16,23,199,2,28,249,22, +172,9,23,195,2,23,200,2,11,28,248,22,138,16,23,194,2,250,2,86,23, +205,2,23,206,2,249,22,133,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, +179,15,23,196,2,27,249,22,133,16,23,198,2,23,205,2,28,28,248,22,128, +16,193,10,248,22,191,15,193,192,11,11,28,23,193,2,192,86,94,23,193,1, +28,23,203,2,11,27,248,22,142,16,23,200,2,28,249,22,172,9,194,23,201, +1,11,28,248,22,138,16,193,250,2,86,205,206,249,22,133,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,136,16,23,197,2,86,95,23,195,1,23,194,1,27,28,23,201, +2,27,248,22,142,16,23,199,2,28,249,22,172,9,23,195,2,23,200,2,11, +28,248,22,138,16,23,194,2,250,2,86,23,204,2,23,205,2,249,22,133,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,179,15,23,196,2,27,249,22,133, +16,23,198,2,23,204,2,28,28,248,22,128,16,193,10,248,22,191,15,193,192, +11,11,28,23,193,2,192,86,94,23,193,1,28,23,202,2,11,27,248,22,142, +16,23,200,2,28,249,22,172,9,194,23,201,1,11,28,248,22,138,16,193,250, +2,86,204,205,249,22,133,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,136,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,179,15,195,27, +249,22,133,16,197,200,28,28,248,22,128,16,193,10,248,22,191,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,89,23,197,2,11,27,249,22,133,16, +248,22,141,16,248,22,82,23,201,2,23,196,2,28,248,22,191,15,23,194,2, +250,2,86,197,198,195,86,94,23,193,1,27,248,22,171,20,23,199,1,28,248, +22,89,23,194,2,11,27,249,22,133,16,248,22,141,16,248,22,82,23,198,2, +23,198,2,28,248,22,191,15,23,194,2,250,2,86,199,200,195,86,94,23,193, +1,27,248,22,171,20,23,196,1,28,248,22,89,23,194,2,11,27,249,22,133, +16,248,22,141,16,248,22,82,23,198,2,23,200,2,28,248,22,191,15,23,194, +2,250,2,86,201,202,195,86,94,23,193,1,27,248,22,171,20,23,196,1,28, +248,22,89,23,194,2,11,27,249,22,133,16,248,22,141,16,248,22,82,197,201, +28,248,22,191,15,193,250,2,86,203,204,195,251,2,90,203,204,205,248,22,171, +20,198,86,95,28,28,248,22,179,15,23,195,2,10,28,248,22,154,7,23,195, +2,28,248,22,138,16,23,195,2,10,248,22,139,16,23,195,2,11,12,250,22, +183,11,2,7,2,48,23,197,2,28,28,23,195,2,28,28,248,22,179,15,23, +196,2,10,28,248,22,154,7,23,196,2,28,248,22,138,16,23,196,2,10,248, +22,139,16,23,196,2,11,248,22,138,16,23,196,2,11,10,12,250,22,183,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,138,16,23,195,2,90, +144,42,11,89,146,42,39,11,248,22,136,16,23,198,2,249,22,170,9,194,2, +49,11,27,249,22,176,8,247,22,175,8,5,4,80,65,84,72,27,28,23,194, +2,249,80,143,43,44,249,22,166,8,23,198,1,7,63,9,86,94,23,194,1, +9,27,28,249,22,170,9,247,22,181,8,2,43,249,22,81,248,22,188,15,5, +1,46,23,196,1,23,194,1,28,248,22,89,23,194,2,11,27,249,22,133,16, +248,22,141,16,248,22,82,23,198,2,23,200,2,28,248,22,191,15,23,194,2, +250,2,86,201,202,195,86,94,23,193,1,27,248,22,171,20,23,196,1,28,248, +22,89,23,194,2,11,27,249,22,133,16,248,22,141,16,248,22,82,23,198,2, +23,202,2,28,248,22,191,15,23,194,2,250,2,86,203,204,195,86,94,23,193, +1,27,248,22,171,20,23,196,1,28,248,22,89,23,194,2,11,27,249,22,133, +16,248,22,141,16,248,22,82,23,198,2,23,204,2,28,248,22,191,15,23,194, +2,250,2,86,205,206,195,86,94,23,193,1,27,248,22,171,20,23,196,1,28, +248,22,89,23,194,2,11,27,249,22,133,16,248,22,141,16,248,22,82,197,205, +28,248,22,191,15,193,250,2,86,23,15,23,16,195,251,2,90,23,15,23,16, +23,17,248,22,171,20,198,27,248,22,141,16,23,196,1,28,248,22,191,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,172,16,23,197,2,23,198,2,28,23,193, +2,86,94,23,196,1,27,248,22,103,23,195,2,27,27,248,22,112,23,197,1, +27,249,22,172,16,23,201,2,23,196,2,28,23,193,2,86,94,23,194,1,27, +248,22,103,23,195,2,27,250,2,95,202,23,204,1,248,22,112,23,199,1,27, +28,249,22,170,9,247,22,181,8,2,43,250,22,184,16,2,96,23,198,1,2, +51,194,28,249,22,151,8,194,2,51,249,22,95,202,195,249,22,81,248,22,188, +15,195,195,86,95,23,199,1,23,193,1,27,28,249,22,170,9,247,22,181,8, +2,43,250,22,184,16,2,96,23,198,1,2,51,194,28,249,22,151,8,194,2, +51,249,22,95,200,9,249,22,81,248,22,188,15,195,9,27,28,249,22,170,9, +247,22,181,8,2,43,250,22,184,16,2,96,23,198,1,2,51,194,28,249,22, +151,8,194,2,51,249,22,95,198,195,249,22,81,248,22,188,15,195,195,86,95, +23,195,1,23,193,1,27,28,249,22,170,9,247,22,181,8,2,43,250,22,184, +16,2,96,23,200,1,2,51,196,28,249,22,151,8,194,2,51,249,22,95,196, +9,249,22,81,248,22,188,15,195,9,86,95,28,28,248,22,143,8,194,10,248, +22,154,7,194,12,250,22,183,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,90,195, +249,22,4,22,179,15,196,11,12,250,22,183,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,154, +7,197,248,22,168,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,35,80,144,8,35,47,40,249,22, +31,11,80,144,8,37,46,40,22,146,15,10,22,147,15,10,22,148,15,10,22, +149,15,11,22,150,15,11,22,154,15,10,22,153,15,11,22,155,15,10,22,152, +15,10,22,156,15,10,22,151,15,11,22,157,15,10,22,158,15,10,22,159,15, +10,22,160,15,11,22,161,15,10,22,144,15,11,247,23,194,1,250,22,183,11, +2,9,2,52,23,197,1,86,94,28,28,248,22,179,15,23,195,2,10,28,248, +22,154,7,23,195,2,28,248,22,138,16,23,195,2,10,248,22,139,16,23,195, +2,11,12,250,22,183,11,23,196,2,2,48,23,197,2,28,248,22,138,16,23, +195,2,12,251,22,185,11,23,197,1,2,53,2,46,23,198,1,86,94,28,28, +248,22,179,15,23,195,2,10,28,248,22,154,7,23,195,2,28,248,22,138,16, +23,195,2,10,248,22,139,16,23,195,2,11,12,250,22,183,11,23,196,2,2, +48,23,197,2,28,248,22,138,16,23,195,2,12,251,22,185,11,23,197,1,2, +53,2,46,23,198,1,86,95,28,28,248,22,179,15,23,195,2,10,28,248,22, +154,7,23,195,2,28,248,22,138,16,23,195,2,10,248,22,139,16,23,195,2, +11,12,250,22,183,11,23,196,2,2,48,23,197,2,28,248,22,138,16,23,195, +2,86,94,23,194,1,12,251,22,185,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,183,11,23,196,1,2,54,23,197,1,86,94,28,28,248,22,179,15,23,194, +2,10,28,248,22,154,7,23,194,2,28,248,22,138,16,23,194,2,10,248,22, +139,16,23,194,2,11,12,250,22,183,11,2,15,2,48,23,196,2,28,248,22, +138,16,23,194,2,12,251,22,185,11,2,15,2,53,2,46,23,197,1,86,97, +28,28,248,22,179,15,23,196,2,10,28,248,22,154,7,23,196,2,28,248,22, +138,16,23,196,2,10,248,22,139,16,23,196,2,11,12,250,22,183,11,2,15, +2,48,23,198,2,28,248,22,138,16,23,196,2,12,251,22,185,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,183,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,179,15,23,194,2,10,28,248,22, +154,7,23,194,2,28,248,22,138,16,23,194,2,10,248,22,139,16,23,194,2, +11,12,250,22,183,11,2,17,2,48,23,196,2,28,248,22,138,16,23,194,2, +12,251,22,185,11,2,17,2,53,2,46,23,197,1,86,99,28,28,248,22,179, +15,23,197,2,10,28,248,22,154,7,23,197,2,28,248,22,138,16,23,197,2, +10,248,22,139,16,23,197,2,11,12,250,22,183,11,2,17,2,48,23,199,2, +28,248,22,138,16,23,197,2,12,251,22,185,11,2,17,2,53,2,46,23,200, +2,28,28,248,22,179,15,23,198,2,10,28,248,22,154,7,23,198,2,28,248, +22,138,16,23,198,2,10,248,22,139,16,23,198,2,11,12,250,22,183,11,2, +17,2,48,23,200,2,28,248,22,138,16,23,198,2,12,251,22,185,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,183,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,156,16,2,55,28,248,22, +140,16,23,194,2,248,22,143,16,23,194,1,28,248,22,139,16,23,194,2,90, +144,42,11,89,146,42,39,11,248,22,136,16,249,22,141,16,250,80,144,49,43, +42,248,22,156,16,2,56,11,11,248,22,156,16,2,57,86,95,23,195,1,23, +194,1,248,22,143,16,249,22,141,16,23,199,1,23,196,1,27,250,80,144,44, +43,42,248,22,156,16,2,56,23,197,1,10,28,23,193,2,248,22,143,16,23, +194,1,11,249,80,144,41,55,40,39,80,144,41,8,40,42,27,248,22,156,16, +2,58,28,248,22,140,16,23,194,2,248,22,143,16,23,194,1,28,248,22,139, +16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,136,16,249,22,141,16, +250,80,144,49,43,42,248,22,156,16,2,56,11,11,248,22,156,16,2,57,86, +95,23,195,1,23,194,1,248,22,143,16,249,22,141,16,23,199,1,23,196,1, +27,250,80,144,44,43,42,248,22,156,16,2,56,23,197,1,10,28,23,193,2, +248,22,143,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,35,80,144,8,36,47,40,249,22,31,11, +80,144,8,38,46,40,22,146,15,10,22,147,15,10,22,148,15,10,22,149,15, +11,22,150,15,11,22,154,15,10,22,153,15,11,22,155,15,10,22,152,15,10, +22,156,15,10,22,151,15,11,22,157,15,10,22,158,15,10,22,159,15,10,22, +160,15,11,22,161,15,10,22,144,15,11,247,22,149,6,28,248,22,150,2,193, +192,11,27,28,23,195,2,249,22,133,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, +191,15,23,195,2,249,22,141,6,23,196,1,80,144,43,8,42,42,11,11,28, +192,192,21,17,1,0,250,22,159,2,23,196,1,2,59,247,22,172,8,250,22, +159,2,195,2,59,247,22,172,8,28,248,22,154,7,23,195,2,27,248,22,187, +15,23,196,1,28,248,22,140,16,23,194,2,192,249,22,141,16,23,195,1,27, +247,80,144,43,54,42,28,23,193,2,192,86,94,23,193,1,247,22,157,16,28, +248,22,143,8,23,195,2,27,248,22,188,15,23,196,1,28,248,22,140,16,23, +194,2,192,249,22,141,16,23,195,1,27,247,80,144,43,54,42,28,23,193,2, +192,86,94,23,193,1,247,22,157,16,28,248,22,179,15,23,195,2,28,248,22, +140,16,23,195,2,193,249,22,141,16,23,196,1,27,247,80,144,42,54,42,28, +23,193,2,192,86,94,23,193,1,247,22,157,16,193,27,248,22,156,16,2,55, +28,248,22,140,16,23,194,2,248,22,143,16,23,194,1,28,248,22,139,16,23, +194,2,90,144,42,11,89,146,42,39,11,248,22,136,16,249,22,141,16,250,80, +144,49,43,42,248,22,156,16,2,56,11,11,248,22,156,16,2,57,86,95,23, +195,1,23,194,1,248,22,143,16,249,22,141,16,23,199,1,23,196,1,27,250, +80,144,44,43,42,248,22,156,16,2,56,23,197,1,10,28,23,193,2,248,22, +143,16,23,194,1,11,28,248,22,140,16,23,195,2,193,249,22,141,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,157,16,28,248,22,140,16,23,195,2,248,22,143,16,23, +195,1,28,248,22,139,16,23,195,2,90,144,42,11,89,146,42,39,11,248,22, +136,16,249,22,141,16,250,80,144,48,43,42,248,22,156,16,2,56,11,11,248, +22,156,16,2,57,86,95,23,195,1,23,194,1,248,22,143,16,249,22,141,16, +23,200,1,23,196,1,27,250,80,144,43,43,42,248,22,156,16,2,56,23,198, +1,10,28,23,193,2,248,22,143,16,23,194,1,11,28,248,22,89,23,196,2, +9,28,248,22,82,23,196,2,249,22,81,27,248,22,170,20,23,199,2,28,248, +22,154,7,23,194,2,27,248,22,187,15,23,195,1,28,248,22,140,16,23,194, +2,192,249,22,141,16,23,195,1,27,247,80,144,46,54,42,28,23,193,2,192, +86,94,23,193,1,247,22,157,16,28,248,22,143,8,23,194,2,27,248,22,188, +15,23,195,1,28,248,22,140,16,23,194,2,192,249,22,141,16,23,195,1,27, +247,80,144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22,157,16,28, +248,22,179,15,23,194,2,28,248,22,140,16,23,194,2,192,249,22,141,16,23, +195,1,27,247,80,144,45,54,42,28,23,193,2,192,86,94,23,193,1,247,22, +157,16,192,27,248,22,171,20,23,199,1,28,248,22,89,23,194,2,9,28,248, +22,82,23,194,2,249,22,81,248,80,144,45,60,42,248,22,170,20,23,197,2, +27,248,22,171,20,23,197,1,28,248,22,89,23,194,2,9,28,248,22,82,23, +194,2,249,22,81,248,80,144,48,60,42,248,22,170,20,23,197,2,249,80,144, +49,8,44,42,23,204,1,248,22,171,20,23,198,1,249,22,95,23,202,2,249, +80,144,49,8,44,42,23,204,1,248,22,171,20,23,198,1,249,22,95,23,199, +2,27,248,22,171,20,23,197,1,28,248,22,89,23,194,2,9,28,248,22,82, +23,194,2,249,22,81,248,80,144,48,60,42,248,22,170,20,23,197,2,249,80, +144,49,8,44,42,23,204,1,248,22,171,20,23,198,1,249,22,95,23,202,2, +249,80,144,49,8,44,42,23,204,1,248,22,171,20,23,198,1,249,22,95,23, +196,2,27,248,22,171,20,23,199,1,28,248,22,89,23,194,2,9,28,248,22, +82,23,194,2,249,22,81,248,80,144,45,60,42,248,22,170,20,23,197,2,27, +248,22,171,20,23,197,1,28,248,22,89,23,194,2,9,28,248,22,82,23,194, +2,249,22,81,248,80,144,48,60,42,248,22,170,20,23,197,2,249,80,144,49, +8,44,42,23,204,1,248,22,171,20,23,198,1,249,22,95,23,202,2,249,80, +144,49,8,44,42,23,204,1,248,22,171,20,23,198,1,249,22,95,23,199,2, +27,248,22,171,20,23,197,1,28,248,22,89,23,194,2,9,28,248,22,82,23, +194,2,249,22,81,248,80,144,48,60,42,248,22,170,20,23,197,2,249,80,144, +49,8,44,42,23,204,1,248,22,171,20,23,198,1,249,22,95,23,202,2,249, +80,144,49,8,44,42,23,204,1,248,22,171,20,23,198,1,27,250,22,159,2, +23,198,1,23,199,1,11,28,192,249,80,144,42,8,44,42,198,194,196,27,248, +22,156,16,2,58,28,248,22,140,16,23,194,2,248,22,143,16,23,194,1,28, +248,22,139,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,136,16,249, +22,141,16,250,80,144,49,43,42,248,22,156,16,2,56,11,11,248,22,156,16, +2,57,86,95,23,195,1,23,194,1,248,22,143,16,249,22,141,16,23,199,1, +23,196,1,27,250,80,144,44,43,42,248,22,156,16,2,56,23,197,1,10,28, +23,193,2,248,22,143,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,159,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,133,16,27,250,22,159,2,23,202,2,71,115,104,97,114,101,45, +100,105,114,11,28,192,192,249,22,133,16,64,117,112,6,5,5,115,104,97,114, +101,2,60,28,248,22,154,7,23,194,2,27,248,22,187,15,23,195,1,28,248, +22,140,16,23,194,2,192,249,22,141,16,23,195,1,27,247,80,144,47,54,42, +28,23,193,2,192,86,94,23,193,1,247,22,157,16,28,248,22,143,8,23,194, +2,27,248,22,188,15,23,195,1,28,248,22,140,16,23,194,2,192,249,22,141, +16,23,195,1,27,247,80,144,47,54,42,28,23,193,2,192,86,94,23,193,1, +247,22,157,16,28,248,22,179,15,23,194,2,28,248,22,140,16,23,194,2,192, +249,22,141,16,23,195,1,27,247,80,144,46,54,42,28,23,193,2,192,86,94, +23,193,1,247,22,157,16,192,250,22,95,248,22,91,11,28,247,22,164,16,28, +247,22,165,16,248,22,91,250,22,133,16,248,22,156,16,2,61,250,22,159,2, +23,204,2,2,59,247,22,172,8,2,60,9,9,28,247,22,165,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,91,23,200,1,9,248,22,175,13,23,194,1,249, +22,14,80,144,41,8,26,41,28,248,22,131,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,136,16,23,197,1,86,95,23,195, +1,23,194,1,28,248,22,179,15,23,194,2,28,248,22,128,16,23,194,2,249, +22,146,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,136,16,23,197,1,86,95,23,195,1,23,194,1, +28,248,22,179,15,23,194,2,28,248,22,128,16,23,194,2,249,22,146,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,136,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,179, +15,23,194,2,28,248,22,128,16,23,194,2,249,22,146,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, +136,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,179,15,23,194,2, +28,248,22,128,16,23,194,2,249,22,146,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,164,6,8,128,128,23,196, +2,28,248,22,149,7,23,194,2,9,249,22,81,23,195,1,27,249,22,164,6, +8,128,128,23,199,2,28,248,22,149,7,23,194,2,9,249,22,81,23,195,1, +27,249,22,164,6,8,128,128,23,202,2,28,248,22,149,7,23,194,2,9,249, +22,81,23,195,1,27,249,22,164,6,8,128,128,23,205,2,28,248,22,149,7, +23,194,2,9,249,22,81,23,195,1,248,2,128,2,23,206,1,27,249,22,164, +6,8,128,128,23,196,2,28,248,22,143,8,23,194,2,28,249,22,133,4,248, +22,148,8,23,196,2,8,128,128,249,22,1,22,155,8,249,22,81,23,197,1, +27,249,22,164,6,8,128,128,23,201,2,28,248,22,149,7,23,194,2,9,249, +22,81,23,195,1,27,249,22,164,6,8,128,128,23,204,2,28,248,22,149,7, +23,194,2,9,249,22,81,23,195,1,27,249,22,164,6,8,128,128,23,207,2, +28,248,22,149,7,23,194,2,9,249,22,81,23,195,1,27,249,22,164,6,8, +128,128,23,210,2,28,248,22,149,7,23,194,2,9,249,22,81,23,195,1,248, +2,128,2,23,211,1,192,192,248,22,134,6,23,194,1,20,13,144,80,144,40, +8,28,40,80,144,40,8,46,42,27,28,249,22,190,8,248,22,181,8,2,62, +41,90,144,42,11,89,146,42,39,11,248,22,136,16,23,198,2,86,95,23,195, +1,23,194,1,28,248,22,179,15,23,194,2,28,248,22,128,16,23,194,2,249, +22,146,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,136,16,23,197,1,86,95,23,195,1,23,194,1, +28,248,22,179,15,23,194,2,28,248,22,128,16,23,194,2,249,22,146,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,136,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,179, +15,23,194,2,28,248,22,128,16,23,194,2,249,22,146,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, +136,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,179,15,23,194,2, +28,248,22,128,16,23,194,2,249,22,146,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,191, +15,23,195,2,27,28,249,22,190,8,248,22,181,8,2,62,41,249,22,146,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,148,6,23,195,1,86,94,23,194,1,12,249,22,81,27,248,22,189, +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,81,11,194,28,28,23,195,2,28,248,22,83,23,196,2,248,22,168,9, +249,22,177,14,39,248,22,171,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,168,9,194,28,192,192,248,22,168,9,248,22,82,195,86,95,28,248,22,152, +12,23,198,2,27,247,22,144,12,28,249,22,134,12,23,195,2,2,63,251,22, +140,12,23,197,1,2,63,250,22,138,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,148,12, +23,206,2,247,22,27,12,12,28,23,193,2,250,22,157,2,80,144,45,8,25, +41,23,198,1,249,22,81,23,198,1,21,17,0,0,86,95,23,195,1,23,193, +1,12,28,248,22,152,12,23,198,2,86,94,23,197,1,248,23,195,1,247,22, +139,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,149,6,23,194,2,28,248,22,149,7,248,22,149,6, +23,195,1,12,248,22,179,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,134,6,23,194,1,28,248,22,90,193,28,28,249,22,129,4,41,248,22,94, +195,10,249,22,129,4,42,248,22,94,195,28,28,248,22,154,7,248,22,82,194, +10,28,249,22,170,9,2,64,248,22,170,20,195,10,249,22,170,9,2,65,248, +22,170,20,195,28,27,248,22,103,194,28,248,22,179,15,193,10,28,248,22,154, +7,193,28,248,22,138,16,193,10,248,22,139,16,193,11,27,248,22,89,248,22, +105,195,28,192,192,248,22,185,16,248,22,112,195,11,11,11,11,28,248,22,128, +16,249,22,133,16,23,196,2,23,198,2,27,248,22,69,248,22,183,15,23,198, +1,250,22,157,2,23,198,2,23,196,2,249,22,81,23,199,1,250,22,159,2, +23,203,1,23,201,1,9,12,250,22,157,2,23,197,1,23,198,1,249,22,81, +23,198,1,23,201,1,28,28,248,22,89,248,22,105,23,197,2,10,249,22,176, +16,248,22,112,23,198,2,247,22,172,8,27,248,22,143,16,249,22,141,16,248, +22,103,23,200,2,23,198,1,28,249,22,170,9,248,22,170,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,146,16,23,196,1,28,249,22,170,9,248, +22,170,20,23,199,2,2,64,86,94,23,196,1,86,94,28,250,22,159,2,23, +197,2,11,11,12,250,22,157,2,23,197,2,11,9,249,22,165,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,69,248,22,170,20,23,199,1,250,22,157,2,23,198,2,23, +196,2,249,22,81,248,22,130,2,23,200,1,250,22,159,2,23,203,1,23,201, +1,9,12,250,22,157,2,23,196,1,23,197,1,248,22,96,23,199,1,27,28, +28,23,194,2,248,22,168,9,248,22,82,23,196,2,10,9,27,249,22,189,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,90,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,179,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,139,2,27,90,144,42,11,89,146,42,39,11,248,22,136,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,165,2,195,88,148,8,36,41,51,11,9, +223,3,33,143,2,250,22,157,2,80,144,47,8,25,41,23,200,1,249,22,81, +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,159,2,80,144,44,8,25,41,23,197,2, +21,143,11,17,0,0,27,248,22,82,23,195,2,27,249,80,144,45,8,27,42, +23,198,2,23,196,2,28,249,22,172,9,23,195,2,23,196,1,248,22,171,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,35,80,144,8,40,47, +40,249,22,31,11,80,144,8,42,46,40,22,146,15,10,22,147,15,10,22,148, +15,10,22,149,15,11,22,150,15,11,22,154,15,10,22,153,15,11,22,155,15, +10,22,152,15,10,22,156,15,10,22,151,15,11,22,157,15,10,22,158,15,10, +22,159,15,10,22,160,15,11,22,161,15,10,22,144,15,11,247,23,193,1,250, +22,183,11,2,9,2,52,23,196,1,248,22,8,20,20,94,88,148,39,40,8, +49,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,154,7,23,195, +2,27,249,22,174,16,2,147,2,23,197,2,28,23,193,2,28,249,22,129,4, +248,22,102,23,196,2,248,22,183,3,248,22,157,7,23,199,2,249,22,7,250, +22,176,7,23,200,1,39,248,22,102,23,199,1,23,198,1,249,22,7,250,22, +176,7,23,200,2,39,248,22,102,23,199,2,249,22,81,249,22,176,7,23,201, +1,248,22,104,23,200,1,23,200,1,86,94,23,193,1,249,22,7,23,197,1, +23,198,1,90,144,42,11,89,146,42,39,11,248,22,136,16,23,198,1,86,94, +23,195,1,28,249,22,170,9,23,195,2,2,49,86,94,23,193,1,249,22,7, +23,196,1,23,200,1,27,249,22,81,23,197,1,23,201,1,28,248,22,154,7, +23,195,2,27,249,22,174,16,2,147,2,23,197,2,28,23,193,2,28,249,22, +129,4,248,22,102,23,196,2,248,22,183,3,248,22,157,7,23,199,2,249,22, +7,250,22,176,7,23,200,1,39,248,22,102,23,199,1,23,196,1,249,22,7, +250,22,176,7,23,200,2,39,248,22,102,23,199,2,249,22,81,249,22,176,7, +23,201,1,248,22,104,23,200,1,23,198,1,86,94,23,193,1,249,22,7,23, +197,1,23,196,1,90,144,42,11,89,146,42,39,11,248,22,136,16,23,198,1, +86,94,23,195,1,28,249,22,170,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,81,197,199, +28,248,22,89,23,196,2,9,28,248,22,82,23,196,2,28,248,22,150,2,248, +22,170,20,23,197,2,250,22,95,249,22,2,22,130,2,250,22,159,2,248,22, +170,20,23,204,2,23,202,2,9,250,22,159,2,248,22,170,20,23,202,2,11, +9,27,248,22,171,20,23,200,1,28,248,22,89,23,194,2,9,28,248,22,82, +23,194,2,28,248,22,150,2,248,22,170,20,23,195,2,250,22,95,249,22,2, +22,130,2,250,22,159,2,248,22,170,20,23,202,2,23,206,2,9,250,22,159, +2,248,22,170,20,23,200,2,11,9,249,80,144,48,8,48,42,23,203,1,248, +22,171,20,23,199,1,27,248,80,144,45,8,30,42,248,22,170,20,23,196,2, +250,22,95,250,22,159,2,23,199,2,23,205,2,9,250,22,159,2,23,199,1, +11,9,249,80,144,49,8,48,42,23,204,1,248,22,171,20,23,200,1,249,22, +95,247,22,160,16,249,80,144,47,8,48,42,23,202,1,248,22,171,20,23,198, +1,27,248,80,144,41,8,30,42,248,22,170,20,23,198,2,250,22,95,250,22, +159,2,23,199,2,23,201,2,9,250,22,159,2,23,199,1,11,9,27,248,22, +171,20,23,201,1,28,248,22,89,23,194,2,9,28,248,22,82,23,194,2,28, +248,22,150,2,248,22,170,20,23,195,2,250,22,95,249,22,2,22,130,2,250, +22,159,2,248,22,170,20,23,202,2,23,207,2,9,250,22,159,2,248,22,170, +20,23,200,2,11,9,249,80,144,49,8,48,42,23,204,1,248,22,171,20,23, +199,1,27,248,80,144,46,8,30,42,248,22,170,20,23,196,2,250,22,95,250, +22,159,2,23,199,2,23,206,2,9,250,22,159,2,23,199,1,11,9,249,80, +144,50,8,48,42,23,205,1,248,22,171,20,23,200,1,249,22,95,247,22,160, +16,249,80,144,48,8,48,42,23,203,1,248,22,171,20,23,198,1,249,22,95, +247,22,160,16,27,248,22,171,20,23,199,1,28,248,22,89,23,194,2,9,28, +248,22,82,23,194,2,28,248,22,150,2,248,22,170,20,23,195,2,250,22,95, +249,22,2,22,130,2,250,22,159,2,248,22,170,20,23,202,2,23,205,2,9, +250,22,159,2,248,22,170,20,23,200,2,11,9,249,80,144,47,8,48,42,23, +202,1,248,22,171,20,23,199,1,27,248,80,144,44,8,30,42,248,22,170,20, +23,196,2,250,22,95,250,22,159,2,23,199,2,23,204,2,9,250,22,159,2, +23,199,1,11,9,249,80,144,48,8,48,42,23,203,1,248,22,171,20,23,200, +1,249,22,95,247,22,160,16,249,80,144,46,8,48,42,23,201,1,248,22,171, +20,23,198,1,32,150,2,88,148,8,36,40,50,11,2,50,222,33,151,2,28, +248,22,89,248,22,83,23,195,2,248,22,91,27,248,22,170,20,195,28,248,22, +179,15,193,248,22,183,15,193,192,250,22,92,27,248,22,170,20,23,198,2,28, +248,22,179,15,193,248,22,183,15,193,192,2,67,248,2,150,2,248,22,171,20, +23,198,1,250,22,138,8,6,7,7,10,32,126,97,32,126,97,6,1,1,32, +23,196,1,249,22,138,8,6,6,6,10,32,32,32,126,97,248,22,133,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,89,23,195,2,9,28,248,23,194,2,248,22,82,23,196,2,249, +22,81,248,22,170,20,23,197,2,249,2,154,2,23,197,1,248,22,171,20,23, +199,1,249,2,154,2,23,195,1,248,22,171,20,23,197,1,28,248,22,89,23, +201,2,86,95,23,200,1,23,199,1,28,23,201,2,28,197,249,22,133,16,202, +199,200,86,95,23,201,1,23,198,1,27,28,248,22,89,23,198,2,2,66,249, +22,1,22,177,7,248,2,150,2,23,200,2,248,23,199,1,251,22,138,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,89,23,203,1,28,248,22,179,15, +23,202,2,248,22,183,15,23,202,1,23,201,1,250,22,177,7,28,248,22,179, +15,23,205,2,248,22,183,15,23,205,1,23,204,1,2,67,23,201,2,249,22, +1,22,177,7,249,22,2,32,0,88,148,8,36,40,48,11,9,222,33,152,2, +27,248,22,94,23,206,2,27,248,22,94,247,22,160,16,28,249,22,130,4,249, +22,185,3,23,198,2,23,197,2,44,23,206,2,249,22,95,247,22,160,16,248, +22,91,249,22,138,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,185,3, +23,201,1,23,200,1,28,249,22,5,22,132,2,23,202,2,250,22,138,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,177,7,249,22,2, +32,0,88,148,8,36,40,48,11,9,222,33,153,2,249,2,154,2,22,132,2, +23,209,1,86,95,23,200,1,23,198,1,2,66,27,248,22,82,23,202,2,27, +28,248,22,179,15,23,195,2,249,22,133,16,23,196,1,23,199,2,248,22,133, +2,23,195,1,28,28,248,22,179,15,248,22,170,20,23,204,2,248,22,128,16, +23,194,2,10,27,250,22,1,22,133,16,23,197,1,23,202,2,28,28,248,22, +89,23,200,2,10,248,22,128,16,23,194,2,28,23,201,2,28,28,250,80,144, +45,8,32,42,195,203,204,10,27,28,248,22,179,15,202,248,22,183,15,202,201, +19,248,22,157,7,23,195,2,27,28,249,22,133,4,23,196,4,43,28,249,22, +160,7,6,4,4,46,114,107,116,249,22,176,7,23,199,2,249,22,185,3,23, +200,4,43,249,22,177,7,250,22,176,7,23,200,1,39,249,22,185,3,23,201, +4,43,6,3,3,46,115,115,86,94,23,195,1,11,86,94,23,195,1,11,28, +23,193,2,250,80,144,48,8,32,42,198,23,196,1,23,15,11,2,28,200,249, +22,133,16,194,202,192,26,8,80,144,50,8,49,42,204,205,206,23,15,23,16, +23,17,248,22,171,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,171,20,23,19,23,19,26,8, +80,144,49,8,49,42,203,204,205,206,23,15,23,16,248,22,171,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,69,28,248,22,179,15,195,248,22,183,15,195,194,27,27,247, +22,161,16,28,248,22,89,23,194,2,9,28,248,22,82,23,194,2,28,248,22, +150,2,248,22,170,20,23,195,2,250,22,95,249,22,2,22,130,2,250,22,159, +2,248,22,170,20,23,202,2,23,203,2,9,250,22,159,2,248,22,170,20,23, +200,2,11,9,249,80,144,49,8,48,42,23,200,1,248,22,171,20,23,199,1, +27,248,80,144,46,8,30,42,248,22,170,20,23,196,2,250,22,95,250,22,159, +2,23,199,2,23,202,2,9,250,22,159,2,23,199,1,11,9,249,80,144,50, +8,48,42,23,201,1,248,22,171,20,23,200,1,249,22,95,247,22,160,16,249, +80,144,48,8,48,42,23,199,1,248,22,171,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,134,4,23,196,2,86,94,23,195,1, +19,248,22,148,8,23,195,2,19,248,22,148,8,23,196,2,249,22,189,15,27, +251,22,155,8,250,22,154,8,23,205,2,39,23,204,4,2,51,249,22,154,8, +23,204,1,23,202,4,2,68,28,248,22,134,4,248,22,148,8,23,195,2,86, +94,23,193,1,251,22,185,11,2,37,2,69,2,70,202,192,28,248,22,180,15, +198,248,22,181,15,198,247,22,182,15,2,2,27,248,22,183,3,23,197,1,28, +249,22,170,9,8,46,249,22,149,8,23,198,2,23,197,2,27,248,22,182,3, +23,195,2,249,22,189,15,27,251,22,155,8,250,22,154,8,23,205,2,39,23, +204,1,2,71,249,22,154,8,23,204,1,23,202,1,2,68,28,248,22,134,4, +248,22,148,8,23,195,2,86,94,23,193,1,251,22,185,11,2,37,2,69,2, +70,202,192,28,248,22,180,15,198,248,22,181,15,198,247,22,182,15,250,2,158, +2,196,197,195,248,22,191,15,27,250,22,133,16,23,200,1,23,202,1,23,199, +1,28,249,22,170,9,23,197,2,66,115,97,109,101,192,28,248,22,138,16,23, +196,2,249,22,133,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,191,15,249,22,133,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,185,15,23,196,1,27,250,2,158,2,23,197,2,23,204,1,248, +22,148,8,23,198,1,28,248,22,180,15,195,249,22,133,16,196,194,192,27,247, +22,162,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,163,16,11,86,95,28,28, +248,22,180,15,23,194,2,10,28,248,22,179,15,23,194,2,10,28,248,22,154, +7,23,194,2,28,248,22,138,16,23,194,2,10,248,22,139,16,23,194,2,11, +12,252,22,183,11,23,200,2,2,42,39,23,198,2,23,199,2,28,28,248,22, +154,7,23,195,2,10,248,22,143,8,23,195,2,86,94,23,194,1,12,252,22, +183,11,23,200,2,2,72,40,23,198,2,23,199,1,90,144,42,11,89,146,42, +39,11,248,22,136,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,186,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,189,15,27,251,22,155,8,250,22,154,8,23,203,2,39,23, +207,1,23,205,1,249,23,203,1,23,202,1,23,208,1,28,248,22,154,7,23, +204,2,249,22,169,8,23,205,1,8,63,23,203,1,28,248,22,134,4,248,22, +148,8,23,195,2,86,94,23,193,1,251,22,185,11,2,37,2,69,2,70,201, +192,28,248,22,180,15,197,248,22,181,15,197,247,22,182,15,32,166,2,88,148, +8,36,45,8,24,11,2,50,222,33,167,2,28,248,22,134,4,23,199,2,86, +95,23,198,1,23,194,1,19,248,22,148,8,23,195,2,19,248,22,148,8,23, +196,2,249,22,189,15,27,251,22,155,8,250,22,154,8,23,205,2,39,23,204, +4,2,51,249,23,206,1,23,204,1,23,202,4,28,248,22,154,7,23,207,2, +249,22,169,8,23,208,1,8,63,23,206,1,28,248,22,134,4,248,22,148,8, +23,195,2,86,94,23,193,1,251,22,185,11,2,37,2,69,2,70,204,192,28, +248,22,180,15,200,248,22,181,15,200,247,22,182,15,2,2,27,248,22,183,3, +23,200,1,28,249,22,170,9,8,46,249,22,149,8,23,198,2,23,197,2,27, +248,22,182,3,23,195,2,249,22,189,15,27,251,22,155,8,250,22,154,8,23, +205,2,39,23,204,1,23,203,1,249,23,206,1,23,204,1,23,202,1,28,248, +22,154,7,23,207,2,249,22,169,8,23,208,1,8,63,23,206,1,28,248,22, +134,4,248,22,148,8,23,195,2,86,94,23,193,1,251,22,185,11,2,37,2, +69,2,70,204,192,28,248,22,180,15,200,248,22,181,15,200,247,22,182,15,28, +248,22,134,4,23,194,2,86,95,23,195,1,23,193,1,19,248,22,148,8,23, +196,2,19,248,22,148,8,23,197,2,249,22,189,15,27,251,22,155,8,250,22, +154,8,23,206,2,39,23,204,4,2,51,249,23,207,1,23,205,1,23,202,4, +28,248,22,154,7,23,208,2,249,22,169,8,23,209,1,8,63,23,207,1,28, +248,22,134,4,248,22,148,8,23,195,2,86,94,23,193,1,251,22,185,11,2, +37,2,69,2,70,205,192,28,248,22,180,15,201,248,22,181,15,201,247,22,182, +15,2,2,27,248,22,183,3,23,195,1,28,249,22,170,9,8,46,249,22,149, +8,23,199,2,23,197,2,27,248,22,182,3,23,195,2,249,22,189,15,27,251, +22,155,8,250,22,154,8,23,206,2,39,23,204,1,23,204,1,249,23,207,1, +23,205,1,23,202,1,28,248,22,154,7,23,208,2,249,22,169,8,23,209,1, +8,63,23,207,1,28,248,22,134,4,248,22,148,8,23,195,2,86,94,23,193, +1,251,22,185,11,2,37,2,69,2,70,205,192,28,248,22,180,15,201,248,22, +181,15,201,247,22,182,15,28,248,22,134,4,193,254,2,164,2,201,203,204,205, +248,22,148,8,202,2,51,248,22,148,8,202,27,248,22,183,3,194,28,249,22, +170,9,8,46,249,22,149,8,199,196,254,2,164,2,202,204,205,206,199,203,248, +22,182,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,180,15,23,199,2,10,28,248,22,179,15,23,199, +2,10,28,248,22,154,7,23,199,2,28,248,22,138,16,23,199,2,10,248,22, +139,16,23,199,2,11,12,252,22,183,11,23,200,2,2,42,39,23,203,2,23, +204,2,28,28,248,22,154,7,23,200,2,10,248,22,143,8,23,200,2,12,252, +22,183,11,23,200,2,2,72,40,23,203,2,23,204,2,90,144,42,11,89,146, +42,39,11,248,22,136,16,23,202,2,86,94,23,195,1,86,94,28,192,12,250, +22,186,11,23,201,1,2,73,23,204,2,249,22,7,194,195,27,248,22,185,15, +23,196,1,27,19,248,22,148,8,23,196,2,28,248,22,134,4,23,194,4,86, +94,23,199,1,19,248,22,148,8,23,197,2,19,248,22,148,8,23,198,2,249, +22,189,15,27,251,22,155,8,250,22,154,8,23,207,2,39,23,204,4,2,51, +249,23,211,1,23,206,1,23,202,4,28,248,22,154,7,23,212,2,249,22,169, +8,23,213,1,8,63,23,211,1,28,248,22,134,4,248,22,148,8,23,195,2, +86,94,23,193,1,251,22,185,11,2,37,2,69,2,70,23,17,192,28,248,22, +180,15,205,248,22,181,15,205,247,22,182,15,2,2,27,248,22,183,3,23,195, +4,28,249,22,170,9,8,46,249,22,149,8,23,200,2,23,197,2,27,248,22, +182,3,23,195,2,249,22,189,15,27,251,22,155,8,250,22,154,8,23,207,2, +39,23,204,1,23,208,1,249,23,211,1,23,206,1,23,202,1,28,248,22,154, +7,23,212,2,249,22,169,8,23,213,1,8,63,23,211,1,28,248,22,134,4, +248,22,148,8,23,195,2,86,94,23,193,1,251,22,185,11,2,37,2,69,2, +70,23,17,192,28,248,22,180,15,205,248,22,181,15,205,247,22,182,15,28,248, +22,134,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,148,8,23,204,2,2,51,248,22,148, +8,23,204,1,27,248,22,183,3,23,195,1,28,249,22,170,9,8,46,249,22, +149,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,182,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, +180,15,195,249,22,133,16,196,194,192,32,169,2,88,148,8,36,43,61,11,2, +50,222,33,170,2,28,248,22,134,4,23,197,2,86,94,23,196,1,19,248,22, +148,8,23,195,2,35,248,22,148,8,23,196,2,249,22,189,15,27,251,22,155, +8,250,22,154,8,23,205,1,39,23,204,4,2,51,2,51,28,248,22,154,7, +23,205,2,249,22,169,8,23,206,1,8,63,23,204,1,28,248,22,134,4,248, +22,148,8,23,195,2,86,94,23,193,1,251,22,185,11,2,37,2,69,2,70, +202,192,28,248,22,180,15,198,248,22,181,15,198,247,22,182,15,2,27,248,22, +183,3,23,198,1,28,249,22,170,9,8,46,249,22,149,8,23,198,2,23,197, +2,35,248,22,182,3,23,195,2,249,22,189,15,27,251,22,155,8,250,22,154, +8,23,205,1,39,23,204,1,2,51,2,51,28,248,22,154,7,23,205,2,249, +22,169,8,23,206,1,8,63,23,204,1,28,248,22,134,4,248,22,148,8,23, +195,2,86,94,23,193,1,251,22,185,11,2,37,2,69,2,70,202,192,28,248, +22,180,15,198,248,22,181,15,198,247,22,182,15,28,248,22,134,4,23,194,2, +86,94,23,193,1,19,248,22,148,8,23,196,2,35,248,22,148,8,23,197,2, +249,22,189,15,27,251,22,155,8,250,22,154,8,23,206,1,39,23,204,4,2, +51,2,51,28,248,22,154,7,23,206,2,249,22,169,8,23,207,1,8,63,23, +205,1,28,248,22,134,4,248,22,148,8,23,195,2,86,94,23,193,1,251,22, +185,11,2,37,2,69,2,70,203,192,28,248,22,180,15,199,248,22,181,15,199, +247,22,182,15,2,27,248,22,183,3,23,195,1,28,249,22,170,9,8,46,249, +22,149,8,23,199,2,23,197,2,35,248,22,182,3,23,195,2,249,22,189,15, +27,251,22,155,8,250,22,154,8,23,206,1,39,23,204,1,2,51,2,51,28, +248,22,154,7,23,206,2,249,22,169,8,23,207,1,8,63,23,205,1,28,248, +22,134,4,248,22,148,8,23,195,2,86,94,23,193,1,251,22,185,11,2,37, +2,69,2,70,203,192,28,248,22,180,15,199,248,22,181,15,199,247,22,182,15, +251,2,169,2,198,199,200,196,90,144,41,11,89,146,41,39,11,86,95,28,28, +248,22,180,15,23,196,2,10,28,248,22,179,15,23,196,2,10,28,248,22,154, +7,23,196,2,28,248,22,138,16,23,196,2,10,248,22,139,16,23,196,2,11, +12,252,22,183,11,2,37,2,42,39,23,200,2,23,201,2,28,28,248,22,154, +7,23,197,2,10,248,22,143,8,23,197,2,12,252,22,183,11,2,37,2,72, +40,23,200,2,23,201,2,90,144,42,11,89,146,42,39,11,248,22,136,16,23, +199,2,86,94,23,195,1,86,94,28,192,12,250,22,186,11,2,37,2,73,23, +201,2,249,22,7,194,195,27,248,22,185,15,23,196,1,27,251,2,169,2,23, +198,2,23,201,1,23,202,1,248,22,148,8,23,199,1,28,248,22,180,15,195, +249,22,133,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,189,15,27,251,22,155,8,250,22,154,8,23,203,2, +39,23,206,1,23,204,1,249,22,154,8,23,202,1,23,207,1,28,248,22,154, +7,23,203,2,249,22,169,8,23,204,1,8,63,23,202,1,28,248,22,134,4, +248,22,148,8,23,195,2,86,94,23,193,1,251,22,185,11,2,37,2,69,2, +70,200,192,28,248,22,180,15,196,248,22,181,15,196,247,22,182,15,28,248,22, +134,4,23,197,2,86,94,23,196,1,19,248,22,148,8,23,195,2,19,248,22, +148,8,23,196,2,249,22,189,15,27,251,22,155,8,250,22,154,8,23,205,2, +39,23,204,4,2,51,249,22,154,8,23,204,1,23,202,4,28,248,22,154,7, +23,205,2,249,22,169,8,23,206,1,8,63,23,204,1,28,248,22,134,4,248, +22,148,8,23,195,2,86,94,23,193,1,251,22,185,11,2,37,2,69,2,70, +202,192,28,248,22,180,15,198,248,22,181,15,198,247,22,182,15,2,2,27,248, +22,183,3,23,198,1,28,249,22,170,9,8,46,249,22,149,8,23,198,2,23, +197,2,27,248,22,182,3,23,195,2,249,22,189,15,27,251,22,155,8,250,22, +154,8,23,205,2,39,23,204,1,2,71,249,22,154,8,23,204,1,23,202,1, +28,248,22,154,7,23,205,2,249,22,169,8,23,206,1,8,63,23,204,1,28, +248,22,134,4,248,22,148,8,23,195,2,86,94,23,193,1,251,22,185,11,2, +37,2,69,2,70,202,192,28,248,22,180,15,198,248,22,181,15,198,247,22,182, +15,28,248,22,134,4,193,253,2,175,2,199,200,201,248,22,148,8,200,2,51, +248,22,148,8,200,27,248,22,183,3,194,28,249,22,170,9,8,46,249,22,149, +8,198,196,253,2,175,2,200,201,202,198,2,71,248,22,182,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,180, +15,23,196,2,10,28,248,22,179,15,23,196,2,10,28,248,22,154,7,23,196, +2,28,248,22,138,16,23,196,2,10,248,22,139,16,23,196,2,11,12,252,22, +183,11,2,37,2,42,39,23,200,2,23,201,2,28,28,248,22,154,7,23,197, +2,10,248,22,143,8,23,197,2,12,252,22,183,11,2,37,2,72,40,23,200, +2,23,201,2,90,144,42,11,89,146,42,39,11,248,22,136,16,23,199,2,86, +94,23,195,1,86,94,28,192,12,250,22,186,11,2,37,2,73,23,201,2,249, +22,7,194,195,27,248,22,185,15,23,196,1,27,251,2,174,2,23,198,2,23, +201,1,23,202,1,248,22,148,8,23,199,1,28,248,22,180,15,195,249,22,133, +16,196,194,192,252,80,144,44,8,35,42,2,37,2,71,22,154,8,198,199,249, +247,22,177,5,23,195,1,11,249,247,22,177,5,194,11,28,248,22,89,23,195, +2,9,27,27,248,22,82,23,197,2,28,248,22,140,16,23,194,2,248,22,143, +16,23,194,1,28,248,22,139,16,23,194,2,90,144,42,11,89,146,42,39,11, +248,22,136,16,249,22,141,16,250,80,144,50,43,42,248,22,156,16,2,56,11, +11,248,22,156,16,2,57,86,95,23,195,1,23,194,1,248,22,143,16,249,22, +141,16,23,199,1,23,196,1,27,250,80,144,45,43,42,248,22,156,16,2,56, +23,197,1,10,28,23,193,2,248,22,143,16,23,194,1,11,28,23,193,2,249, +22,81,248,22,143,16,249,22,141,16,23,198,1,247,22,157,16,27,248,22,171, +20,23,199,1,28,248,22,89,23,194,2,9,27,248,80,144,45,56,42,248,22, +82,23,196,2,28,23,193,2,249,22,81,248,22,143,16,249,22,141,16,23,198, +1,247,22,157,16,248,80,144,47,8,50,42,248,22,171,20,23,198,1,86,94, +23,193,1,248,80,144,45,8,50,42,248,22,171,20,23,196,1,86,94,23,193, +1,27,248,22,171,20,23,197,1,28,248,22,89,23,194,2,9,27,248,80,144, +43,56,42,248,22,82,23,196,2,28,23,193,2,249,22,81,248,22,143,16,249, +22,141,16,23,198,1,247,22,157,16,248,80,144,45,8,50,42,248,22,171,20, +23,198,1,86,94,23,193,1,248,80,144,43,8,50,42,248,22,171,20,23,196, +1,28,248,22,89,23,195,2,9,27,27,248,22,82,23,197,2,28,248,22,140, +16,23,194,2,248,22,143,16,23,194,1,28,248,22,139,16,23,194,2,90,144, +42,11,89,146,42,39,11,248,22,136,16,249,22,141,16,250,80,144,50,43,42, +248,22,156,16,2,56,11,11,248,22,156,16,2,57,86,95,23,195,1,23,194, +1,248,22,143,16,249,22,141,16,23,199,1,23,196,1,27,250,80,144,45,43, +42,248,22,156,16,2,56,23,197,1,10,28,23,193,2,248,22,143,16,23,194, +1,11,28,23,193,2,249,22,81,248,22,143,16,249,22,141,16,23,198,1,247, +22,157,16,27,248,22,171,20,23,199,1,28,248,22,89,23,194,2,9,27,248, +80,144,45,56,42,248,22,82,23,196,2,28,23,193,2,249,22,81,248,22,143, +16,249,22,141,16,23,198,1,247,22,157,16,248,80,144,47,8,51,42,248,22, +171,20,23,198,1,86,94,23,193,1,248,80,144,45,8,51,42,248,22,171,20, +23,196,1,86,94,23,193,1,27,248,22,171,20,23,197,1,28,248,22,89,23, +194,2,9,27,248,80,144,43,56,42,248,22,82,23,196,2,28,23,193,2,249, +22,81,248,22,143,16,249,22,141,16,23,198,1,247,22,157,16,248,80,144,45, +8,51,42,248,22,171,20,23,198,1,86,94,23,193,1,248,80,144,43,8,51, +42,248,22,171,20,23,196,1,27,248,22,156,16,2,58,28,248,22,140,16,23, +194,2,248,22,143,16,23,194,1,28,248,22,139,16,23,194,2,90,144,42,11, +89,146,42,39,11,248,22,136,16,249,22,141,16,250,80,144,49,43,42,248,22, +156,16,2,56,11,11,248,22,156,16,2,57,86,95,23,195,1,23,194,1,248, +22,143,16,249,22,141,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248, +22,156,16,2,56,23,197,1,10,28,23,193,2,248,22,143,16,23,194,1,11, +28,248,22,89,23,195,2,9,27,27,248,22,82,23,197,2,28,248,22,140,16, +23,194,2,248,22,143,16,23,194,1,28,248,22,139,16,23,194,2,90,144,42, +11,89,146,42,39,11,248,22,136,16,249,22,141,16,250,80,144,50,43,42,248, +22,156,16,2,56,11,11,248,22,156,16,2,57,86,95,23,195,1,23,194,1, +248,22,143,16,249,22,141,16,23,199,1,23,196,1,27,250,80,144,45,43,42, +248,22,156,16,2,56,23,197,1,10,28,23,193,2,248,22,143,16,23,194,1, +11,28,23,193,2,249,22,81,248,22,143,16,249,22,141,16,23,198,1,247,22, +157,16,27,248,22,171,20,23,199,1,28,248,22,89,23,194,2,9,27,27,248, +22,82,23,196,2,28,248,22,140,16,23,194,2,248,22,143,16,23,194,1,28, +248,22,139,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,136,16,249, +22,141,16,250,80,144,54,43,42,248,22,156,16,2,56,11,11,248,22,156,16, +2,57,86,95,23,195,1,23,194,1,248,22,143,16,249,22,141,16,23,199,1, +23,196,1,27,250,80,144,49,43,42,248,22,156,16,2,56,23,197,1,10,28, +23,193,2,248,22,143,16,23,194,1,11,28,23,193,2,249,22,81,248,22,143, +16,249,22,141,16,23,198,1,247,22,157,16,27,248,22,171,20,23,198,1,28, +248,22,89,23,194,2,9,27,248,80,144,49,56,42,248,22,82,23,196,2,28, +23,193,2,249,22,81,248,22,143,16,249,22,141,16,23,198,1,247,22,157,16, +248,80,144,51,8,53,42,248,22,171,20,23,198,1,86,94,23,193,1,248,80, +144,49,8,53,42,248,22,171,20,23,196,1,86,94,23,193,1,27,248,22,171, +20,23,196,1,28,248,22,89,23,194,2,9,27,248,80,144,47,56,42,248,22, +82,23,196,2,28,23,193,2,249,22,81,248,22,143,16,249,22,141,16,23,198, +1,247,22,157,16,248,80,144,49,8,53,42,248,22,171,20,23,198,1,86,94, +23,193,1,248,80,144,47,8,53,42,248,22,171,20,23,196,1,86,94,23,193, +1,27,248,22,171,20,23,197,1,28,248,22,89,23,194,2,9,27,27,248,22, +82,23,196,2,28,248,22,140,16,23,194,2,248,22,143,16,23,194,1,28,248, +22,139,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,136,16,249,22, +141,16,250,80,144,52,43,42,248,22,156,16,2,56,11,11,248,22,156,16,2, +57,86,95,23,195,1,23,194,1,248,22,143,16,249,22,141,16,23,199,1,23, +196,1,27,250,80,144,47,43,42,248,22,156,16,2,56,23,197,1,10,28,23, +193,2,248,22,143,16,23,194,1,11,28,23,193,2,249,22,81,248,22,143,16, +249,22,141,16,23,198,1,247,22,157,16,27,248,22,171,20,23,198,1,28,248, +22,89,23,194,2,9,27,248,80,144,47,56,42,248,22,82,23,196,2,28,23, +193,2,249,22,81,248,22,143,16,249,22,141,16,23,198,1,247,22,157,16,248, +80,144,49,8,53,42,248,22,171,20,23,198,1,86,94,23,193,1,248,80,144, +47,8,53,42,248,22,171,20,23,196,1,86,94,23,193,1,27,248,22,171,20, +23,196,1,28,248,22,89,23,194,2,9,27,248,80,144,45,56,42,248,22,82, +23,196,2,28,23,193,2,249,22,81,248,22,143,16,249,22,141,16,23,198,1, +247,22,157,16,248,80,144,47,8,53,42,248,22,171,20,23,198,1,86,94,23, +193,1,248,80,144,45,8,53,42,248,22,171,20,23,196,1,27,247,22,164,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,176,8,247,22,175,8,2,75,28,192,249,22,166,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,133,16,248,22,156,16,2,61,250,22,159,2,23,205,1,2,59,247, +22,172,8,2,77,86,94,23,199,1,11,27,248,80,144,49,8,50,42,250,22, +95,9,248,22,91,248,22,156,16,2,55,9,28,193,249,22,81,195,194,192,27, +247,22,164,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,176,8,247,22,175,8,2,75,28,192,249,22, +166,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,133,16,248,22,156,16,2,61,250,22,159,2,23,205, +1,2,59,247,22,172,8,2,77,86,94,23,199,1,11,27,248,80,144,49,8, +51,42,250,22,95,23,207,1,248,22,91,248,22,156,16,2,55,9,28,193,249, +22,81,195,194,192,27,247,22,164,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,176,8,247,22,175,8,2,75,28,192,249,22,166,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,133, +16,248,22,156,16,2,61,250,22,159,2,23,205,1,2,59,247,22,172,8,2, +77,86,94,23,199,1,11,27,27,250,22,95,23,207,1,248,22,91,248,22,156, +16,2,55,23,208,1,28,248,22,89,23,194,2,9,27,27,248,22,82,23,196, +2,28,248,22,140,16,23,194,2,248,22,143,16,23,194,1,28,248,22,139,16, +23,194,2,90,144,42,11,89,146,42,39,11,248,22,136,16,249,22,141,16,250, +80,144,60,43,42,248,22,156,16,2,56,11,11,248,22,156,16,2,57,86,95, +23,195,1,23,194,1,248,22,143,16,249,22,141,16,23,199,1,23,196,1,27, +250,80,144,55,43,42,248,22,156,16,2,56,23,197,1,10,28,23,193,2,248, +22,143,16,23,194,1,11,28,23,193,2,249,22,81,248,22,143,16,249,22,141, +16,23,198,1,247,22,157,16,27,248,22,171,20,23,198,1,28,248,22,89,23, +194,2,9,27,248,80,144,55,56,42,248,22,82,23,196,2,28,23,193,2,249, +22,81,248,22,143,16,249,22,141,16,23,198,1,247,22,157,16,248,80,144,57, +8,53,42,248,22,171,20,23,198,1,86,94,23,193,1,248,80,144,55,8,53, +42,248,22,171,20,23,196,1,86,94,23,193,1,27,248,22,171,20,23,196,1, +28,248,22,89,23,194,2,9,27,248,80,144,53,56,42,248,22,82,23,196,2, +28,23,193,2,249,22,81,248,22,143,16,249,22,141,16,23,198,1,247,22,157, +16,248,80,144,55,8,53,42,248,22,171,20,23,198,1,86,94,23,193,1,248, +80,144,53,8,53,42,248,22,171,20,23,196,1,28,193,249,22,81,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,153,15,10,22,160,15,10,22,161,15,10,22,162,15,10,248, +22,149,6,23,196,2,28,248,22,149,7,23,194,2,12,86,94,248,22,178,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,153,15,10,22,160,15,10,22,161,15,10,22,162, +15,10,248,22,149,6,23,197,2,28,248,22,149,7,23,194,2,12,86,94,248, +22,178,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,153,15,10,22,160,15,10,22,161,15, +10,22,162,15,10,248,22,149,6,23,198,2,28,248,22,149,7,23,194,2,12, +86,94,248,22,178,9,23,194,1,248,80,144,43,8,54,42,197,86,94,249,22, +140,7,247,22,173,5,23,196,2,248,22,164,6,249,22,137,4,39,249,22,185, +3,28,23,198,2,23,198,1,86,94,23,198,1,39,23,199,1,27,248,22,190, +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,156,16,2,56,11,11,27,248,22,140,4,23, +199,1,27,28,23,194,2,23,194,1,86,94,23,194,1,39,27,248,22,140,4, +23,202,1,249,22,141,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,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,156,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, +168,16,248,22,168,8,27,28,249,22,170,9,247,22,181,8,2,43,6,1,1, +59,6,1,1,58,250,22,138,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,44,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,44,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,141,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, 9765); + EVAL_ONE_SIZED_STR((char *)expr, 19824); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,54,46,51,46,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,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,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,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, 531); + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,8,54,46,51,46,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,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,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,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,191,10,2,4,11,41,39,11,248, +22,91,249,22,81,22,176,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,8,54,46,51,46,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,29,11,59,11,110,11,185,11,201,11, +217,11,231,11,247,11,66,12,82,12,98,12,114,12,189,12,96,13,112,13,187, +13,182,14,62,15,137,15,44,16,57,16,210,16,138,17,181,17,7,18,140,18, +201,18,209,18,220,18,254,19,101,20,129,20,142,20,63,21,70,21,230,21,250, +21,94,22,116,22,126,22,140,22,178,22,21,23,25,23,32,23,238,23,157,32, +210,32,234,32,2,33,0,0,51,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,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,133,16,28,249,22,170,9,23,201,2,2,27,86,94, +23,199,1,23,200,1,28,248,22,138,16,23,200,2,249,22,133,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,182,8,249,80,144,50,46,42,23,203,1,80,144,50,39,41,27,250,22,151, +16,196,11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249,22,81,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,133,16, +28,249,22,170,9,23,201,2,2,27,86,94,23,199,1,23,200,1,28,248,22, +138,16,23,200,2,249,22,133,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,182,8,249,80,144,50,46,42, +23,203,1,80,144,50,39,41,27,250,22,151,16,196,11,32,0,88,148,8,36, +39,44,11,9,222,11,28,192,249,22,81,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,133,16,28,249,22,170,9,23,199,2,2, +27,86,94,23,197,1,23,198,1,28,248,22,138,16,23,198,2,249,22,133,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,151,16,196,11,32,0,88, +148,8,36,39,44,11,9,222,11,28,192,249,22,81,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,133,16,28,249,22,170,9,23, +199,2,2,27,86,94,23,197,1,23,198,1,28,248,22,138,16,23,198,2,249, +22,133,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,151,16,196,11, +32,0,88,148,8,36,39,44,11,9,222,11,28,192,249,22,81,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,183,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,65,23,196,2,10, +28,248,22,90,23,196,2,28,249,22,131,4,248,22,94,23,198,2,40,28,28, +248,22,65,248,22,82,23,197,2,10,248,22,168,9,248,22,170,20,23,197,2, +249,22,4,22,65,248,22,171,20,23,198,2,11,11,11,10,12,250,22,183,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,128,5,11,27,28,23,194,2,250,22,159,2,80,143,44,44,248,22,133, +17,247,22,146,14,11,11,27,28,23,194,2,250,22,159,2,248,22,83,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,129,5,248,22,103,23,197,2,27,248,22,112,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, +178,5,28,248,22,179,15,23,197,2,23,196,1,86,94,23,196,1,247,22,157, +16,249,247,22,176,5,248,22,170,20,23,197,1,23,201,1,86,94,23,193,1, +27,28,248,22,140,16,23,199,2,23,198,2,27,247,22,178,5,28,192,249,22, +141,16,23,201,2,194,23,199,2,90,144,42,11,89,146,42,39,11,248,22,136, +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,184,15,23,198,2,19,248,22,148,8,194,28,28,249,22,133,4, +23,195,4,43,249,22,151,8,2,26,249,22,154,8,197,249,22,185,3,23,199, +4,43,11,249,22,7,23,200,2,248,22,188,15,249,22,155,8,250,22,154,8, +201,39,249,22,185,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,170,9,23,196,2,23,199,2, +23,199,2,249,22,133,16,23,198,2,23,196,2,27,28,23,196,2,28,249,22, +170,9,23,198,2,23,200,1,23,200,1,86,94,23,200,1,249,22,133,16,23, +199,2,23,198,2,86,95,23,200,1,23,198,1,11,27,28,249,22,170,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,162,16,27,247,22,163,16,27,250,22,151,16,23,201,2,11,32,0, +88,148,8,36,39,44,11,9,222,11,27,28,23,194,2,249,22,81,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,151,16,23,203,2,11,32,0,88,148,8,36,39,44,11,9,222,11,28,192, +249,22,81,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,168,9,23,196,2,27,28,23,205,2,28,23, +196,2,86,94,23,197,1,23,196,2,248,22,168,9,23,198,1,86,94,23,197, +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,133,4,248,22,83,196,248,22,83,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,129,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,178,5,28,248,22, +179,15,23,206,2,23,205,1,86,94,23,205,1,247,22,157,16,249,247,22,167, +16,248,22,82,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,133,4,248, +22,83,196,248,22,83,202,193,11,11,11,86,94,23,198,1,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,129,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,178,5,28,248,22,179,15,23,207,2,23,206,1,86,94,23, +206,1,247,22,157,16,249,247,22,167,16,248,22,82,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,133,4,248,22,83,196, +248,22,83,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,82,23,195,2,28,23,215,2,250,22,157,2, +248,22,83,23,219,1,23,219,1,250,22,91,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,129,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,178,5,28,248,22,179,15, +23,208,2,23,207,1,86,94,23,207,1,247,22,157,16,249,247,22,176,5,248, +22,170,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,133,4,248,22,83,196,248,22,83,203,193,11,11,11,86,97, +23,209,1,23,204,1,23,203,1,23,199,1,11,28,23,193,2,86,95,23,207, +1,23,198,1,86,94,27,248,22,82,23,195,2,28,23,216,2,250,22,157,2, +248,22,83,23,220,1,23,220,1,250,22,91,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,129,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,178,5,28, +248,22,179,15,23,209,2,23,208,1,86,94,23,208,1,247,22,157,16,249,247, +22,176,5,248,22,170,20,23,196,1,23,221,1,86,96,23,216,1,23,215,1, +23,193,1,28,28,248,22,79,23,220,2,248,22,170,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,79,23,221,2,248,22,168,9,248,22,191,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,129,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,178,5,28,248,22,179,15,23,210,2,23,209, +1,86,94,23,209,1,247,22,157,16,249,247,22,176,5,23,195,1,23,222,1, +12,28,23,194,2,250,22,157,2,248,22,83,23,198,1,23,196,1,250,22,91, +23,201,1,23,202,1,23,203,1,12,27,249,22,190,8,80,144,42,50,41,249, +22,128,4,248,22,188,3,248,22,174,2,200,8,128,8,27,28,193,248,22,177, +2,194,11,28,192,27,249,22,101,198,195,28,192,248,22,83,193,11,11,27,249, +22,128,4,248,22,188,3,248,22,174,2,23,199,2,8,128,8,27,249,22,190, +8,80,144,43,50,41,23,196,2,250,22,191,8,80,144,44,50,41,23,197,1, +248,22,176,2,249,22,81,249,22,81,23,204,1,23,205,1,27,28,23,200,2, +248,22,177,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,129,4,23,197,2,23,195,4,248, +22,91,194,28,249,22,137,9,7,47,249,22,158,7,23,198,2,23,199,2,249, +22,81,250,22,176,7,23,199,2,39,23,200,2,248,2,56,249,22,176,7,23, +199,1,248,22,182,3,23,201,1,250,2,57,23,196,4,196,248,22,182,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,129,4,23,197,2,23,195,4,248,22,91,194, +28,249,22,137,9,7,47,249,22,158,7,23,198,2,23,199,2,249,22,81,250, +22,176,7,23,199,2,39,23,200,2,248,2,56,249,22,176,7,23,199,1,248, +22,182,3,23,201,1,250,2,61,23,196,4,196,248,22,182,3,198,28,249,22, +129,4,23,197,2,23,195,4,248,22,91,194,28,249,22,137,9,7,47,249,22, +158,7,23,198,2,23,199,2,249,22,81,250,22,176,7,23,199,2,39,23,200, +2,27,249,22,176,7,23,199,1,248,22,182,3,23,201,1,19,248,22,157,7, +23,195,2,250,2,61,23,196,4,23,197,1,39,2,27,248,22,182,3,23,197, +1,28,249,22,129,4,23,195,2,23,196,4,248,22,91,195,28,249,22,137,9, +7,47,249,22,158,7,23,199,2,23,197,2,249,22,81,250,22,176,7,23,200, +2,39,23,198,2,248,2,56,249,22,176,7,23,200,1,248,22,182,3,23,199, +1,250,2,60,23,197,4,197,248,22,182,3,196,32,64,88,149,8,38,42,53, +11,2,30,39,223,3,33,65,28,249,22,129,4,23,197,2,23,195,4,248,22, +91,194,28,249,22,137,9,7,47,249,22,158,7,23,198,2,23,199,2,249,22, +81,250,22,176,7,23,199,2,39,23,200,2,248,2,56,249,22,176,7,23,199, +1,248,22,182,3,23,201,1,250,2,64,23,196,4,196,248,22,182,3,198,28, +249,22,129,4,23,197,2,23,195,4,248,22,91,194,28,249,22,137,9,7,47, +249,22,158,7,23,198,2,23,199,2,249,22,81,250,22,176,7,23,199,2,39, +23,200,2,27,249,22,176,7,23,199,1,248,22,182,3,23,201,1,19,248,22, +157,7,23,195,2,250,2,60,23,196,4,23,197,1,39,2,27,248,22,182,3, +23,197,1,28,249,22,129,4,23,195,2,23,196,4,248,22,91,195,28,249,22, +137,9,7,47,249,22,158,7,23,199,2,23,197,2,249,22,81,250,22,176,7, +23,200,2,39,23,198,2,27,249,22,176,7,23,200,1,248,22,182,3,23,199, +1,19,248,22,157,7,23,195,2,250,2,64,23,196,4,23,197,1,39,2,27, +248,22,182,3,23,195,1,28,249,22,129,4,23,195,2,23,197,4,248,22,91, +196,28,249,22,137,9,7,47,249,22,158,7,23,200,2,23,197,2,249,22,81, +250,22,176,7,23,201,2,39,23,198,2,248,2,56,249,22,176,7,23,201,1, +248,22,182,3,23,199,1,250,2,59,23,198,4,198,248,22,182,3,196,19,248, +22,157,7,23,195,2,28,249,22,129,4,39,23,195,4,248,22,91,194,28,249, +22,137,9,7,47,249,22,158,7,23,198,2,39,249,22,81,250,22,176,7,23, +199,2,39,39,27,249,22,176,7,23,199,1,40,19,248,22,157,7,23,195,2, +250,2,57,23,196,4,23,197,1,39,2,28,249,22,129,4,40,23,195,4,248, +22,91,194,28,249,22,137,9,7,47,249,22,158,7,23,198,2,40,249,22,81, +250,22,176,7,23,199,2,39,40,248,2,56,249,22,176,7,23,199,1,41,250, +2,59,23,196,4,196,41,2,28,249,22,129,4,23,197,2,23,195,4,248,22, +91,194,28,249,22,137,9,7,47,249,22,158,7,23,198,2,23,199,2,249,22, +81,250,22,176,7,23,199,2,39,23,200,2,248,2,56,249,22,176,7,23,199, +1,248,22,182,3,23,201,1,250,2,55,23,196,4,196,248,22,182,3,198,28, +249,22,129,4,23,197,2,23,195,4,248,22,91,194,28,249,22,137,9,7,47, +249,22,158,7,23,198,2,23,199,2,249,22,81,250,22,176,7,23,199,2,39, +23,200,2,27,249,22,176,7,23,199,1,248,22,182,3,23,201,1,19,248,22, +157,7,23,195,2,250,2,55,23,196,4,23,197,1,39,2,27,248,22,182,3, +23,197,1,28,249,22,129,4,23,195,2,23,196,4,248,22,91,195,28,249,22, +137,9,7,47,249,22,158,7,23,199,2,23,197,2,249,22,81,250,22,176,7, +23,200,2,39,23,198,2,248,2,56,249,22,176,7,23,200,1,248,22,182,3, +23,199,1,250,2,54,23,197,4,197,248,22,182,3,196,32,70,88,148,39,40, +58,11,2,31,222,33,71,28,248,22,89,248,22,83,23,195,2,249,22,7,9, +248,22,170,20,23,196,1,90,144,41,11,89,146,41,39,11,27,248,22,171,20, +23,197,2,28,248,22,89,248,22,83,23,195,2,249,22,7,9,248,22,170,20, +195,90,144,41,11,89,146,41,39,11,27,248,22,171,20,196,28,248,22,89,248, +22,83,23,195,2,249,22,7,9,248,22,170,20,195,90,144,41,11,89,146,41, +39,11,248,2,70,248,22,171,20,196,249,22,7,249,22,81,248,22,170,20,199, +196,195,249,22,7,249,22,81,248,22,170,20,199,196,195,249,22,7,249,22,81, +248,22,170,20,23,200,1,23,197,1,23,196,1,27,19,248,22,157,7,23,196, +2,250,2,54,23,196,4,23,198,1,39,2,28,23,195,1,192,28,248,22,89, +248,22,83,23,195,2,249,22,7,9,248,22,170,20,23,196,1,27,248,22,171, +20,23,195,2,90,144,41,11,89,146,41,39,11,28,248,22,89,248,22,83,23, +197,2,249,22,7,9,248,22,170,20,23,198,1,27,248,22,171,20,23,197,2, +90,144,41,11,89,146,41,39,11,28,248,22,89,248,22,83,23,197,2,249,22, +7,9,248,22,170,20,197,90,144,41,11,89,146,41,39,11,248,2,70,248,22, +171,20,198,249,22,7,249,22,81,248,22,170,20,201,196,195,249,22,7,249,22, +81,248,22,170,20,23,203,1,196,195,249,22,7,249,22,81,248,22,170,20,23, +201,1,23,197,1,23,196,1,248,22,145,12,252,22,163,10,248,22,164,4,23, +200,2,248,22,160,4,23,200,2,248,22,161,4,23,200,2,248,22,162,4,23, +200,2,248,22,163,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,131,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,170,9,23,197,2,80, +143,42,55,86,94,23,195,1,80,143,40,56,27,248,22,154,5,23,197,2,27, +28,248,22,79,23,195,2,248,22,170,20,23,195,1,23,194,1,28,248,22,179, +15,23,194,2,90,144,42,11,89,146,42,39,11,248,22,136,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, +86,94,23,195,1,11,28,23,193,2,192,86,94,23,193,1,27,247,22,178,5, +28,23,193,2,192,86,94,23,193,1,247,22,157,16,90,144,42,11,89,146,42, +39,11,248,22,136,16,23,198,2,86,95,23,195,1,23,193,1,28,249,22,172, +16,0,11,35,114,120,34,91,46,93,115,115,36,34,248,22,184,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,152,5,23,196,2,12, +250,22,183,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,147,14, +23,197,2,10,12,250,22,183,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,159,2,80,144,44,44, +41,248,22,133,17,247,22,146,14,11,27,28,23,194,2,23,194,1,86,94,23, +194,1,27,249,22,81,247,22,139,2,247,22,139,2,86,94,250,22,157,2,80, +144,46,44,41,248,22,133,17,247,22,146,14,195,192,86,94,250,22,157,2,248, +22,82,23,197,2,23,200,2,70,100,101,99,108,97,114,101,100,28,23,198,2, +27,28,248,22,79,248,22,154,5,23,200,2,248,22,153,5,248,22,82,248,22, +154,5,23,201,1,23,198,1,27,250,22,159,2,80,144,47,44,41,248,22,133, +17,23,204,1,11,28,23,193,2,27,250,22,159,2,248,22,83,23,198,1,23, +198,2,11,28,23,193,2,250,22,157,2,248,22,171,20,23,200,1,23,198,1, +23,196,1,12,12,12,86,94,251,22,140,12,247,22,144,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,89,23,197,2,28,248,22,89,195,192,249,22,81,194,248, +22,96,197,28,249,22,172,9,248,22,82,23,199,2,2,35,28,248,22,89,23, +196,2,86,95,23,196,1,23,195,1,250,22,179,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,92,2,34,28,249, +22,172,9,23,201,2,2,36,23,199,1,28,248,22,179,15,23,200,2,23,199, +1,249,22,91,28,248,22,65,23,202,2,2,5,2,37,23,201,1,23,200,1, +251,2,82,196,197,248,22,83,199,248,22,171,20,200,251,2,82,196,197,249,22, +81,248,22,170,20,202,200,248,22,171,20,200,251,2,82,196,197,9,197,27,250, +22,177,7,27,28,23,199,2,28,247,22,132,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,183,16,0,7,35,114,120,34,92,110,34,23,203,1,249,22,138,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,175,13,28,23,196,2,251,22,183,12,23, +198,1,247,22,27,248,22,91,23,201,1,23,199,1,86,94,23,196,1,250,22, +146,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,157,7,194,28,249,22,133,4, +23,195,4,42,28,249,22,170,9,7,46,249,22,158,7,197,249,22,185,3,23, +199,4,42,28,28,249,22,170,9,7,115,249,22,158,7,197,249,22,185,3,23, +199,4,41,249,22,170,9,7,115,249,22,158,7,197,249,22,185,3,23,199,4, +40,11,249,22,177,7,250,22,176,7,198,39,249,22,185,3,23,200,4,42,2, +40,193,193,193,2,28,249,22,160,7,194,2,36,2,27,28,249,22,160,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,89,23,194,2,9,250,22,92,6, +4,4,10,32,32,32,248,22,183,15,248,22,104,23,198,2,248,2,90,248,22, +171,20,23,198,1,28,249,22,172,9,248,22,83,23,200,2,23,197,1,28,249, +22,170,9,248,22,170,20,23,200,1,23,196,1,251,22,179,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,177,7,248,2,90,248,22,96,23,201,1,12,12,247, +23,193,1,250,22,158,4,11,196,195,20,13,144,80,144,49,53,41,249,22,81, +249,22,81,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,128,5,23,201,2,22, +130,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,65,23,207,2,23,206,1, +28,28,248,22,79,23,207,2,249,22,170,9,248,22,170,20,23,209,2,2,32, +11,23,206,1,86,94,23,206,1,28,248,22,152,5,23,203,2,27,248,22,154, +5,23,204,2,28,248,22,65,193,249,22,91,2,5,194,192,23,202,2,249,247, +22,177,5,23,201,1,27,248,22,69,248,22,183,15,23,202,1,28,23,204,2, +28,250,22,159,2,248,22,170,20,23,202,1,23,202,1,11,249,22,81,11,205, +249,22,81,194,205,192,86,96,28,248,22,162,5,23,196,2,12,28,248,22,156, +4,23,198,2,250,22,181,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,183,11,2,22,2,33,23,198,2,28, +28,23,196,2,248,22,152,5,23,197,2,10,12,250,22,183,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, +156,4,23,198,2,10,12,250,22,183,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,79,23, +196,2,249,22,170,9,248,22,170,20,23,198,2,2,5,11,86,97,23,198,1, +23,197,1,23,196,1,23,193,1,248,22,153,5,248,22,103,23,197,1,28,28, +248,22,79,23,196,2,28,249,22,170,9,248,22,170,20,23,198,2,2,34,28, +248,22,79,248,22,103,23,197,2,249,22,170,9,248,22,107,23,198,2,2,5, +11,11,11,86,97,23,198,1,23,197,1,23,196,1,23,193,1,248,22,153,5, +249,2,81,248,22,120,23,199,2,248,22,105,23,199,1,28,28,248,22,79,23, +196,2,28,249,22,170,9,248,22,170,20,23,198,2,2,34,28,28,249,22,172, +9,248,22,103,23,198,2,2,36,10,249,22,172,9,248,22,103,23,198,2,2, +35,28,23,196,2,27,248,22,154,5,23,198,2,28,248,22,65,193,10,28,248, +22,79,193,248,22,65,248,22,170,20,194,11,11,11,11,11,86,96,23,198,1, +23,197,1,23,193,1,27,248,22,154,5,23,198,1,248,22,153,5,249,2,81, +28,248,22,79,23,197,2,248,22,170,20,23,197,2,23,196,2,27,28,249,22, +172,9,248,22,103,23,203,2,2,35,248,22,171,20,200,248,22,105,200,28,248, +22,79,23,198,2,249,22,95,248,22,171,20,199,194,192,28,28,248,22,79,23, +196,2,249,22,170,9,248,22,170,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,79,23,196,2,28,249,22,170,9,248, +22,170,20,23,198,2,2,34,28,248,22,79,248,22,103,23,197,2,249,22,170, +9,248,22,107,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,103,23,202,2,23,202,1,23,203,1,23,204, +1,248,22,105,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,79,23,198, +2,28,249,22,170,9,2,34,248,22,170,20,23,200,2,27,248,22,103,23,199, +2,28,28,249,22,172,9,23,195,2,2,36,10,249,22,172,9,23,195,2,2, +35,86,94,23,193,1,28,23,199,2,27,248,22,154,5,23,201,2,28,248,22, +79,193,248,22,170,20,193,192,250,22,179,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,79,23,199,2,28,249,22,170, +9,2,34,248,22,170,20,23,201,2,27,28,28,28,249,22,172,9,248,22,103, +23,202,2,2,36,10,249,22,172,9,248,22,103,23,202,2,2,35,23,200,2, +11,27,248,22,154,5,23,202,2,27,28,249,22,172,9,248,22,103,23,204,2, +2,35,248,22,171,20,23,202,1,248,22,105,23,202,1,28,248,22,79,23,195, +2,249,2,81,248,22,170,20,23,197,2,249,22,95,248,22,171,20,23,199,1, +23,197,1,249,2,81,23,196,1,23,195,1,249,2,81,2,36,28,249,22,172, +9,248,22,103,23,204,2,2,35,248,22,171,20,23,202,1,248,22,105,23,202, +1,28,248,22,79,193,248,22,171,20,193,11,86,94,23,198,1,11,86,94,23, +198,1,11,27,28,248,22,65,23,196,2,27,248,80,144,46,51,42,249,22,81, +23,199,2,248,22,133,17,247,22,146,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,72,23,201,2, +11,27,28,248,22,89,23,195,2,2,39,249,22,177,7,23,197,2,2,40,252, +80,144,53,8,23,42,23,205,1,28,248,22,89,23,200,2,23,200,1,86,94, +23,200,1,248,22,82,23,200,2,28,248,22,89,23,200,2,86,94,23,199,1, +9,248,22,83,23,200,1,23,198,1,10,28,248,22,154,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,81,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,89, +23,194,2,86,94,23,193,1,249,22,133,16,23,198,1,248,2,86,23,197,1, +250,22,1,22,133,16,23,199,1,249,22,95,249,22,2,32,0,88,148,8,36, +40,47,11,9,222,33,88,23,200,1,248,22,91,248,2,86,23,201,1,28,248, +22,179,15,23,196,2,86,94,23,196,1,248,80,144,45,8,30,42,248,22,143, +16,28,248,22,140,16,23,198,2,23,197,2,249,22,141,16,23,199,2,248,80, +144,49,8,29,42,23,205,2,28,249,22,170,9,248,22,82,23,198,2,2,32, +27,248,80,144,46,51,42,249,22,81,23,199,2,248,22,133,17,247,22,146,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,103,23,201,2,11,27,28,248,22,89,248,22,105,23,201, +2,28,248,22,89,23,195,2,249,22,176,16,2,89,23,197,2,11,10,27,28, +23,194,2,248,2,86,23,197,2,28,248,22,89,23,196,2,2,39,28,249,22, +176,16,2,89,23,198,2,248,2,86,23,197,2,249,22,177,7,23,198,2,2, +40,27,28,23,195,1,86,94,23,197,1,249,22,95,28,248,22,89,248,22,105, +23,205,2,21,93,6,5,5,109,122,108,105,98,249,22,1,22,95,249,22,2, +80,144,56,8,31,42,248,22,105,23,208,2,23,198,1,28,248,22,89,23,197, +2,86,94,23,196,1,248,22,91,23,198,1,86,94,23,197,1,23,196,1,252, +80,144,55,8,23,42,23,207,1,248,22,82,23,199,2,248,22,171,20,23,199, +1,23,199,1,10,86,94,23,196,1,28,249,22,170,9,248,22,170,20,23,198, +2,2,37,248,80,144,45,8,30,42,248,22,143,16,249,22,141,16,248,22,145, +16,248,22,103,23,201,2,248,80,144,49,8,29,42,23,205,2,12,86,94,28, +28,248,22,179,15,23,194,2,10,248,22,185,8,23,194,2,12,28,23,201,2, +250,22,181,11,69,114,101,113,117,105,114,101,249,22,138,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, +82,23,199,2,6,0,0,23,204,2,250,22,183,11,2,22,2,33,23,198,2, +27,28,248,22,185,8,23,195,2,249,22,190,8,23,196,2,39,249,22,143,16, +248,22,144,16,23,197,2,11,27,28,248,22,185,8,23,196,2,249,22,190,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,185,8,23,199,2,250,22,7,2,41,249,22,190,8,23,203, +2,41,2,41,248,22,136,16,23,198,2,86,95,23,195,1,23,193,1,27,28, +248,22,185,8,23,200,2,249,22,190,8,23,201,2,42,249,80,144,52,61,42, +23,197,2,5,0,27,28,248,22,185,8,23,201,2,249,22,190,8,23,202,2, +43,248,22,153,5,23,200,2,27,250,22,159,2,80,144,55,44,41,248,22,133, +17,247,22,146,14,11,27,28,23,194,2,23,194,1,86,94,23,194,1,27,249, +22,81,247,22,139,2,247,22,139,2,86,94,250,22,157,2,80,144,57,44,41, +248,22,133,17,247,22,146,14,195,192,27,28,23,204,2,248,22,153,5,249,22, +81,248,22,154,5,23,200,2,23,207,2,23,196,2,86,95,28,23,212,2,28, +250,22,159,2,248,22,82,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,133,17,247,22,146,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,86,96,23,211,1,23,204,1,23,194,1, +12,28,28,248,22,185,8,23,204,1,86,94,23,212,1,11,28,23,212,1,28, +248,22,154,7,23,206,2,10,28,248,22,65,23,206,2,10,28,248,22,79,23, +206,2,249,22,170,9,248,22,170,20,23,208,2,2,32,11,11,249,80,144,56, +52,42,28,248,22,154,7,23,208,2,249,22,81,23,209,1,248,80,144,59,8, +29,42,23,215,1,86,94,23,212,1,249,22,81,23,209,1,248,22,133,17,247, +22,146,14,252,22,187,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,191,4,80,144,40,60,41,248,22,177,5, +80,144,40,40,42,248,22,145,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,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,181,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,142,2, +80,144,39,44,40,20,15,16,2,8,128,8,80,144,39,49,40,20,15,16,2, +249,22,186,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,77,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, 9766); + } + { + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,8,54,46,51,46,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,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,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,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, 532); } diff --git a/racket/src/racket/src/fun.c b/racket/src/racket/src/fun.c index 5053cb3115..886628c73a 100644 --- a/racket/src/racket/src/fun.c +++ b/racket/src/racket/src/fun.c @@ -179,6 +179,7 @@ static Scheme_Object *procedure_reduce_arity(int argc, Scheme_Object *argv[]); static Scheme_Object *procedure_rename(int argc, Scheme_Object *argv[]); static Scheme_Object *procedure_to_method(int argc, Scheme_Object *argv[]); static Scheme_Object *procedure_equal_closure_p(int argc, Scheme_Object *argv[]); +static Scheme_Object *procedure_specialize(int argc, Scheme_Object *argv[]); static Scheme_Object *chaperone_procedure(int argc, Scheme_Object *argv[]); static Scheme_Object *impersonate_procedure(int argc, Scheme_Object *argv[]); static Scheme_Object *chaperone_procedure_star(int argc, Scheme_Object *argv[]); @@ -593,6 +594,11 @@ scheme_init_fun (Scheme_Env *env) "procedure-closure-contents-eq?", 2, 2, 1), env); + scheme_add_global_constant("procedure-specialize", + scheme_make_prim_w_arity(procedure_specialize, + "procedure-specialize", + 1, 1), + env); scheme_add_global_constant("chaperone-procedure", scheme_make_prim_w_arity(chaperone_procedure, "chaperone-procedure", @@ -3425,6 +3431,26 @@ static Scheme_Object *procedure_equal_closure_p(int argc, Scheme_Object *argv[]) return scheme_false; } +static Scheme_Object *procedure_specialize(int argc, Scheme_Object *argv[]) +{ + if (!SCHEME_PROCP(argv[0])) + scheme_wrong_contract("procedure-specialize", "procedure?", 0, argc, argv); + + if (SAME_TYPE(SCHEME_TYPE(argv[0]), scheme_native_closure_type)) { + Scheme_Native_Closure *nc = (Scheme_Native_Closure *)argv[0]; + if ((nc->code->start_code == scheme_on_demand_jit_code) + && !(SCHEME_NATIVE_CLOSURE_DATA_FLAGS(nc->code) & NATIVE_SPECIALIZED)) { + Scheme_Native_Closure_Data *data; + data = MALLOC_ONE_TAGGED(Scheme_Native_Closure_Data); + memcpy(data, nc->code, sizeof(Scheme_Native_Closure_Data)); + SCHEME_NATIVE_CLOSURE_DATA_FLAGS(data) |= NATIVE_SPECIALIZED; + nc->code = data; + } + } + + return argv[0]; +} + static Scheme_Object *do_chaperone_procedure(const char *name, const char *whating, int is_impersonator, int pass_self, int argc, Scheme_Object *argv[]) diff --git a/racket/src/racket/src/jit.c b/racket/src/racket/src/jit.c index a57816e51d..6dfcbcfa8b 100644 --- a/racket/src/racket/src/jit.c +++ b/racket/src/racket/src/jit.c @@ -453,18 +453,16 @@ Scheme_Object *scheme_extract_global(Scheme_Object *o, Scheme_Native_Closure *nc return globs->a[pos]; } -Scheme_Object *scheme_extract_closure_local(Scheme_Object *obj, mz_jit_state *jitter, int extra_push) +static Scheme_Object *extract_closure_local(int pos, mz_jit_state *jitter, int get_constant) { - int pos; - - pos = SCHEME_LOCAL_POS(obj); - pos -= extra_push; if (pos >= jitter->self_pos - jitter->self_to_closure_delta) { pos -= (jitter->self_pos - jitter->self_to_closure_delta); if (pos < jitter->nc->code->u2.orig_code->closure_size) { /* in the closure */ - return jitter->nc->vals[pos]; - } else { + if (!get_constant + || (SCHEME_NATIVE_CLOSURE_DATA_FLAGS(jitter->nc->code) & NATIVE_SPECIALIZED)) + return jitter->nc->vals[pos]; + } else if (!get_constant) { /* maybe an example argument... which is useful when the enclosing function has been lifted, converting a closure element into an argument */ @@ -477,6 +475,43 @@ Scheme_Object *scheme_extract_closure_local(Scheme_Object *obj, mz_jit_state *ji return NULL; } +Scheme_Object *scheme_extract_closure_local(Scheme_Object *obj, mz_jit_state *jitter, + int extra_push, int get_constant) +{ + int pos; + + pos = SCHEME_LOCAL_POS(obj); + pos -= extra_push; + return extract_closure_local(pos, jitter, get_constant); +} + + +Scheme_Object *scheme_specialize_to_constant(Scheme_Object *obj, mz_jit_state *jitter, int extra_push) +{ + Scheme_Object *c; + + if (SCHEME_NATIVE_CLOSURE_DATA_FLAGS(jitter->nc->code) & NATIVE_SPECIALIZED) { + if (SAME_TYPE(SCHEME_TYPE(obj), scheme_local_type)) { + c = scheme_extract_closure_local(obj, jitter, extra_push, 1); + if (c) { + MZ_ASSERT(SCHEME_TYPE(c) != scheme_prefix_type); + return c; + } + } + + if (SAME_TYPE(SCHEME_TYPE(obj), scheme_toplevel_type)) { + c = scheme_extract_global(obj, jitter->nc, 0); + if (c) { + c = ((Scheme_Bucket *)c)->val; + if (c) + return c; + } + } + } + + return obj; +} + int scheme_native_closure_preserves_marks(Scheme_Object *p) { Scheme_Native_Closure_Data *ndata = ((Scheme_Native_Closure *)p)->code; @@ -496,6 +531,8 @@ int scheme_native_closure_preserves_marks(Scheme_Object *p) int scheme_is_noncm(Scheme_Object *a, mz_jit_state *jitter, int depth, int stack_start) { + a = scheme_specialize_to_constant(a, jitter, stack_start); + if (SCHEME_PRIMP(a)) { int opts; opts = ((Scheme_Prim_Proc_Header *)a)->flags & SCHEME_PRIM_OPT_MASK; @@ -601,27 +638,40 @@ int scheme_is_simple(Scheme_Object *obj, int depth, int just_markless, mz_jit_st break; case scheme_application_type: - if (scheme_inlined_nary_prim(((Scheme_App_Rec *)obj)->args[0], obj, jitter) - && !SAME_OBJ(((Scheme_App_Rec *)obj)->args[0], scheme_values_func)) - return 1; - if (just_markless) { - return scheme_is_noncm(((Scheme_App_Rec *)obj)->args[0], jitter, depth, - stack_start + ((Scheme_App_Rec *)obj)->num_args); + { + Scheme_Object *rator; + rator = scheme_specialize_to_constant(((Scheme_App_Rec *)obj)->args[0], jitter, + stack_start + ((Scheme_App_Rec *)obj)->num_args); + if (scheme_inlined_nary_prim(rator, obj, jitter) + && !SAME_OBJ(rator, scheme_values_func)) + return 1; + if (just_markless) { + return scheme_is_noncm(rator, jitter, depth, + stack_start + ((Scheme_App_Rec *)obj)->num_args); + } } break; case scheme_application2_type: - if (scheme_inlined_unary_prim(((Scheme_App2_Rec *)obj)->rator, obj, jitter)) - return 1; - else if (just_markless) { - return scheme_is_noncm(((Scheme_App2_Rec *)obj)->rator, jitter, depth, stack_start + 1); + { + Scheme_Object *rator; + rator = scheme_specialize_to_constant(((Scheme_App2_Rec *)obj)->rator, jitter, stack_start + 1); + if (scheme_inlined_unary_prim(rator, obj, jitter)) + return 1; + else if (just_markless) { + return scheme_is_noncm(rator, jitter, depth, stack_start + 1); + } } break; case scheme_application3_type: - if (scheme_inlined_binary_prim(((Scheme_App2_Rec *)obj)->rator, obj, jitter) - && !SAME_OBJ(((Scheme_App2_Rec *)obj)->rator, scheme_values_func)) - return 1; - else if (just_markless) { - return scheme_is_noncm(((Scheme_App3_Rec *)obj)->rator, jitter, depth, stack_start + 2); + { + Scheme_Object *rator; + rator = scheme_specialize_to_constant(((Scheme_App3_Rec *)obj)->rator, jitter, stack_start + 2); + if (scheme_inlined_binary_prim(rator, obj, jitter) + && !SAME_OBJ(rator, scheme_values_func)) + return 1; + else if (just_markless) { + return scheme_is_noncm(rator, jitter, depth, stack_start + 2); + } } break; @@ -1177,7 +1227,7 @@ static int generate_closure(Scheme_Closure_Data *data, jit_movi_l(JIT_R1, init_word); jit_str_l(JIT_R0, JIT_R1); } - scheme_mz_load_retained(jitter, JIT_R1, code); + scheme_mz_load_retained(jitter, JIT_R1, code, 0); jit_stxi_p((intptr_t)&((Scheme_Native_Closure *)0x0)->code, JIT_R0, JIT_R1); return 1; @@ -1187,7 +1237,7 @@ static int generate_closure(Scheme_Closure_Data *data, JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); mz_prepare(1); - scheme_mz_load_retained(jitter, JIT_R0, code); + scheme_mz_load_retained(jitter, JIT_R0, code, 0); jit_pusharg_p(JIT_R0); { GC_CAN_IGNORE jit_insn *refr USED_ONLY_FOR_FUTURES; @@ -1337,7 +1387,7 @@ static int generate_case_closure(Scheme_Object *obj, mz_jit_state *jitter, int t JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); mz_prepare(1); - scheme_mz_load_retained(jitter, JIT_R0, ndata); + scheme_mz_load_retained(jitter, JIT_R0, ndata, 0); jit_pusharg_p(JIT_R0); { GC_CAN_IGNORE jit_insn *refr USED_ONLY_FOR_FUTURES; @@ -1686,6 +1736,9 @@ static int generate_branch(Scheme_Object *obj, mz_jit_state *jitter, int is_tail } CHECK_LIMIT(); + if (old_self_pos != jitter->self_pos) + scheme_signal_error("internal error: self position moved across test"); + save_ubd = jitter->unbox_depth; scheme_mz_unbox_restore(jitter, &ubs); @@ -1923,6 +1976,8 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w } #endif + obj = scheme_specialize_to_constant(obj, jitter, 0); + orig_target = target; result_ignored = (target < 0); if (target < 0) target = JIT_R0; @@ -1948,12 +2003,20 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w START_JIT_DATA(); LOG_IT(("top-level\n")); mz_rs_sync_fail_branch(); - /* Load global array: */ - pos = mz_remap(SCHEME_TOPLEVEL_DEPTH(obj)); - mz_rs_ldxi(JIT_R2, pos); - /* Load bucket: */ - pos = SCHEME_TOPLEVEL_POS(obj); - jit_ldxi_p(JIT_R2, JIT_R2, &(((Scheme_Prefix *)0x0)->a[pos])); + if (SCHEME_NATIVE_CLOSURE_DATA_FLAGS(jitter->nc->code) & NATIVE_SPECIALIZED) { + /* Must be a top-level that is not yet defined. */ + Scheme_Object *b; + mz_rs_sync_fail_branch(); + b = scheme_extract_global(obj, jitter->nc, 0); + scheme_mz_load_retained(jitter, JIT_R2, b, 1); + } else { + /* Load global array: */ + pos = mz_remap(SCHEME_TOPLEVEL_DEPTH(obj)); + mz_rs_ldxi(JIT_R2, pos); + /* Load bucket: */ + pos = SCHEME_TOPLEVEL_POS(obj); + jit_ldxi_p(JIT_R2, JIT_R2, &(((Scheme_Prefix *)0x0)->a[pos])); + } /* Extract bucket value */ jit_ldxi_p(target, JIT_R2, &(SCHEME_VAR_BUCKET(0x0)->val)); CHECK_LIMIT(); @@ -2054,15 +2117,23 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w case scheme_local_unbox_type: { int pos; + Scheme_Object *specialized = NULL; START_JIT_DATA(); LOG_IT(("unbox local\n")); + if (SCHEME_NATIVE_CLOSURE_DATA_FLAGS(jitter->nc->code) & NATIVE_SPECIALIZED) + specialized = scheme_extract_closure_local(obj, jitter, 0, 1); + pos = mz_remap(SCHEME_LOCAL_POS(obj)); if (!result_ignored) { - mz_rs_ldxi(JIT_R0, pos); + if (specialized) + scheme_mz_load_retained(jitter, JIT_R0, specialized, 1); + else + mz_rs_ldxi(JIT_R0, pos); jit_ldr_p(target, JIT_R0); } - if (SCHEME_GET_LOCAL_FLAGS(obj) == SCHEME_LOCAL_CLEAR_ON_READ) { + if ((SCHEME_GET_LOCAL_FLAGS(obj) == SCHEME_LOCAL_CLEAR_ON_READ) + && !specialized) { LOG_IT(("clear-on-read\n")); mz_rs_stxi(pos, JIT_RUNSTACK); } @@ -2256,6 +2327,9 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w v = SCHEME_PTR1_VAL(obj); p = SCHEME_PTR2_VAL(obj); + v = scheme_specialize_to_constant(v, jitter, 0); + p = scheme_specialize_to_constant(p, jitter, 0); + scheme_generate_non_tail(v, jitter, 0, 1, 0); CHECK_LIMIT(); @@ -2727,13 +2801,20 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w if (lv->count == 1) { /* Expect one result: */ + Scheme_Object *specialized = NULL; + if (SCHEME_NATIVE_CLOSURE_DATA_FLAGS(jitter->nc->code) & NATIVE_SPECIALIZED) + specialized = extract_closure_local(lv->position, jitter, 1); scheme_generate_non_tail(lv->value, jitter, 0, 1, 0); /* no sync */ CHECK_LIMIT(); if (ab) { pos = mz_remap(lv->position); - mz_rs_ldxi(JIT_R2, pos); + if (specialized) + scheme_mz_load_retained(jitter, JIT_R2, specialized, 1); + else + mz_rs_ldxi(JIT_R2, pos); jit_str_p(JIT_R2, JIT_R0); } else { + MZ_ASSERT(!specialized); pos = mz_remap(lv->position); mz_rs_stxi(pos, JIT_R0); } @@ -3206,7 +3287,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w } } - scheme_mz_load_retained(jitter, target, obj); + scheme_mz_load_retained(jitter, target, obj, 0); END_JIT_DATA(19); return 1; @@ -3347,6 +3428,7 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data) void *retain_code = NULL; #endif int i, r, cnt, has_rest, is_method, num_params, to_args, argc, argv_delta; + int specialized; Scheme_Object **argv; start_code = jit_get_ip(); @@ -3549,26 +3631,32 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data) to_args = 0; #endif + specialized = SCHEME_NATIVE_CLOSURE_DATA_FLAGS(jitter->nc->code) & NATIVE_SPECIALIZED; + /* Extract closure to runstack: */ cnt = data->closure_size; to_args += cnt; if (cnt) { - mz_rs_dec(cnt); - CHECK_RUNSTACK_OVERFLOW(); + if (specialized) { + /* References to closure data will be replaced with values */ + } else { + mz_rs_dec(cnt); + CHECK_RUNSTACK_OVERFLOW(); - for (i = cnt; i--; ) { - int pos; - pos = WORDS_TO_BYTES(i) + (intptr_t)&((Scheme_Native_Closure *)0x0)->vals; - jit_ldxi_p(JIT_R1, JIT_R0, pos); - mz_rs_stxi(i, JIT_R1); - CHECK_LIMIT(); + for (i = cnt; i--; ) { + int pos; + pos = WORDS_TO_BYTES(i) + (intptr_t)&((Scheme_Native_Closure *)0x0)->vals; + jit_ldxi_p(JIT_R1, JIT_R0, pos); + mz_rs_stxi(i, JIT_R1); + CHECK_LIMIT(); + } } } mz_rs_sync(); /* If we have a letrec context, record arities */ - if (data->context && SAME_TYPE(SCHEME_TYPE(data->context), scheme_letrec_type)) { + if (data->context && SAME_TYPE(SCHEME_TYPE(data->context), scheme_letrec_type) && !specialized) { Scheme_Letrec *lr = (Scheme_Letrec *)data->context; int pos, self_pos = -1; for (i = data->closure_size; i--; ) { @@ -3614,7 +3702,7 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data) } else { #ifdef USE_FLONUM_UNBOXING /* Unpack flonum closure data */ - if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_TYPED_ARGS) { + if ((SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_TYPED_ARGS) && !specialized) { for (i = data->closure_size; i--; ) { if (CLOSURE_CONTENT_IS_FLONUM(data, i) || CLOSURE_CONTENT_IS_EXTFLONUM(data, i)) { @@ -3632,7 +3720,12 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data) } } else #endif - mz_runstack_pushed(jitter, cnt); + { + if (specialized) + mz_runstack_skipped(jitter, cnt); + else + mz_runstack_pushed(jitter, cnt); + } /* A define-values context? */ if (data->context && SAME_TYPE(SCHEME_TYPE(data->context), scheme_toplevel_type)) { @@ -3738,6 +3831,9 @@ static void on_demand_generate_lambda(Scheme_Native_Closure *nc, int argc, Schem abort(); } + if (SCHEME_NATIVE_CLOSURE_DATA_FLAGS(ndata) & NATIVE_SPECIALIZED) + SCHEME_NATIVE_CLOSURE_DATA_FLAGS(ndata) -= NATIVE_SPECIALIZED; + if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_PRESERVES_MARKS) SCHEME_NATIVE_CLOSURE_DATA_FLAGS(ndata) |= NATIVE_PRESERVES_MARKS; if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_SINGLE_RESULT) diff --git a/racket/src/racket/src/jit.h b/racket/src/racket/src/jit.h index 16901f34bd..44cb45d251 100644 --- a/racket/src/racket/src/jit.h +++ b/racket/src/racket/src/jit.h @@ -152,8 +152,10 @@ END_XFORM_ARITH; # define SCHEME_FLOAT_TYPE scheme_double_type #endif +/* These flags are set post-JIT: */ #define NATIVE_PRESERVES_MARKS 0x1 #define NATIVE_IS_SINGLE_RESULT 0x2 +/* Pre-JIT flags rae in "schpriv.h" */ #if defined(MZ_PRECISE_GC) && !defined(USE_COMPACT_3M_GC) # define CAN_INLINE_ALLOC @@ -1367,7 +1369,7 @@ int scheme_stack_safety(mz_jit_state *jitter, int cnt, int offset); #ifdef USE_FLONUM_UNBOXING int scheme_mz_flostack_pos(mz_jit_state *jitter, int i); #endif -void scheme_mz_load_retained(mz_jit_state *jitter, int rs, void *o); +void scheme_mz_load_retained(mz_jit_state *jitter, int rs, void *o, int non_obj); void scheme_mz_runstack_skipped(mz_jit_state *jitter, int n); void scheme_mz_runstack_unskipped(mz_jit_state *jitter, int n); @@ -1587,7 +1589,8 @@ int scheme_jit_check_closure_extflonum_bit(Scheme_Closure_Data *data, int pos, i #endif Scheme_Object *scheme_extract_global(Scheme_Object *o, Scheme_Native_Closure *nc, int local_only); -Scheme_Object *scheme_extract_closure_local(Scheme_Object *obj, mz_jit_state *jitter, int extra_push); +Scheme_Object *scheme_extract_closure_local(Scheme_Object *obj, mz_jit_state *jitter, int extra_push, int get_constant); +Scheme_Object *scheme_specialize_to_constant(Scheme_Object *obj, mz_jit_state *jitter, int extra_push); void scheme_jit_register_traversers(void); #ifdef MZ_USE_LWC diff --git a/racket/src/racket/src/jitcall.c b/racket/src/racket/src/jitcall.c index 44bc298bcf..73f058aaaf 100644 --- a/racket/src/racket/src/jitcall.c +++ b/racket/src/racket/src/jitcall.c @@ -479,7 +479,7 @@ int scheme_generate_tail_call(mz_jit_state *jitter, int num_rands, int direct_na if (direct_native && direct_to_code) { __END_SHORT_JUMPS__(num_rands < 100); /* load closure pointer into R0: */ - scheme_mz_load_retained(jitter, JIT_R0, direct_to_code); + scheme_mz_load_retained(jitter, JIT_R0, direct_to_code, 0); /* jump directly: */ (void)jit_jmpi(direct_to_code->code->u.tail_code); /* no slow path in this mode */ @@ -1762,6 +1762,8 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ rator = (alt_rands ? alt_rands[0] : app->args[0]); + rator = scheme_specialize_to_constant(rator, jitter, num_rands); + if (no_call == 2) { direct_prim = 1; } else if (SCHEME_PRIMP(rator)) { @@ -1828,6 +1830,9 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ } } } + } else if (SAME_TYPE(t, scheme_native_closure_type)) { + direct_native = can_direct_native(rator, num_rands, &extract_case); + reorder_ok = 1; } else if (SAME_TYPE(t, scheme_closure_type)) { Scheme_Closure_Data *data; data = ((Scheme_Closure *)rator)->code; diff --git a/racket/src/racket/src/jitinline.c b/racket/src/racket/src/jitinline.c index 2e6e6b0a7b..080edec928 100644 --- a/racket/src/racket/src/jitinline.c +++ b/racket/src/racket/src/jitinline.c @@ -174,7 +174,7 @@ static int inlineable_struct_prim(Scheme_Object *o, mz_jit_state *jitter, int ex return check_val_struct_prim(p, arity); } else if (SAME_TYPE(SCHEME_TYPE(o), scheme_local_type)) { Scheme_Object *p; - p = scheme_extract_closure_local(o, jitter, extra_push); + p = scheme_extract_closure_local(o, jitter, extra_push, 0); return check_val_struct_prim(p, arity); } } @@ -947,6 +947,8 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in { Scheme_Object *rator = app->rator; + rator = scheme_specialize_to_constant(rator, jitter, 1); + { int k; k = inlineable_struct_prim(rator, jitter, 1, 1); @@ -2088,6 +2090,9 @@ int scheme_generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_ Return is 1 if thr arguments are in order, -1 if reversed. */ { int simple1, simple2, direction = 1; + + rand1 = scheme_specialize_to_constant(rand1, jitter, skipped); + rand2 = scheme_specialize_to_constant(rand2, jitter, skipped); simple1 = scheme_is_relatively_constant_and_avoids_r1(rand1, rand2); simple2 = scheme_is_relatively_constant_and_avoids_r1(rand2, rand1); @@ -2480,6 +2485,8 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i { Scheme_Object *rator = app->rator; + rator = scheme_specialize_to_constant(rator, jitter, 2); + if (SCHEME_PRIMP(rator) && IS_NAMED_PRIM(rator, "ptr-ref")) { Scheme_App_Rec *app2; mz_rs_sync(); @@ -2550,7 +2557,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i && !SCHEME_FALSEP(a1) && !SCHEME_VOIDP(a1) && !SAME_OBJ(a1, scheme_true)) { - scheme_mz_load_retained(jitter, JIT_R1, a1); + scheme_mz_load_retained(jitter, JIT_R1, a1, 0); ref = jit_bner_p(jit_forward(), JIT_R0, JIT_R1); /* In case true is a fall-through, note that the test didn't disturb R0: */ @@ -3837,7 +3844,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i ref = jit_bnei_p(jit_forward(), JIT_R0, scheme_undefined); __END_TINY_JUMPS__(1); - scheme_mz_load_retained(jitter, JIT_R1, app->rand2); + scheme_mz_load_retained(jitter, JIT_R1, app->rand2, 0); if (IS_NAMED_PRIM(rator, "check-not-unsafe-undefined")) (void)jit_calli(sjc.call_check_not_defined_code); else @@ -3950,7 +3957,9 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int /* de-sync's; for branch, sync'd before */ { Scheme_Object *rator = app->args[0]; - + + rator = scheme_specialize_to_constant(rator, jitter, app->num_args); + if (!for_branch) { int k; k = inlineable_struct_prim(rator, jitter, app->num_args, app->num_args); diff --git a/racket/src/racket/src/jitstate.c b/racket/src/racket/src/jitstate.c index 42040bb6f2..575cce824e 100644 --- a/racket/src/racket/src/jitstate.c +++ b/racket/src/racket/src/jitstate.c @@ -70,14 +70,15 @@ int scheme_mz_retain_it(mz_jit_state *jitter, void *v) return jitter->retained; } -void scheme_mz_load_retained(mz_jit_state *jitter, int rs, void *obj) +void scheme_mz_load_retained(mz_jit_state *jitter, int rs, void *obj, int non_obj) /* obj is a pointer, but not necesarily tagged (in CGC) */ { - if (!SCHEME_INTP((Scheme_Object *)obj) - && !SAME_OBJ((Scheme_Object *)obj, scheme_true) - && !SAME_OBJ((Scheme_Object *)obj, scheme_false) - && !SAME_OBJ((Scheme_Object *)obj, scheme_void) - && !SAME_OBJ((Scheme_Object *)obj, scheme_null)) { + if (non_obj + || (!SCHEME_INTP((Scheme_Object *)obj) + && !SAME_OBJ((Scheme_Object *)obj, scheme_true) + && !SAME_OBJ((Scheme_Object *)obj, scheme_false) + && !SAME_OBJ((Scheme_Object *)obj, scheme_void) + && !SAME_OBJ((Scheme_Object *)obj, scheme_null))) { #ifdef JIT_PRECISE_GC int retptr; void *p; diff --git a/racket/src/racket/src/schminc.h b/racket/src/racket/src/schminc.h index 4e010a8f14..2c50dd4b5c 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 1140 +#define EXPECTED_PRIM_COUNT 1141 #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 1f26f0b3f5..b76978cd72 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -2788,6 +2788,10 @@ typedef struct Scheme_Native_Closure_Data { #define SCHEME_NATIVE_CLOSURE_DATA_FLAGS(obj) MZ_OPT_HASH_KEY(&(obj)->iso) +/* This flag is set pre-JIT: */ +#define NATIVE_SPECIALIZED 0x1 +/* Other flags are in "jit.h" */ + typedef struct { Scheme_Object so; Scheme_Native_Closure_Data *code; diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 5fd088b00f..7224f9d8be 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.9" +#define MZSCHEME_VERSION "6.3.0.10" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 3 #define MZSCHEME_VERSION_Z 0 -#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 44e12626483675ca12e038ad8af81169506ba21e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 23 Dec 2015 21:51:14 -0700 Subject: [PATCH 230/369] unbreak no-JIT build --- racket/src/racket/src/fun.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/src/fun.c b/racket/src/racket/src/fun.c index 886628c73a..0c38151030 100644 --- a/racket/src/racket/src/fun.c +++ b/racket/src/racket/src/fun.c @@ -3435,7 +3435,8 @@ static Scheme_Object *procedure_specialize(int argc, Scheme_Object *argv[]) { if (!SCHEME_PROCP(argv[0])) scheme_wrong_contract("procedure-specialize", "procedure?", 0, argc, argv); - + +#ifdef MZ_USE_JIT if (SAME_TYPE(SCHEME_TYPE(argv[0]), scheme_native_closure_type)) { Scheme_Native_Closure *nc = (Scheme_Native_Closure *)argv[0]; if ((nc->code->start_code == scheme_on_demand_jit_code) @@ -3447,7 +3448,8 @@ static Scheme_Object *procedure_specialize(int argc, Scheme_Object *argv[]) nc->code = data; } } - +#endif + return argv[0]; } From ba2eb6487c44b08043225f04809c0d619afc53cd Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 23 Dec 2015 22:06:18 -0700 Subject: [PATCH 231/369] restore precision for `procedure-closure-contents-eq?` After adding `procedure-specialize`, making `procedure-closure-contents-eq?` work as before involves a little extra tracking. I'd prefer to weaken or even get rid of `procedure-closure-contents-eq?`, but this adjustment keeps some contract tests passing. --- racket/src/racket/src/fun.c | 8 +++++++- racket/src/racket/src/mzmark_jit.inc | 2 ++ racket/src/racket/src/mzmarksrc.c | 1 + racket/src/racket/src/schpriv.h | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/racket/src/racket/src/fun.c b/racket/src/racket/src/fun.c index 0c38151030..b1aff09b65 100644 --- a/racket/src/racket/src/fun.c +++ b/racket/src/racket/src/fun.c @@ -3377,7 +3377,8 @@ static Scheme_Object *procedure_equal_closure_p(int argc, Scheme_Object *argv[]) Scheme_Native_Closure *c1 = (Scheme_Native_Closure *)v1; Scheme_Native_Closure *c2 = (Scheme_Native_Closure *)v2; - if (SAME_OBJ(c1->code, c2->code)) { + if (SAME_OBJ(c1->code, c2->code) + || (c1->code->eq_key && SAME_OBJ(c1->code->eq_key, c2->code->eq_key))) { int i; i = c1->code->closure_size; if (i < 0) { @@ -3442,6 +3443,11 @@ static Scheme_Object *procedure_specialize(int argc, Scheme_Object *argv[]) if ((nc->code->start_code == scheme_on_demand_jit_code) && !(SCHEME_NATIVE_CLOSURE_DATA_FLAGS(nc->code) & NATIVE_SPECIALIZED)) { Scheme_Native_Closure_Data *data; + if (!nc->code->eq_key) { + void *p; + p = scheme_malloc_atomic(sizeof(int)); + nc->code->eq_key = p; + } data = MALLOC_ONE_TAGGED(Scheme_Native_Closure_Data); memcpy(data, nc->code, sizeof(Scheme_Native_Closure_Data)); SCHEME_NATIVE_CLOSURE_DATA_FLAGS(data) |= NATIVE_SPECIALIZED; diff --git a/racket/src/racket/src/mzmark_jit.inc b/racket/src/racket/src/mzmark_jit.inc index a6cbabd86d..aeb5be06da 100644 --- a/racket/src/racket/src/mzmark_jit.inc +++ b/racket/src/racket/src/mzmark_jit.inc @@ -158,6 +158,7 @@ static int native_unclosed_proc_MARK(void *p, struct NewGC *gc) { gcMARK2(d->u.arities, gc); } gcMARK2(d->tl_map, gc); + gcMARK2(d->eq_key, gc); # ifdef GC_NO_SIZE_NEEDED_FROM_PROCS return 0; @@ -183,6 +184,7 @@ static int native_unclosed_proc_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(d->u.arities, gc); } gcFIXUP2(d->tl_map, gc); + gcFIXUP2(d->eq_key, gc); # ifdef GC_NO_SIZE_NEEDED_FROM_PROCS return 0; diff --git a/racket/src/racket/src/mzmarksrc.c b/racket/src/racket/src/mzmarksrc.c index 96d438a8df..d099050a6d 100644 --- a/racket/src/racket/src/mzmarksrc.c +++ b/racket/src/racket/src/mzmarksrc.c @@ -2511,6 +2511,7 @@ native_unclosed_proc { gcMARK2(d->u.arities, gc); } gcMARK2(d->tl_map, gc); + gcMARK2(d->eq_key, gc); size: gcBYTES_TO_WORDS(sizeof(Scheme_Native_Closure_Data)); diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index b76978cd72..f1ea327d3a 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -2784,6 +2784,7 @@ typedef struct Scheme_Native_Closure_Data { /* Thumb code is off by one, need real start for GC */ void *retain_code; #endif + void *eq_key; /* for `procedure-closure-contents-eq?` */ } Scheme_Native_Closure_Data; #define SCHEME_NATIVE_CLOSURE_DATA_FLAGS(obj) MZ_OPT_HASH_KEY(&(obj)->iso) From c1950f1ae307a68c50e3ed3f57c2d47f2a70e011 Mon Sep 17 00:00:00 2001 From: ven Date: Thu, 24 Dec 2015 10:11:56 +0100 Subject: [PATCH 232/369] Fix small typo in jit.h Just noticed it while reading db0a6de1d2d5d3059ec971275b287860c5bda6e2 --- racket/src/racket/src/jit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/src/racket/src/jit.h b/racket/src/racket/src/jit.h index 44cb45d251..539d550d46 100644 --- a/racket/src/racket/src/jit.h +++ b/racket/src/racket/src/jit.h @@ -155,7 +155,7 @@ END_XFORM_ARITH; /* These flags are set post-JIT: */ #define NATIVE_PRESERVES_MARKS 0x1 #define NATIVE_IS_SINGLE_RESULT 0x2 -/* Pre-JIT flags rae in "schpriv.h" */ +/* Pre-JIT flags are in "schpriv.h" */ #if defined(MZ_PRECISE_GC) && !defined(USE_COMPACT_3M_GC) # define CAN_INLINE_ALLOC From 843992d0c72a5331d5042c619e6b4777efb1a75c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 24 Dec 2015 12:17:31 -0600 Subject: [PATCH 233/369] use specialization opportunity for `#%apply-values` --- racket/src/racket/src/jit.c | 348 ++++++++++++++++++------------ racket/src/racket/src/jit.h | 11 +- racket/src/racket/src/jitarith.c | 2 +- racket/src/racket/src/jitcall.c | 37 +++- racket/src/racket/src/jitinline.c | 20 +- racket/src/racket/src/jitstate.c | 26 ++- 6 files changed, 269 insertions(+), 175 deletions(-) diff --git a/racket/src/racket/src/jit.c b/racket/src/racket/src/jit.c index 6dfcbcfa8b..82f68277da 100644 --- a/racket/src/racket/src/jit.c +++ b/racket/src/racket/src/jit.c @@ -928,6 +928,54 @@ int scheme_needs_only_target_register(Scheme_Object *obj, int and_can_reorder) return (t >= _scheme_compiled_values_types_); } +static int produces_single_value(Scheme_Object *rator, int num_args, mz_jit_state *jitter) +{ + rator = scheme_specialize_to_constant(rator, jitter, num_args); + + if (SAME_TYPE(SCHEME_TYPE(rator), scheme_native_closure_type)) { + Scheme_Native_Closure *nc = (Scheme_Native_Closure *)rator; + if (nc->code->start_code == scheme_on_demand_jit_code) + return (SCHEME_CLOSURE_DATA_FLAGS(nc->code->u2.orig_code) & CLOS_SINGLE_RESULT); + else + return (SCHEME_NATIVE_CLOSURE_DATA_FLAGS(nc->code) & NATIVE_IS_SINGLE_RESULT); + } + + if (SCHEME_PRIMP(rator)) { + int opt; + opt = ((Scheme_Prim_Proc_Header *)rator)->flags & SCHEME_PRIM_OPT_MASK; + if (opt >= SCHEME_PRIM_OPT_NONCM) + return 1; + + /* special case: (values ) */ + if (SAME_OBJ(rator, scheme_values_func) && (num_args == 1)) + return 1; + } + + return 0; +} + +static int is_single_valued(Scheme_Object *obj, mz_jit_state *jitter) +{ + Scheme_Type t = SCHEME_TYPE(obj); + + switch(t) { + case scheme_application_type: + return produces_single_value(((Scheme_App_Rec *)obj)->args[0], ((Scheme_App_Rec *)obj)->num_args, jitter); + break; + case scheme_application2_type: + return produces_single_value(((Scheme_App2_Rec *)obj)->rator, 1, jitter); + break; + case scheme_application3_type: + return produces_single_value(((Scheme_App3_Rec *)obj)->rator, 2, jitter); + break; + default: + if (t > _scheme_values_types_) + return 1; + } + + return 0; +} + /*========================================================================*/ /* branch info */ /*========================================================================*/ @@ -2319,7 +2367,6 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w case scheme_apply_values_type: { Scheme_Object *p, *v; - GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *ref5, *refloop; START_JIT_DATA(); LOG_IT(("appvals\n")); @@ -2330,146 +2377,169 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w v = scheme_specialize_to_constant(v, jitter, 0); p = scheme_specialize_to_constant(p, jitter, 0); - scheme_generate_non_tail(v, jitter, 0, 1, 0); - CHECK_LIMIT(); + if (is_single_valued(p, jitter)) { + /* We might discover late that `v` produces a single value, + possibly because we're in a specialized closure. In that + case, use a plain application. */ + Scheme_Object *alt_rands[2]; + int r; + + alt_rands[0] = v; + alt_rands[1] = p; + + r = scheme_generate_app(NULL, alt_rands, 1, 0, jitter, is_tail, multi_ok, result_ignored, 0); - /* If v is not known to produce a procedure, then check result: */ - if (!is_a_procedure(v, jitter)) { - mz_rs_sync(); - (void)jit_bmsi_l(sjc.bad_app_vals_target, JIT_R0, 0x1); - jit_ldxi_s(JIT_R1, JIT_R0, &((Scheme_Object *)0x0)->type); - (void)jit_blti_i(sjc.bad_app_vals_target, JIT_R1, scheme_prim_type); - (void)jit_bgti_i(sjc.bad_app_vals_target, JIT_R1, scheme_proc_chaperone_type); CHECK_LIMIT(); - } - - mz_pushr_p(JIT_R0); - scheme_generate_non_tail(p, jitter, 1, 1, 0); - CHECK_LIMIT(); - - mz_popr_p(JIT_V1); - /* Function is in V1, argument(s) in R0 */ - - mz_rs_sync(); - - __START_SHORT_JUMPS__(1); - ref = jit_beqi_p(jit_forward(), JIT_R0, SCHEME_MULTIPLE_VALUES); - /* Single-value case: --------------- */ - /* We definitely have stack space for one argument, because we - just used it for the rator. */ - if (is_tail) { - mz_ld_runstack_base_alt(JIT_RUNSTACK); - jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK_BASE_OR_ALT(JIT_RUNSTACK), WORDS_TO_BYTES(1)); - } else { - jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); - } - CHECK_RUNSTACK_OVERFLOW(); - jit_str_p(JIT_RUNSTACK, JIT_R0); - jit_movi_l(JIT_R0, 1); - ref2 = jit_jmpi(jit_forward()); - CHECK_LIMIT(); - - /* Multiple-values case: ------------ */ - mz_patch_branch(ref); - /* Get new argc: */ - (void)mz_tl_ldi_p(JIT_R1, tl_scheme_current_thread); - jit_ldxi_l(JIT_R2, JIT_R1, &((Scheme_Thread *)0x0)->ku.multiple.count); - /* Enough room on runstack? */ - mz_tl_ldi_p(JIT_R0, tl_MZ_RUNSTACK_START); - if (is_tail) { - mz_ld_runstack_base_alt(JIT_R0); - jit_subr_ul(JIT_R0, JIT_RUNSTACK_BASE_OR_ALT(JIT_R0), JIT_R0); - } else { - jit_subr_ul(JIT_R0, JIT_RUNSTACK, JIT_R0); - } - CHECK_LIMIT(); - /* R0 is space left (in bytes), R2 is argc */ - jit_lshi_l(JIT_R2, JIT_R2, JIT_LOG_WORD_SIZE); - if (is_tail) { - int fpos, fstack; - fstack = scheme_mz_flostack_save(jitter, &fpos); - __END_SHORT_JUMPS__(1); - scheme_mz_flostack_restore(jitter, 0, 0, 1, 1); - (void)jit_bltr_ul(sjc.app_values_tail_slow_code, JIT_R0, JIT_R2); - __START_SHORT_JUMPS__(1); - scheme_mz_flostack_restore(jitter, fstack, fpos, 0, 1); - ref5 = 0; - } else { - GC_CAN_IGNORE jit_insn *refok; - refok = jit_bger_ul(jit_forward(), JIT_R0, JIT_R2); - __END_SHORT_JUMPS__(1); - if (multi_ok) { - (void)jit_calli(sjc.app_values_multi_slow_code); - } else { - (void)jit_calli(sjc.app_values_slow_code); - } - __START_SHORT_JUMPS__(1); - ref5 = jit_jmpi(jit_forward()); - mz_patch_branch(refok); - } - CHECK_LIMIT(); - if (is_tail) { - mz_ld_runstack_base_alt(JIT_RUNSTACK); - jit_subr_ul(JIT_RUNSTACK, JIT_RUNSTACK_BASE_OR_ALT(JIT_RUNSTACK), JIT_R2); - } else { - jit_subr_ul(JIT_RUNSTACK, JIT_RUNSTACK, JIT_R2); - } - CHECK_RUNSTACK_OVERFLOW(); - /* Copy args: */ - jit_ldxi_l(JIT_R1, JIT_R1, &((Scheme_Thread *)0x0)->ku.multiple.array); - refloop = jit_get_ip(); - ref3 = jit_blei_l(jit_forward(), JIT_R2, 0); - jit_subi_l(JIT_R2, JIT_R2, JIT_WORD_SIZE); - jit_ldxr_p(JIT_R0, JIT_R1, JIT_R2); - jit_stxr_p(JIT_R2, JIT_RUNSTACK, JIT_R0); - (void)jit_jmpi(refloop); - CHECK_LIMIT(); - mz_patch_branch(ref3); - /* clear array pointer and re-laod argc: */ - (void)mz_tl_ldi_p(JIT_R0, tl_scheme_current_thread); - (void)jit_movi_p(JIT_R1, NULL); - jit_stxi_l(&((Scheme_Thread *)0x0)->ku.multiple.array, JIT_R0, JIT_R1); - jit_ldxi_l(JIT_R0, JIT_R0, &((Scheme_Thread *)0x0)->ku.multiple.count); - CHECK_LIMIT(); - - /* Perform call --------------------- */ - /* Function is in V1, argc in R0, args on RUNSTACK */ - mz_patch_ucbranch(ref2); - __END_SHORT_JUMPS__(1); - - if (is_tail) { - if (!sjc.shared_tail_argc_code) { - sjc.shared_tail_argc_code = scheme_generate_shared_call(-1, jitter, 1, 0, 1, 0, 0, 0, 0); - } - mz_set_local_p(JIT_R0, JIT_LOCAL2); - (void)jit_jmpi(sjc.shared_tail_argc_code); - } else { - int mo = (multi_ok - ? (result_ignored ? SHARED_RESULT_IGNORED_CASE : SHARED_MULTI_OK_CASE) - : SHARED_SINGLE_VALUE_CASE); - void *code; - if (!sjc.shared_non_tail_argc_code[mo]) { - scheme_ensure_retry_available(jitter, multi_ok, result_ignored); - code = scheme_generate_shared_call(-2, jitter, multi_ok, result_ignored, 0, 0, 0, 0, 0); - sjc.shared_non_tail_argc_code[mo] = code; - } - code = sjc.shared_non_tail_argc_code[mo]; - (void)jit_calli(code); - /* non-tail code pops args off runstack for us */ - jitter->need_set_rs = 1; - mz_patch_ucbranch(ref5); if (target != JIT_R0) jit_movr_p(target, JIT_R0); + + if (for_branch) finish_branch(jitter, target, for_branch); + + return r; + } else { + GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *ref5, *refloop; + + scheme_generate_non_tail(v, jitter, 0, 1, 0); + CHECK_LIMIT(); + + /* If v is not known to produce a procedure, then check result: */ + if (!is_a_procedure(v, jitter)) { + mz_rs_sync(); + (void)jit_bmsi_l(sjc.bad_app_vals_target, JIT_R0, 0x1); + jit_ldxi_s(JIT_R1, JIT_R0, &((Scheme_Object *)0x0)->type); + (void)jit_blti_i(sjc.bad_app_vals_target, JIT_R1, scheme_prim_type); + (void)jit_bgti_i(sjc.bad_app_vals_target, JIT_R1, scheme_proc_chaperone_type); + CHECK_LIMIT(); + } + + mz_pushr_p(JIT_R0); + scheme_generate_non_tail(p, jitter, 1, 1, 0); + CHECK_LIMIT(); + + mz_popr_p(JIT_V1); + /* Function is in V1, argument(s) in R0 */ + + mz_rs_sync(); + + __START_SHORT_JUMPS__(1); + ref = jit_beqi_p(jit_forward(), JIT_R0, SCHEME_MULTIPLE_VALUES); + /* Single-value case: --------------- */ + /* We definitely have stack space for one argument, because we + just used it for the rator. */ + if (is_tail) { + mz_ld_runstack_base_alt(JIT_RUNSTACK); + jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK_BASE_OR_ALT(JIT_RUNSTACK), WORDS_TO_BYTES(1)); + } else { + jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); + } + CHECK_RUNSTACK_OVERFLOW(); + jit_str_p(JIT_RUNSTACK, JIT_R0); + jit_movi_l(JIT_R0, 1); + ref2 = jit_jmpi(jit_forward()); + CHECK_LIMIT(); + + /* Multiple-values case: ------------ */ + mz_patch_branch(ref); + /* Get new argc: */ + (void)mz_tl_ldi_p(JIT_R1, tl_scheme_current_thread); + jit_ldxi_l(JIT_R2, JIT_R1, &((Scheme_Thread *)0x0)->ku.multiple.count); + /* Enough room on runstack? */ + mz_tl_ldi_p(JIT_R0, tl_MZ_RUNSTACK_START); + if (is_tail) { + mz_ld_runstack_base_alt(JIT_R0); + jit_subr_ul(JIT_R0, JIT_RUNSTACK_BASE_OR_ALT(JIT_R0), JIT_R0); + } else { + jit_subr_ul(JIT_R0, JIT_RUNSTACK, JIT_R0); + } + CHECK_LIMIT(); + /* R0 is space left (in bytes), R2 is argc */ + jit_lshi_l(JIT_R2, JIT_R2, JIT_LOG_WORD_SIZE); + if (is_tail) { + int fpos, fstack; + fstack = scheme_mz_flostack_save(jitter, &fpos); + __END_SHORT_JUMPS__(1); + scheme_mz_flostack_restore(jitter, 0, 0, 1, 1); + (void)jit_bltr_ul(sjc.app_values_tail_slow_code, JIT_R0, JIT_R2); + __START_SHORT_JUMPS__(1); + scheme_mz_flostack_restore(jitter, fstack, fpos, 0, 1); + ref5 = 0; + } else { + GC_CAN_IGNORE jit_insn *refok; + refok = jit_bger_ul(jit_forward(), JIT_R0, JIT_R2); + __END_SHORT_JUMPS__(1); + if (multi_ok) { + (void)jit_calli(sjc.app_values_multi_slow_code); + } else { + (void)jit_calli(sjc.app_values_slow_code); + } + __START_SHORT_JUMPS__(1); + ref5 = jit_jmpi(jit_forward()); + mz_patch_branch(refok); + } + CHECK_LIMIT(); + if (is_tail) { + mz_ld_runstack_base_alt(JIT_RUNSTACK); + jit_subr_ul(JIT_RUNSTACK, JIT_RUNSTACK_BASE_OR_ALT(JIT_RUNSTACK), JIT_R2); + } else { + jit_subr_ul(JIT_RUNSTACK, JIT_RUNSTACK, JIT_R2); + } + CHECK_RUNSTACK_OVERFLOW(); + /* Copy args: */ + jit_ldxi_l(JIT_R1, JIT_R1, &((Scheme_Thread *)0x0)->ku.multiple.array); + refloop = jit_get_ip(); + ref3 = jit_blei_l(jit_forward(), JIT_R2, 0); + jit_subi_l(JIT_R2, JIT_R2, JIT_WORD_SIZE); + jit_ldxr_p(JIT_R0, JIT_R1, JIT_R2); + jit_stxr_p(JIT_R2, JIT_RUNSTACK, JIT_R0); + (void)jit_jmpi(refloop); + CHECK_LIMIT(); + mz_patch_branch(ref3); + /* clear array pointer and re-laod argc: */ + (void)mz_tl_ldi_p(JIT_R0, tl_scheme_current_thread); + (void)jit_movi_p(JIT_R1, NULL); + jit_stxi_l(&((Scheme_Thread *)0x0)->ku.multiple.array, JIT_R0, JIT_R1); + jit_ldxi_l(JIT_R0, JIT_R0, &((Scheme_Thread *)0x0)->ku.multiple.count); + CHECK_LIMIT(); + + /* Perform call --------------------- */ + /* Function is in V1, argc in R0, args on RUNSTACK */ + mz_patch_ucbranch(ref2); + __END_SHORT_JUMPS__(1); + + if (is_tail) { + if (!sjc.shared_tail_argc_code) { + sjc.shared_tail_argc_code = scheme_generate_shared_call(-1, jitter, 1, 0, 1, 0, 0, 0, 0); + } + mz_set_local_p(JIT_R0, JIT_LOCAL2); + (void)jit_jmpi(sjc.shared_tail_argc_code); + } else { + int mo = (multi_ok + ? (result_ignored ? SHARED_RESULT_IGNORED_CASE : SHARED_MULTI_OK_CASE) + : SHARED_SINGLE_VALUE_CASE); + void *code; + if (!sjc.shared_non_tail_argc_code[mo]) { + scheme_ensure_retry_available(jitter, multi_ok, result_ignored); + code = scheme_generate_shared_call(-2, jitter, multi_ok, result_ignored, 0, 0, 0, 0, 0); + sjc.shared_non_tail_argc_code[mo] = code; + } + code = sjc.shared_non_tail_argc_code[mo]; + (void)jit_calli(code); + /* non-tail code pops args off runstack for us */ + jitter->need_set_rs = 1; + mz_patch_ucbranch(ref5); + if (target != JIT_R0) + jit_movr_p(target, JIT_R0); + } + CHECK_LIMIT(); + + if (for_branch) finish_branch(jitter, target, for_branch); + + END_JIT_DATA(81); + + if (is_tail) + return 2; + return 1; } - CHECK_LIMIT(); - - if (for_branch) finish_branch(jitter, target, for_branch); - - END_JIT_DATA(81); - - if (is_tail) - return 2; - return 1; } break; case scheme_with_immed_mark_type: @@ -2642,7 +2712,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w return r; } - r = scheme_generate_app(app, NULL, app->num_args, jitter, is_tail, multi_ok, result_ignored, 0); + r = scheme_generate_app(app, NULL, app->num_args, app->num_args, jitter, is_tail, multi_ok, result_ignored, 0); CHECK_LIMIT(); if (target != JIT_R0) @@ -2670,7 +2740,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w args[0] = app->rator; args[1] = app->rand; - r = scheme_generate_app(NULL, args, 1, jitter, is_tail, multi_ok, result_ignored, 0); + r = scheme_generate_app(NULL, args, 1, 1, jitter, is_tail, multi_ok, result_ignored, 0); CHECK_LIMIT(); if (target != JIT_R0) @@ -2721,7 +2791,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w args[1] = app->rand1; args[2] = app->rand2; - r = scheme_generate_app(NULL, args, 2, jitter, is_tail, multi_ok, result_ignored, 0); + r = scheme_generate_app(NULL, args, 2, 2, jitter, is_tail, multi_ok, result_ignored, 0); CHECK_LIMIT(); if (target != JIT_R0) diff --git a/racket/src/racket/src/jit.h b/racket/src/racket/src/jit.h index 539d550d46..70ccaf1ea1 100644 --- a/racket/src/racket/src/jit.h +++ b/racket/src/racket/src/jit.h @@ -203,12 +203,7 @@ END_XFORM_ARITH; #include "jitfpu.h" -#if 0 -static void assert_failure(int where) { printf("JIT assert failed %d\n", where); } -#define JIT_ASSERT(v) if (!(v)) assert_failure(__LINE__); -#else -#define JIT_ASSERT(v) /* */ -#endif +#define JIT_ASSERT(v) MZ_ASSERT(v) /* Tracking statistics: */ #if 0 @@ -1364,6 +1359,8 @@ long_double *scheme_mz_retain_long_double(mz_jit_state *jitter, long_double d); int scheme_mz_remap_it(mz_jit_state *jitter, int i); void scheme_mz_pushr_p_it(mz_jit_state *jitter, int reg); void scheme_mz_popr_p_it(mz_jit_state *jitter, int reg, int discard); +void scheme_extra_pushed(mz_jit_state *jitter, int n); +void scheme_extra_popped(mz_jit_state *jitter, int n); void scheme_mz_need_space(mz_jit_state *jitter, int need_extra); int scheme_stack_safety(mz_jit_state *jitter, int cnt, int offset); #ifdef USE_FLONUM_UNBOXING @@ -1480,7 +1477,7 @@ typedef struct jit_direct_arg jit_direct_arg; void *scheme_generate_shared_call(int num_rands, mz_jit_state *old_jitter, int multi_ok, int result_ignored, int is_tail, int direct_prim, int direct_native, int nontail_self, int unboxed_args); void scheme_ensure_retry_available(mz_jit_state *jitter, int multi_ok, int result_ignored); -int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_rands, +int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_rands, int num_pushes, mz_jit_state *jitter, int is_tail, int multi_ok, int ignored_result, int no_call); int scheme_generate_tail_call(mz_jit_state *jitter, int num_rands, int direct_native, int need_set_rs, diff --git a/racket/src/racket/src/jitarith.c b/racket/src/racket/src/jitarith.c index 4a81996ca9..a84b039f0d 100644 --- a/racket/src/racket/src/jitarith.c +++ b/racket/src/racket/src/jitarith.c @@ -2241,7 +2241,7 @@ int scheme_generate_nary_arith(mz_jit_state *jitter, Scheme_App_Rec *app, } if (stack_c) - scheme_generate_app(app, alt_args, stack_c, jitter, 0, 0, 0, 2); + scheme_generate_app(app, alt_args, stack_c, stack_c, jitter, 0, 0, 0, 2); CHECK_LIMIT(); mz_rs_sync(); diff --git a/racket/src/racket/src/jitcall.c b/racket/src/racket/src/jitcall.c index 73f058aaaf..d44ec7513e 100644 --- a/racket/src/racket/src/jitcall.c +++ b/racket/src/racket/src/jitcall.c @@ -1737,7 +1737,7 @@ static int generate_call_path_with_unboxes(mz_jit_state *jitter, int direct_flos } #endif -int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_rands, +int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_rands, int num_pushes, mz_jit_state *jitter, int is_tail, int multi_ok, int result_ignored, int no_call) /* de-sync'd ok @@ -1762,7 +1762,7 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ rator = (alt_rands ? alt_rands[0] : app->args[0]); - rator = scheme_specialize_to_constant(rator, jitter, num_rands); + rator = scheme_specialize_to_constant(rator, jitter, num_pushes); if (no_call == 2) { direct_prim = 1; @@ -1785,6 +1785,13 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ } else { Scheme_Type t; t = SCHEME_TYPE(rator); + + if (t == scheme_case_closure_type) { + /* Turn it into a JITted empty case closure: */ + rator = scheme_unclose_case_lambda(rator, 1); + t = SCHEME_TYPE(rator); + } + if ((t == scheme_local_type) && scheme_ok_to_delay_local(rator)) { /* We can re-order evaluation of the rator. */ reorder_ok = 1; @@ -1792,7 +1799,7 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ /* Call to known native, or even known self? */ { int pos, flags; - pos = SCHEME_LOCAL_POS(rator) - num_rands; + pos = SCHEME_LOCAL_POS(rator) - num_pushes; if (scheme_mz_is_closure(jitter, pos, num_rands, &flags)) { direct_native = 1; if ((pos == jitter->self_pos) @@ -1922,7 +1929,7 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ locations that will be filled with argument values; that is, check how many arguments are already in place for the call. */ - mz_runstack_skipped(jitter, num_rands); + mz_runstack_skipped(jitter, num_pushes); for (i = 0; i < num_rands; i++) { v = (alt_rands ? alt_rands[i+1] : app->args[i+1]); if (SAME_TYPE(SCHEME_TYPE(v), scheme_local_type) @@ -1936,11 +1943,14 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ } else break; } - mz_runstack_unskipped(jitter, num_rands); + mz_runstack_unskipped(jitter, num_pushes); if (args_already_in_place) { direct_native = 2; - mz_runstack_skipped(jitter, args_already_in_place); + if (num_pushes) + mz_runstack_skipped(jitter, args_already_in_place); num_rands -= args_already_in_place; + if (num_pushes) + num_pushes -= args_already_in_place; } LOG_IT((" [args in place: %d]\n", args_already_in_place)); } @@ -1953,7 +1963,7 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ if (num_rands) { if (inline_direct_args) { - mz_runstack_skipped(jitter, num_rands); + mz_runstack_skipped(jitter, num_pushes); } else if (!direct_prim || (num_rands > 1) || (no_call == 2)) { int skip_end = 0; if (direct_self && is_tail && !no_call && (num_rands > 0)) { @@ -1963,13 +1973,17 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ if (num_rands - skip_end > 0) { mz_rs_dec(num_rands-skip_end); CHECK_RUNSTACK_OVERFLOW(); - mz_runstack_pushed(jitter, num_rands-skip_end); + if (num_pushes) + mz_runstack_pushed(jitter, num_pushes-skip_end); + else + scheme_extra_pushed(jitter, num_rands-skip_end); } need_safety = num_rands-skip_end; - if (skip_end) + if (skip_end && num_pushes) mz_runstack_skipped(jitter, skip_end); } else { - mz_runstack_skipped(jitter, 1); + if (num_pushes) + mz_runstack_skipped(jitter, 1); } } @@ -2130,7 +2144,8 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ if (!no_call) { (void)jit_movi_p(JIT_V1, ((Scheme_Primitive_Proc *)rator)->prim_val); if (num_rands == 1) { - mz_runstack_unskipped(jitter, 1); + if (num_pushes) + mz_runstack_unskipped(jitter, 1); } else { mz_rs_sync(); JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); diff --git a/racket/src/racket/src/jitinline.c b/racket/src/racket/src/jitinline.c index 080edec928..616ac701ca 100644 --- a/racket/src/racket/src/jitinline.c +++ b/racket/src/racket/src/jitinline.c @@ -401,7 +401,7 @@ static int generate_inlined_struct_op(int kind, mz_jit_state *jitter, args[0] = rator; args[1] = rand; args[2] = rand2; - scheme_generate_app(NULL, args, 2, jitter, 0, 0, 0, 1); /* sync'd below */ + scheme_generate_app(NULL, args, 2, 2, jitter, 0, 0, 0, 1); /* sync'd below */ CHECK_LIMIT(); jit_movr_p(JIT_R0, JIT_V1); mz_rs_ldr(JIT_R1); @@ -623,7 +623,7 @@ static int generate_inlined_nary_struct_op(int kind, mz_jit_state *jitter, /* de-sync'd ok; for branch, sync'd before */ { /* generate code to evaluate the arguments */ - scheme_generate_app(app, NULL, app->num_args, jitter, 0, 0, 0, 1); + scheme_generate_app(app, NULL, app->num_args, app->num_args, jitter, 0, 0, 0, 1); CHECK_LIMIT(); mz_rs_sync(); @@ -3876,7 +3876,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i args[1] = app->rand1; args[2] = app->rand2; - scheme_generate_app(NULL, args, 2, jitter, 0, 0, 0, 2); + scheme_generate_app(NULL, args, 2, 2, jitter, 0, 0, 0, 2); CHECK_LIMIT(); mz_rs_sync(); @@ -4014,7 +4014,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int } /* generate code to evaluate the arguments */ - scheme_generate_app(app, NULL, 3, jitter, 0, 0, 0, 2); + scheme_generate_app(app, NULL, 3, 3, jitter, 0, 0, 0, 2); CHECK_LIMIT(); mz_rs_sync(); @@ -4465,7 +4465,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int } else { got_two = 1; mz_runstack_skipped(jitter, 1); - scheme_generate_app(app, NULL, 2, jitter, 0, 0, 0, 2); + scheme_generate_app(app, NULL, 2, 2, jitter, 0, 0, 0, 2); CHECK_LIMIT(); } @@ -4531,7 +4531,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int star = IS_NAMED_PRIM(rator, "list*"); if (c) - scheme_generate_app(app, NULL, c, jitter, 0, 0, 0, 2); + scheme_generate_app(app, NULL, c, c, jitter, 0, 0, 0, 2); CHECK_LIMIT(); mz_rs_sync(); @@ -4592,7 +4592,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int if (!multi_ok) return 0; if (c) { - scheme_generate_app(app, NULL, c, jitter, 0, 0, 0, 2); + scheme_generate_app(app, NULL, c, c, jitter, 0, 0, 0, 2); CHECK_LIMIT(); mz_rs_sync(); @@ -4629,7 +4629,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int } else if (IS_NAMED_PRIM(rator, "max")) { return scheme_generate_nary_arith(jitter, app, ARITH_MAX, 0, NULL, 1, dest); } else if (IS_NAMED_PRIM(rator, "checked-procedure-check-and-extract")) { - scheme_generate_app(app, NULL, 5, jitter, 0, 0, 0, 2); /* sync'd below */ + scheme_generate_app(app, NULL, 5, 5, jitter, 0, 0, 0, 2); /* sync'd below */ CHECK_LIMIT(); mz_rs_sync(); @@ -4652,7 +4652,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int is_ref = IS_NAMED_PRIM(rator, "ptr-ref"); abs_offset = (n == (is_ref ? 4 : 5)); - scheme_generate_app(app, NULL, n, jitter, 0, 0, 0, 2); /* sync'd below */ + scheme_generate_app(app, NULL, n, n, jitter, 0, 0, 0, 2); /* sync'd below */ CHECK_LIMIT(); mz_rs_sync(); @@ -5004,7 +5004,7 @@ static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator, } else { c = app->num_args; if (c) - scheme_generate_app(app, NULL, c, jitter, 0, 0, 0, 2); /* sync'd below */ + scheme_generate_app(app, NULL, c, c, jitter, 0, 0, 0, 2); /* sync'd below */ } CHECK_LIMIT(); diff --git a/racket/src/racket/src/jitstate.c b/racket/src/racket/src/jitstate.c index 575cce824e..d6db88b92f 100644 --- a/racket/src/racket/src/jitstate.c +++ b/racket/src/racket/src/jitstate.c @@ -488,12 +488,11 @@ static void new_mapping(mz_jit_state *jitter) jitter->mappings[jitter->num_mappings] = 0; } -void scheme_mz_pushr_p_it(mz_jit_state *jitter, int reg) -/* de-sync's rs */ +void scheme_extra_pushed(mz_jit_state *jitter, int n) { int v; - jitter->extra_pushed++; + jitter->extra_pushed += n; if (jitter->extra_pushed > jitter->max_extra_pushed) jitter->max_extra_pushed = jitter->extra_pushed; @@ -503,8 +502,14 @@ void scheme_mz_pushr_p_it(mz_jit_state *jitter, int reg) new_mapping(jitter); } v = (jitter->mappings[jitter->num_mappings]) >> 2; - v++; + v += n; jitter->mappings[jitter->num_mappings] = ((v << 2) | 0x1); +} + +void scheme_mz_pushr_p_it(mz_jit_state *jitter, int reg) +/* de-sync's rs */ +{ + scheme_extra_pushed(jitter, 1); mz_rs_dec(1); CHECK_RUNSTACK_OVERFLOW_NOCL(); @@ -513,21 +518,28 @@ void scheme_mz_pushr_p_it(mz_jit_state *jitter, int reg) jitter->need_set_rs = 1; } -void scheme_mz_popr_p_it(mz_jit_state *jitter, int reg, int discard) +void scheme_extra_popped(mz_jit_state *jitter, int n) /* de-sync's rs */ { int v; - jitter->extra_pushed--; + jitter->extra_pushed -= n; JIT_ASSERT(jitter->mappings[jitter->num_mappings] & 0x1); JIT_ASSERT(!(jitter->mappings[jitter->num_mappings] & 0x2)); v = jitter->mappings[jitter->num_mappings] >> 2; - v--; + v -= n; + JIT_ASSERT(v >= 0); if (!v) --jitter->num_mappings; else jitter->mappings[jitter->num_mappings] = ((v << 2) | 0x1); +} + +void scheme_mz_popr_p_it(mz_jit_state *jitter, int reg, int discard) +/* de-sync's rs */ +{ + scheme_extra_popped(jitter, 1); if (!discard) mz_rs_ldr(reg); From f0d09dbef123924f6533db5b94507d058720e53c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 25 Dec 2015 07:14:40 -0600 Subject: [PATCH 234/369] make JIT recognize literal struct predicatates, etc. Mka the closure specializer handle literal struct operations (as opposed to just references to struct operations). --- racket/src/racket/src/jitinline.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/racket/src/racket/src/jitinline.c b/racket/src/racket/src/jitinline.c index 616ac701ca..32743f1cf9 100644 --- a/racket/src/racket/src/jitinline.c +++ b/racket/src/racket/src/jitinline.c @@ -178,7 +178,8 @@ static int inlineable_struct_prim(Scheme_Object *o, mz_jit_state *jitter, int ex return check_val_struct_prim(p, arity); } } - return 0; + + return check_val_struct_prim(o, 1); } int scheme_inlined_unary_prim(Scheme_Object *o, Scheme_Object *_app, mz_jit_state *jitter) @@ -371,6 +372,9 @@ static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app static Scheme_Object *extract_struct_constant(mz_jit_state *jitter, Scheme_Object *rator) { + if (SCHEME_PROCP(rator)) + return rator; + if (SAME_TYPE(SCHEME_TYPE(rator), scheme_toplevel_type) && (SCHEME_TOPLEVEL_FLAGS(rator) & SCHEME_TOPLEVEL_FLAGS_MASK) >= SCHEME_TOPLEVEL_CONST) { rator = scheme_extract_global(rator, jitter->nc, 0); From 0840fcd6c84aca8e635669e25891452cd9b49450 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 25 Dec 2015 08:04:22 -0600 Subject: [PATCH 235/369] JIT: avoid assertion failures due to a full buffer --- racket/src/racket/src/jitstate.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/racket/src/racket/src/jitstate.c b/racket/src/racket/src/jitstate.c index d6db88b92f..09e7a14fed 100644 --- a/racket/src/racket/src/jitstate.c +++ b/racket/src/racket/src/jitstate.c @@ -523,6 +523,8 @@ void scheme_extra_popped(mz_jit_state *jitter, int n) { int v; + if (PAST_LIMIT()) return; + jitter->extra_pushed -= n; JIT_ASSERT(jitter->mappings[jitter->num_mappings] & 0x1); @@ -559,6 +561,7 @@ void scheme_mz_runstack_skipped(mz_jit_state *jitter, int n) int v; if (!n) return; + if (PAST_LIMIT()) return; if (!(jitter->mappings[jitter->num_mappings] & 0x1) || (jitter->mappings[jitter->num_mappings] & 0x2) @@ -577,6 +580,7 @@ void scheme_mz_runstack_unskipped(mz_jit_state *jitter, int n) int v; if (!n) return; + if (PAST_LIMIT()) return; JIT_ASSERT(jitter->mappings[jitter->num_mappings] & 0x1); JIT_ASSERT(!(jitter->mappings[jitter->num_mappings] & 0x2)); @@ -633,6 +637,9 @@ void scheme_mz_runstack_flonum_pushed(mz_jit_state *jitter, int pos) void scheme_mz_runstack_popped(mz_jit_state *jitter, int n) { int v; + + if (PAST_LIMIT()) return; + jitter->depth -= n; jitter->self_pos -= n; From 7708b2056a9b1a90108720285ac2f19cbc302a63 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Fri, 25 Dec 2015 14:12:36 -0600 Subject: [PATCH 236/369] use specialize-procedure on predicate portion or or/c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This seems to give about a 10% speedup on this program: #lang racket/base (require racket/contract/base) (define f (contract (-> (or/c number? symbol?) any) (λ (x) 0) 'pos 'neg)) (time (for ([_ (in-range 1000000)]) (f 'x) (f 'x) (f 'x) (f 'x))) --- racket/collects/racket/contract/private/orc.rkt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/racket/collects/racket/contract/private/orc.rkt b/racket/collects/racket/contract/private/orc.rkt index dcb8bfc566..b8455f226c 100644 --- a/racket/collects/racket/contract/private/orc.rkt +++ b/racket/collects/racket/contract/private/orc.rkt @@ -70,7 +70,8 @@ [(null? rst) fst-pred] [else (let ([r (loop (car rst) (cdr rst))]) - (λ (x) (or (fst-pred x) (r x))))])))])) + (procedure-specialize + (λ (x) (or (fst-pred x) (r x)))))])))])) (define (single-or/c-late-neg-projection ctc) (define c-proj (get/build-late-neg-projection (single-or/c-ho-ctc ctc))) From badf2bd19e4afd49a8b66311f51f7f83ce14d2a1 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 22 Dec 2015 16:26:17 -0600 Subject: [PATCH 237/369] audit requires of files that require misc.rkt in racket/contract --- racket/collects/racket/contract/private/arr-i-parse.rkt | 1 - .../collects/racket/contract/private/arrow-higher-order.rkt | 2 -- racket/collects/racket/contract/private/arrow-val-first.rkt | 1 - racket/collects/racket/contract/private/arrow.rkt | 1 - racket/collects/racket/contract/private/base.rkt | 5 +---- racket/collects/racket/contract/private/box.rkt | 3 +-- racket/collects/racket/contract/private/ds.rkt | 3 +-- racket/collects/racket/contract/private/hash.rkt | 3 +-- racket/collects/racket/contract/private/opt.rkt | 1 - racket/collects/racket/contract/private/opters.rkt | 1 - racket/collects/racket/contract/private/parametric.rkt | 1 - racket/collects/racket/contract/private/provide.rkt | 4 ---- racket/collects/racket/contract/private/struct-prop.rkt | 3 +-- 13 files changed, 5 insertions(+), 24 deletions(-) diff --git a/racket/collects/racket/contract/private/arr-i-parse.rkt b/racket/collects/racket/contract/private/arr-i-parse.rkt index ab472d387c..ebbd1be11d 100644 --- a/racket/collects/racket/contract/private/arr-i-parse.rkt +++ b/racket/collects/racket/contract/private/arr-i-parse.rkt @@ -7,7 +7,6 @@ [module-identifier-mapping-get free-identifier-mapping-get] [module-identifier-mapping-put! free-identifier-mapping-put!] [module-identifier-mapping-for-each free-identifier-mapping-for-each]) - "application-arity-checking.rkt" "arr-util.rkt" (for-template racket/base "misc.rkt")) diff --git a/racket/collects/racket/contract/private/arrow-higher-order.rkt b/racket/collects/racket/contract/private/arrow-higher-order.rkt index 071b0667c9..7e7ac58481 100644 --- a/racket/collects/racket/contract/private/arrow-higher-order.rkt +++ b/racket/collects/racket/contract/private/arrow-higher-order.rkt @@ -8,8 +8,6 @@ "misc.rkt" "prop.rkt" "guts.rkt" - "generate.rkt" - racket/stxparam (prefix-in arrow: "arrow.rkt")) (provide (for-syntax build-chaperone-constructor/real) diff --git a/racket/collects/racket/contract/private/arrow-val-first.rkt b/racket/collects/racket/contract/private/arrow-val-first.rkt index 8cd4477632..a5ae6a5fe3 100644 --- a/racket/collects/racket/contract/private/arrow-val-first.rkt +++ b/racket/collects/racket/contract/private/arrow-val-first.rkt @@ -3,7 +3,6 @@ "application-arity-checking.rkt" "arr-util.rkt") "kwd-info-struct.rkt" - "arity-checking.rkt" "blame.rkt" "misc.rkt" "prop.rkt" diff --git a/racket/collects/racket/contract/private/arrow.rkt b/racket/collects/racket/contract/private/arrow.rkt index 38215e750f..c953a56775 100644 --- a/racket/collects/racket/contract/private/arrow.rkt +++ b/racket/collects/racket/contract/private/arrow.rkt @@ -4,7 +4,6 @@ "blame.rkt" "prop.rkt" "misc.rkt" - "generate.rkt" racket/stxparam racket/private/performance-hint) (require (for-syntax racket/base) diff --git a/racket/collects/racket/contract/private/base.rkt b/racket/collects/racket/contract/private/base.rkt index f9e8242b21..e2b49f0025 100644 --- a/racket/collects/racket/contract/private/base.rkt +++ b/racket/collects/racket/contract/private/base.rkt @@ -13,10 +13,7 @@ "guts.rkt" "blame.rkt" "prop.rkt" - "arrow.rkt" - "misc.rkt" - "generate.rkt" - ) + "generate.rkt") (begin-for-syntax (define lifted-key (gensym 'contract:lifted)) diff --git a/racket/collects/racket/contract/private/box.rkt b/racket/collects/racket/contract/private/box.rkt index d0461ca79c..0abccd0365 100644 --- a/racket/collects/racket/contract/private/box.rkt +++ b/racket/collects/racket/contract/private/box.rkt @@ -3,8 +3,7 @@ (require (for-syntax racket/base) "prop.rkt" "blame.rkt" - "guts.rkt" - "misc.rkt") + "guts.rkt") (provide box-immutable/c (rename-out [wrap-box/c box/c])) diff --git a/racket/collects/racket/contract/private/ds.rkt b/racket/collects/racket/contract/private/ds.rkt index 246fd1de5f..4341ec8bb6 100644 --- a/racket/collects/racket/contract/private/ds.rkt +++ b/racket/collects/racket/contract/private/ds.rkt @@ -20,8 +20,7 @@ it around flattened out. (require "guts.rkt" "prop.rkt" "blame.rkt" - "opt.rkt" - "misc.rkt") + "opt.rkt") (require (for-syntax racket/base) (for-syntax "ds-helpers.rkt") (for-syntax "helpers.rkt") diff --git a/racket/collects/racket/contract/private/hash.rkt b/racket/collects/racket/contract/private/hash.rkt index 3f3369fb9d..deaeb3578d 100644 --- a/racket/collects/racket/contract/private/hash.rkt +++ b/racket/collects/racket/contract/private/hash.rkt @@ -4,8 +4,7 @@ syntax/location "guts.rkt" "blame.rkt" - "prop.rkt" - "misc.rkt") + "prop.rkt") (provide (rename-out [wrap-hash/c hash/c]) hash/dc) diff --git a/racket/collects/racket/contract/private/opt.rkt b/racket/collects/racket/contract/private/opt.rkt index 4743434a71..f3f44d5e98 100644 --- a/racket/collects/racket/contract/private/opt.rkt +++ b/racket/collects/racket/contract/private/opt.rkt @@ -1,6 +1,5 @@ #lang racket/base (require "prop.rkt" - "misc.rkt" "blame.rkt" "guts.rkt" "base.rkt" diff --git a/racket/collects/racket/contract/private/opters.rkt b/racket/collects/racket/contract/private/opters.rkt index b1ef4d8dbe..d1e0104929 100644 --- a/racket/collects/racket/contract/private/opters.rkt +++ b/racket/collects/racket/contract/private/opters.rkt @@ -4,7 +4,6 @@ "guts.rkt" "arrow.rkt" "blame.rkt" - "misc.rkt" "arrow.rkt" "arrow-val-first.rkt" "orc.rkt" diff --git a/racket/collects/racket/contract/private/parametric.rkt b/racket/collects/racket/contract/private/parametric.rkt index 727ae8e344..34ac6bea4f 100644 --- a/racket/collects/racket/contract/private/parametric.rkt +++ b/racket/collects/racket/contract/private/parametric.rkt @@ -1,7 +1,6 @@ #lang racket/base (require "prop.rkt" "blame.rkt" - "misc.rkt" "guts.rkt" (for-syntax "arr-util.rkt" racket/base)) (provide parametric->/c) diff --git a/racket/collects/racket/contract/private/provide.rkt b/racket/collects/racket/contract/private/provide.rkt index 12055dcadc..f3f699fb61 100644 --- a/racket/collects/racket/contract/private/provide.rkt +++ b/racket/collects/racket/contract/private/provide.rkt @@ -26,14 +26,10 @@ [make-module-identifier-mapping make-free-identifier-mapping] [module-identifier-mapping-get free-identifier-mapping-get] [module-identifier-mapping-put! free-identifier-mapping-put!])) - "arrow.rkt" "arrow-val-first.rkt" "base.rkt" "guts.rkt" - "misc.rkt" "exists.rkt" - "opt.rkt" - "prop.rkt" "blame.rkt" syntax/location syntax/srcloc) diff --git a/racket/collects/racket/contract/private/struct-prop.rkt b/racket/collects/racket/contract/private/struct-prop.rkt index 10edb1961e..b468aa215f 100644 --- a/racket/collects/racket/contract/private/struct-prop.rkt +++ b/racket/collects/racket/contract/private/struct-prop.rkt @@ -1,8 +1,7 @@ #lang racket/base (require "guts.rkt" "blame.rkt" - "prop.rkt" - "misc.rkt") + "prop.rkt") (provide (rename-out [struct-type-property/c* struct-type-property/c])) (define (get-stpc-late-neg-proj stpc) From c9d192f09bbe4a2d78d27975fbaa9d6891cdba54 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 22 Dec 2015 20:02:27 -0600 Subject: [PATCH 238/369] make more explicit that `define-custom-set-types` produces hash sets. --- pkgs/racket-doc/scribblings/reference/sets.scrbl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/sets.scrbl b/pkgs/racket-doc/scribblings/reference/sets.scrbl index f14c27b0ab..b6e5a99765 100644 --- a/pkgs/racket-doc/scribblings/reference/sets.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sets.scrbl @@ -709,7 +709,7 @@ Supported for any @racket[st] that @supp{supports} @racket[set->stream]. (code:line hash1-expr) (code:line hash1-expr hash2-expr)])]{ -Creates a new set type based on the given comparison @racket[comparison-expr], +Creates a new hash set type based on the given comparison @racket[comparison-expr], hash functions @racket[hash1-expr] and @racket[hash2-expr], and element predicate @racket[predicate-expr]; the interfaces for these functions are the same as in @racket[make-custom-set-types]. The new set type has three @@ -749,6 +749,8 @@ initial elements. (make-mutable-string-set '("apple" "banana"))) (generic-set? imm) (generic-set? mut) +(set? imm) +(generic-set? imm) (string-set? imm) (string-set? mut) (immutable-string-set? imm) From f0f85549ce069da47e6498b6e6af3ea719f9fc2a Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 22 Dec 2015 21:47:26 -0600 Subject: [PATCH 239/369] add impersonate-hash-set and chaperone-hash-set --- .../scribblings/reference/sets.scrbl | 53 ++++++++ pkgs/racket-test-core/tests/racket/set.rktl | 36 +++++ racket/collects/racket/private/set-types.rkt | 124 +++++++++++++++++- 3 files changed, 212 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/sets.scrbl b/pkgs/racket-doc/scribblings/reference/sets.scrbl index b6e5a99765..8f8aefc29c 100644 --- a/pkgs/racket-doc/scribblings/reference/sets.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sets.scrbl @@ -695,6 +695,59 @@ Supported for any @racket[st] that @supp{supports} @racket[set->stream]. } +@defproc[(impersonate-hash-set [st mutable-set?] + [ref-proc (-> set? any/c any/c)] + [add-proc (-> set? any/c any/c)] + [remove-proc (-> set? any/c any/c)] + [clear-proc (or/c #f (-> set? any))] + [prop impersonator-property?] + [prop-val any/c] ... ...) + (and/c set? impersonator?)]{ + Impersonates @racket[set], redirecting via the given procedures. + + The @racket[ref-proc] procedure + is called whenever an element is extracted from @racket[st]. Its first argument + is the set and its second argument is the element being extracted. The + result of @racket[ref-proc] is used in place of the extracted argument. + + The @racket[add-proc] procedure is called whenever an element is added to @racket[st]. + Its first argument is the set and its second argument is the element being + added. The result of the procedure is the one actually added to the set. + + The @racket[remove-proc] procedure is called whenever an element is removed + from @racket[st]. Its first argument is the set and its second argument is the + element being removed. The result of the procedure is the element that actually + gets removed from the set. + + If @racket[clear-proc] is not @racket[#f], it must accept @racket[set] as + an argument and is result is ignored. The fact that @racket[clear-proc] + returns (as opposed to raising an exception or otherwise escaping) grants the + capability to remove all elements from @racket[st]. + If @racket[clear-proc] is @racket[#f], then + @racket[set-clear] or @racket[set-clear!] on the impersonated set + is implemented using @racket[custom-set-first], @racket[custom-set-rest] + and @racket[set-remove] or @racket[set-remove!]. + + Pairs of @racket[prop] and @racket[prop-val] (the number of arguments to + @racket[impersonate-hash-set] must be odd) add @tech{impersonator properties} or + override impersonator property values of @racket[st]. +} + +@defproc[(chaperone-hash-set [st (or/c set? mutable-set?)] + [ref-proc (-> set? any/c any/c)] + [add-proc (-> set? any/c any/c)] + [remove-proc (-> set? any/c any/c)] + [clear-proc (or/c #f (-> set? any))] + [prop impersonator-property?] + [prop-val any/c] ... ...) + (and/c set? chaperone?)]{ + Chaperones @racket[set]. Like @racket[impersonate-hash-set] but with + the constraints that the results of the @racket[ref-proc], + @racket[add-proc], and @racket[remove-proc] must be + @racket[chaperone-of?] their second arguments. Also, the input + may be an @racket[immutable?] set. +} + @section{Custom Hash Sets} @defform[(define-custom-set-types name diff --git a/pkgs/racket-test-core/tests/racket/set.rktl b/pkgs/racket-test-core/tests/racket/set.rktl index 50f9525b02..3322a3d996 100644 --- a/pkgs/racket-test-core/tests/racket/set.rktl +++ b/pkgs/racket-test-core/tests/racket/set.rktl @@ -596,4 +596,40 @@ (test/blame-pos (set-first (app-ctc (set/c string?) (set 1)))) (test/blame-neg (set-add! (app-ctc (set/c string? #:kind 'mutable) (mutable-set)) 1)) +(let ([s (set (list 1 2))]) + (test #f eq? + (set-first (chaperone-hash-set s + (λ (s l) (apply list l)) + (λ (s l) l) + (λ (s l) l))) + (set-first s))) +(let ([s (set (list 1 2))]) + (test #t eq? + (set-first (chaperone-hash-set s + (λ (s l) l) + (λ (s l) l) + (λ (s l) l))) + (set-first s))) +(let ([l (list 1 2)]) + (test #f eq? + (set-first (set-add (chaperone-hash-set (set) + (λ (s l) l) + (λ (s l) (apply list l)) + (λ (s l) l)) + l)) + l)) +(let ([l (list 1 2)]) + (test #t eq? + (set-first (set-add (chaperone-hash-set (set) + (λ (s l) l) + (λ (s l) l) + (λ (s l) l)) + l)) + l)) +(test #t even? + (set-first (impersonate-hash-set (mutable-set 1 3 5) + (λ (s e) (+ e 1)) + (λ (s l) l) + (λ (s l) l)))) + (report-errs) diff --git a/racket/collects/racket/private/set-types.rkt b/racket/collects/racket/private/set-types.rkt index dbb587617f..7192549c45 100644 --- a/racket/collects/racket/private/set-types.rkt +++ b/racket/collects/racket/private/set-types.rkt @@ -28,7 +28,10 @@ make-custom-set-types make-custom-set make-weak-custom-set - make-mutable-custom-set) + make-mutable-custom-set + + chaperone-hash-set + impersonate-hash-set) (define (custom-set-empty? s) (dprintf "custom-set-empty?\n") @@ -335,6 +338,125 @@ [(hash-weak? table) (weak-custom-set (custom-set-spec s) table)] [else (mutable-custom-set (custom-set-spec s) table)])) +(define (chaperone-hash-set s + ref-proc + add-proc + remove-proc + . + clear-proc+props) + (define-values (clear-proc args) + (check-chap/imp-args #f + s + ref-proc + add-proc + remove-proc + clear-proc+props)) + (define (check-it who original new) + (unless (chaperone-of? new original) + (error 'chaperone-hash-set + "~s did not return a chaperone of ~e, got ~e" + who original new)) + new) + (update-custom-set-table + s + (apply + chaperone-hash + (custom-set-table s) + (λ (hash key) (values (check-it 'ref-proc key (ref-proc (update-custom-set-table s hash) key)) + (λ (hash key val) val))) + (λ (hash key val) (values (check-it 'add-proc key (add-proc (update-custom-set-table s hash) key)) + val)) + (λ (hash key) (check-it 'remove-proc key (remove-proc (update-custom-set-table s hash) key))) + (λ (hash key) (check-it 'ref-proc key (ref-proc (update-custom-set-table s hash) key))) + (and clear-proc (λ (hash) (clear-proc (update-custom-set-table s hash)))) + args))) + +(define (impersonate-hash-set s + ref-proc + add-proc + remove-proc + . + clear-proc+props) + (define-values (clear-proc args) + (check-chap/imp-args #t + s + ref-proc + add-proc + remove-proc + clear-proc+props)) + (update-custom-set-table + s + (apply + impersonate-hash + (custom-set-table s) + (λ (hash key) (values (ref-proc (update-custom-set-table s hash) key) (λ (hash key val) val))) + (λ (hash key val) (values (add-proc (update-custom-set-table s hash) key) val)) + (λ (hash key) (remove-proc (update-custom-set-table s hash) key)) + (λ (hash key) (ref-proc (update-custom-set-table s hash) key)) + (and clear-proc (λ (hash) (clear-proc (update-custom-set-table s hash)))) + args))) + +(define (check-chap/imp-args impersonate? + s + ref-proc + add-proc + remove-proc + clear-proc+props) + (define who (if impersonate? 'impersonate-hash-set 'chaperone-hash-set)) + (unless (if impersonate? (set-mutable? s) (or (set? s) (set-mutable? s))) + (apply raise-argument-error + who + (if impersonate? "set-mutable?" (format "~s" '(or/c set? set-mutable?))) + 0 s ref-proc add-proc clear-proc+props)) + (unless (and (procedure? ref-proc) + (procedure-arity-includes? ref-proc 2)) + (apply raise-argument-error + who + "(procedure-arity-includes/c 2)" + 1 s ref-proc add-proc clear-proc+props)) + (unless (and (procedure? add-proc) + (procedure-arity-includes? add-proc 2)) + (apply raise-argument-error + who + "(procedure-arity-includes/c 2)" + 2 s ref-proc add-proc clear-proc+props)) + (unless (and (procedure? remove-proc) + (procedure-arity-includes? remove-proc 2)) + (apply raise-argument-error + who + "(procedure-arity-includes/c 2)" + 3 s ref-proc add-proc clear-proc+props)) + (unless (null? clear-proc+props) + (unless (or (not (car clear-proc+props)) + (and (procedure? (car clear-proc+props)) + (procedure-arity-includes? (car clear-proc+props) 1)) + (impersonator-property? (car clear-proc+props))) + (apply raise-argument-error + who + (format "~s" `(or/c #f + (procedure-arity-includes/c 1) + impersonator-property?)) + 4 + s ref-proc add-proc clear-proc+props))) + (define-values (supplied-clear-proc? clear-proc args) + (cond + [(null? clear-proc+props) (values #f #f '())] + [(impersonator-property? (car clear-proc+props)) (values #f #f clear-proc+props)] + [else + (values #t + (car clear-proc+props) + (cdr clear-proc+props))])) + (for ([ele (in-list args)] + [i (in-naturals)] + #:when (even? i)) + (unless (impersonator-property? ele) + (apply raise-argument-error + who + "impersonator-property?" + (+ i (if supplied-clear-proc? 1 0) 4) + s ref-proc add-proc clear-proc+props))) + (values clear-proc args)) + (define (set-check-compatible name s1 s2) (define spec (custom-set-spec s1)) (unless (and (custom-set? s2) From d927d04efdb70bfbfc2c24fbdd4c7eefa7089ec1 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Fri, 25 Dec 2015 22:31:30 -0600 Subject: [PATCH 240/369] generalize tail contract checking for function contracts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Specifically, remove reliance on procedure-closure-contents-eq? to tell when a pending check is stronger in favor of usint contract-stronger? Also, tighten up the specification of contract-stronger? to require that any contract is stronger than itself With this commit, this program gets about 10% slower: #lang racket/base (require racket/contract/base) (define f (contract (-> any/c integer?) (λ (x) (if (zero? x) 0 (f (- x 1)))) 'pos 'neg)) (time (f 2000000)) becuase the checking is doing work more explicitly now but because the checking in more general, it identifies the redundant checking in this program #lang racket/base (require racket/contract/base) (define f (contract (-> any/c integer?) (contract (-> any/c integer?) (λ (x) (if (zero? x) 0 (f (- x 1)))) 'pos 'neg) 'pos 'neg)) (time (f 200000)) which makes it run about 13x faster than it did before I'm not sure if this is a win overall, since the checking can be more significant in the case of "near misses". For example, with this program, where neither the new nor the old checking detects the redundancy is about 40% slower after this commit than it was before: #lang racket/base (require racket/contract/base) (define f (contract (-> any/c (<=/c 0)) (contract (-> any/c (>=/c 0)) (λ (x) (if (zero? x) 0 (f (- x 1)))) 'pos 'neg) 'pos 'neg)) (time (f 50000)) (The redundancy isn't detected here because the contract system only looks at the first pending contract check.) Overall, despite the fact that it slows down some programs and speeds up others, my main thought is that it is worth doing because it eliminates a (painful) reliance on procedure-closure-contents-eq? that inhibits other approaches to optimizing these contracts we might try. --- .../scribblings/reference/contracts.scrbl | 11 +- .../tests/racket/contract/arrow.rkt | 15 +++ .../tests/racket/contract/tail.rkt | 23 ++++ .../contract/private/arrow-higher-order.rkt | 35 +++-- .../contract/private/arrow-val-first.rkt | 10 +- .../racket/contract/private/arrow.rkt | 127 +++++++++++------- .../racket/contract/private/case-arrow.rkt | 104 ++++++++------ .../racket/contract/private/opt-guts.rkt | 5 + .../racket/contract/private/opters.rkt | 4 +- .../collects/racket/contract/private/prop.rkt | 76 ++++++----- 10 files changed, 266 insertions(+), 144 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index 487a0b3899..fc6313f011 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -2024,8 +2024,8 @@ flat contracts do not need to supply an explicit projection. The @racket[stronger] argument is used to implement @racket[contract-stronger?]. The first argument is always the contract itself and the second argument is whatever was passed as the second argument to @racket[contract-stronger?]. If no -@racket[stronger] argument is supplied, then a default that always returns -@racket[#f] is used. +@racket[stronger] argument is supplied, then a default that compares its arguments +with @racket[equal?] is used. The @racket[is-list-contract?] argument is used by the @racket[list-contract?] predicate to determine if this is a contract that accepts only @racket[list?] values. @@ -2721,6 +2721,9 @@ are below): Returns @racket[#t] if the contract @racket[x] accepts either fewer or the same number of values as @racket[y] does. + Contracts that are the same (i.e., where @racket[x] is @racket[equal?] + to @racket[y]) are considered to always be stronger than each other. + This function is conservative, so it may return @racket[#f] when @racket[x] does, in fact, accept fewer values. @@ -2730,8 +2733,8 @@ are below): (contract-stronger? (between/c 0 100) (between/c 25 75)) (contract-stronger? (between/c -10 0) (between/c 0 10)) - (contract-stronger? (λ (x) (and (real? x) (<= x (random 10)))) - (λ (x) (and (real? x) (<= x (+ 100 (random 10))))))] + (contract-stronger? (λ (x) (and (real? x) (<= x 0))) + (λ (x) (and (real? x) (<= x 100))))] } diff --git a/pkgs/racket-test/tests/racket/contract/arrow.rkt b/pkgs/racket-test/tests/racket/contract/arrow.rkt index 9d436e3bcc..c0de59f415 100644 --- a/pkgs/racket-test/tests/racket/contract/arrow.rkt +++ b/pkgs/racket-test/tests/racket/contract/arrow.rkt @@ -340,6 +340,21 @@ ;; pass; this is fixed in a separate branch that can't (regexp-match #rx"expected:? keyword argument #:the-missing-keyword-arg-b" (exn-message x))))) + + ;; need to preserve the inner contract here + ;; (not the outer one) + ;; when dropping redundant tail contracts + (test/pos-blame + 'tail-wrapping-preserves-blame + '(let ([c (-> number? number?)]) + ((contract + c + (contract + c + (λ (x) #f) + 'pos 'neg) + 'something-else 'yet-another-thing) + 1))) (test/pos-blame 'predicate/c1 diff --git a/pkgs/racket-test/tests/racket/contract/tail.rkt b/pkgs/racket-test/tests/racket/contract/tail.rkt index 708b376ce0..024f0fe544 100644 --- a/pkgs/racket-test/tests/racket/contract/tail.rkt +++ b/pkgs/racket-test/tests/racket/contract/tail.rkt @@ -85,6 +85,29 @@ (c))) (ctest/rewrite '(1) + mut-rec-with-any + (let () + (define f + (contract (-> number? any) + (lambda (x) + (if (zero? x) + (continuation-mark-set->list (current-continuation-marks) + 'tail-test) + (with-continuation-mark 'tail-test x + (g (- x 1))))) + 'something-that-is-not-pos + 'neg)) + + (define g + (contract (-> number? any) + (lambda (x) + (f x)) + 'also-this-is-not-pos + 'neg)) + + (f 3))) + + (ctest/rewrite '(1 2 3) mut-rec-with-any/c (let () (define f diff --git a/racket/collects/racket/contract/private/arrow-higher-order.rkt b/racket/collects/racket/contract/private/arrow-higher-order.rkt index 7e7ac58481..8c72a5cdde 100644 --- a/racket/collects/racket/contract/private/arrow-higher-order.rkt +++ b/racket/collects/racket/contract/private/arrow-higher-order.rkt @@ -32,15 +32,15 @@ [(optional-dom-kwd-proj ...) (nvars (length optional-dom-kwds) 'optional-dom-proj)] [(rng-proj ...) (if rngs (generate-temporaries rngs) '())] [(rest-proj ...) (if rest (generate-temporaries '(rest-proj)) '())]) - #`(λ (blame f neg-party + #`(λ (blame f neg-party blame-party-info rng-ctcs mandatory-dom-proj ... optional-dom-proj ... rest-proj ... mandatory-dom-kwd-proj ... optional-dom-kwd-proj ... rng-proj ...) - #,(create-chaperone - #'blame #'f + #,(create-chaperone + #'blame #'neg-party #'blame-party-info #'f #'rng-ctcs this-args (syntax->list #'(mandatory-dom-proj ...)) (syntax->list #'(optional-dom-proj ...)) @@ -114,7 +114,8 @@ (if pre? "pre" "post") condition-result)])) -(define-for-syntax (create-chaperone blame val +(define-for-syntax (create-chaperone blame neg-party blame-party-info + val rng-ctcs this-args doms opt-doms req-kwds opt-kwds @@ -150,7 +151,7 @@ [(opt-kwd ...) (map car opt-kwds)] [(opt-kwd-ctc ...) (map cadr opt-kwds)] [(opt-kwd-x ...) (generate-temporaries (map car opt-kwds))] - [(rng-ctc ...) (if rngs rngs '())] + [(rng-late-neg-projs ...) (if rngs rngs '())] [(rng-x ...) (if rngs (generate-temporaries rngs) '())]) (with-syntax ([(rng-checker-name ...) (if rngs @@ -161,7 +162,7 @@ (list (with-syntax ([rng-len (length rngs)]) (with-syntax ([rng-results - #'(values (rng-ctc rng-x neg-party) + #'(values (rng-late-neg-projs rng-x neg-party) ...)]) #'(case-lambda [(rng-x ...) @@ -248,7 +249,9 @@ dom-projd-args ...)))]) (if no-rng-checking? (inner-stx-gen #'()) - (arrow:check-tail-contract #'(rng-ctc ...) + (arrow:check-tail-contract rng-ctcs + blame-party-info + neg-party #'(rng-checker-name ...) inner-stx-gen)))] [kwd-return @@ -273,7 +276,9 @@ #`(let ([kwd-results kwd-stx]) #,(if no-rng-checking? (outer-stx-gen #'()) - (arrow:check-tail-contract #'(rng-ctc ...) + (arrow:check-tail-contract rng-ctcs + blame-party-info + neg-party #'(rng-checker-name ...) outer-stx-gen))))]) (with-syntax ([basic-lambda-name (gen-id 'basic-lambda)] @@ -398,12 +403,15 @@ man-then-opt-partial-kwds partial-ranges (if partial-rest (list partial-rest) '()))) - + (define blame-party-info (arrow:get-blame-party-info orig-blame)) (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)) + (define chap/imp-func (apply chaperone-constructor + orig-blame val + neg-party blame-party-info + rngs the-args)) (cond [chap/imp-func - (if post? + (if (or post? (not rngs)) (chaperone-or-impersonate-procedure val chap/imp-func @@ -414,9 +422,8 @@ 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)))] + impersonator-prop:application-mark + (cons arrow:tail-contract-key (list* neg-party blame-party-info rngs))))] [else val])) (cond diff --git a/racket/collects/racket/contract/private/arrow-val-first.rkt b/racket/collects/racket/contract/private/arrow-val-first.rkt index a5ae6a5fe3..8e229e3c95 100644 --- a/racket/collects/racket/contract/private/arrow-val-first.rkt +++ b/racket/collects/racket/contract/private/arrow-val-first.rkt @@ -895,7 +895,7 @@ optional-keywords (and rest-contract #t) rng-len) - (λ (blame f neg-party . args) + (λ (blame f neg-party blame-party-info rng-ctc-x . args) (define-next next args) (define mandatory-dom-projs (next min-arity)) (define optional-dom-projs (next optionals)) @@ -1242,7 +1242,7 @@ (make--> 0 '() '() #f #f (list (coerce-contract 'whatever void?)) #f - (λ (blame f _ignored-rng-contract) + (λ (blame f _ignored-rng-ctcs _ignored-rng-proj) (λ (neg-party) (call-with-values (λ () (f)) @@ -1276,7 +1276,11 @@ (call-with-values (λ () (f argument)) (rng-checker f blame neg-party)))) - (λ (blame f neg-party _ignored-dom-contract _ignored-rng-contract) + (λ (blame f neg-party + _ignored-blame-party-info + _ignored-rng-ctcs + _ignored-dom-contract + _ignored-rng-contract) (unless (procedure? f) (raise-blame-error blame #:missing-party neg-party f diff --git a/racket/collects/racket/contract/private/arrow.rkt b/racket/collects/racket/contract/private/arrow.rkt index c953a56775..0d9f9dea3a 100644 --- a/racket/collects/racket/contract/private/arrow.rkt +++ b/racket/collects/racket/contract/private/arrow.rkt @@ -32,8 +32,9 @@ (for-syntax check-tail-contract make-this-parameters parse-leftover->*) - contract-key + tail-contract-key tail-marks-match? + get-blame-party-info values/drop arity-checking-wrapper unspecified-dom @@ -49,34 +50,51 @@ (list id) null)) -(define contract-key (gensym 'contract-key)) +(define tail-contract-key (gensym 'tail-contract-key)) -(define-for-syntax (check-tail-contract rng-ctcs rng-checkers call-gen) +(define-for-syntax (check-tail-contract rng-ctcs blame-party-info neg-party rng-checkers call-gen) + (unless (identifier? rng-ctcs) + (raise-argument-error 'check-tail-contract + "identifier?" + 0 + rng-ctcs rng-checkers call-gen)) #`(call-with-immediate-continuation-mark - contract-key + tail-contract-key (λ (m) - (if (tail-marks-match? m . #,rng-ctcs) + (if (tail-marks-match? m #,rng-ctcs #,blame-party-info #,neg-party) #,(call-gen #'()) #,(call-gen rng-checkers))))) -(begin-encourage-inline - (define tail-marks-match? - (case-lambda - [(m) (and m (null? m))] - [(m rng-ctc) - (and m - (not (null? m)) - (null? (cdr m)) - (procedure-closure-contents-eq? (car m) rng-ctc))] - [(m rng-ctc1 rng-ctc2) - (and m - (= (length m) 2) - (procedure-closure-contents-eq? (car m) rng-ctc1) - (procedure-closure-contents-eq? (cadr m) rng-ctc1))] - [(m . rng-ctcs) - (and m - (= (length m) (length rng-ctcs)) - (andmap procedure-closure-contents-eq? m rng-ctcs))]))) +;; m : (or/c #f (cons/c neg-party (cons/c (list/c pos-party boolean?[blame-swapped?]) (listof ctc)))) +;; rng-ctc : (or/c #f (listof ctc)) +;; blame-party-info : (list/c pos-party boolean?[blame-swapped?]) +;; neg-party : neg-party +(define (tail-marks-match? m rng-ctcs blame-party-info neg-party) + (and m + rng-ctcs + (eq? (car m) neg-party) + (let ([mark-blame-part-info (cadr m)]) + (and (eq? (car mark-blame-part-info) (car blame-party-info)) + (eq? (cadr mark-blame-part-info) (cadr blame-party-info)))) + (let loop ([m (cddr m)] + [rng-ctcs rng-ctcs]) + (cond + [(null? m) (null? rng-ctcs)] + [(null? rng-ctcs) (null? m)] + [else + (define m1 (car m)) + (define rng-ctc1 (car rng-ctcs)) + (cond + [(eq? m1 rng-ctc1) (loop (cdr m) (cdr rng-ctcs))] + [(contract-struct-stronger? m1 rng-ctc1) (loop (cdr m) (cdr rng-ctcs))] + [else #f])])))) + +;; used as part of the information in the continuation mark +;; that records what is to be checked for a pending contract +(define (get-blame-party-info blame) + (define swapped? (blame-swapped? blame)) + (list (if swapped? (blame-negative blame) (blame-positive blame)) + swapped?)) (define-syntax (unconstrained-domain-> stx) (syntax-case stx () @@ -86,9 +104,11 @@ [(p-app-x ...) (generate-temporaries #'(rngs ...))] [(res-x ...) (generate-temporaries #'(rngs ...))]) #`(let ([rngs-x (coerce-contract 'unconstrained-domain-> rngs)] ...) - (let ([proj-x (get/build-late-neg-projection rngs-x)] ...) + (let ([rngs-list (list rngs-x ...)] + [proj-x (get/build-late-neg-projection rngs-x)] ...) (define (projection wrapper get-ctc) (λ (orig-blame) + (define blame-party-info (get-blame-party-info orig-blame)) (define ctc (get-ctc)) (let ([rng-blame (blame-add-range-context orig-blame)]) (let* ([p-app-x (proj-x rng-blame)] ...) @@ -102,19 +122,23 @@ (with-contract-continuation-mark (cons orig-blame neg-party) #,(check-tail-contract - #'(p-app-x ...) + #'rngs-list + #'blame-party-info + #'neg-party (list #'res-checker) (λ (s) #`(apply values #,@s kwd-vals args))))) (λ args (with-contract-continuation-mark (cons orig-blame neg-party) #,(check-tail-contract - #'(p-app-x ...) + #'rngs-list + #'blame-party-info + #'neg-party (list #'res-checker) (λ (s) #`(apply values #,@s args)))))) impersonator-prop:contracted ctc impersonator-prop:application-mark - (cons contract-key (list p-app-x ...)))))))) + (cons tail-contract-key (list neg-party blame-party-info rngs-x ...)))))))) (make-unconstrained-domain-> (list rngs-x ...) projection))))])) @@ -200,9 +224,9 @@ (loop (cdr accepted) req-kwds (cdr opt-kwds))] [else #f]))]))) -(define-for-syntax (create-chaperone blame neg-party val pre post this-args +(define-for-syntax (create-chaperone blame neg-party blame-party-info val pre post this-args doms opt-doms dom-rest req-kwds opt-kwds - rngs) + rngs rng-ctc-id) (with-syntax ([blame blame] [neg-party neg-party] [val val]) @@ -318,7 +342,9 @@ (dom-ctc dom-x neg-party) ...)))]) (if no-rng-checking? (inner-stx-gen #'()) - (check-tail-contract #'(rng-ctc ...) + (check-tail-contract rng-ctc-id + blame-party-info + #'neg-party #'(rng-checker-name ...) inner-stx-gen)))] [kwd-return @@ -340,7 +366,11 @@ #`(let ([kwd-results kwd-stx]) #,(if no-rng-checking? (outer-stx-gen #'()) - (check-tail-contract #'(rng-ctc ...) #'(rng-checker-name ...) outer-stx-gen))))]) + (check-tail-contract rng-ctc-id + blame-party-info + #'neg-party + #'(rng-checker-name ...) + outer-stx-gen))))]) (with-syntax ([basic-lambda-name (gen-id 'basic-lambda)] [basic-lambda #'(λ basic-params ;; Arrow contract domain checking is instrumented @@ -534,7 +564,8 @@ (append (base->-doms/c ctc) (list (base->-dom-rest/c ctc))) (base->-doms/c ctc)))] [doms-optional-proj (map get/build-late-neg-projection (base->-optional-doms/c ctc))] - [rngs-proj (map get/build-late-neg-projection (base->-rngs/c ctc))] + [rngs-ctc (base->-rngs/c ctc)] + [rngs-proj (map get/build-late-neg-projection rngs-ctc)] [mandatory-kwds-proj (map get/build-late-neg-projection (base->-mandatory-kwds/c ctc))] [optional-kwds-proj (map get/build-late-neg-projection (base->-optional-kwds/c ctc))] [mandatory-keywords (base->-mandatory-kwds ctc)] @@ -578,16 +609,18 @@ (kwd-proj (blame-add-context orig-blame (format "the ~a argument of" kwd) #:swap? #t)))) - (define the-args (append partial-doms partial-optional-doms - partial-mandatory-kwds partial-optional-kwds - partial-ranges)) + (define the-args (cons rngs-ctc + (append partial-doms partial-optional-doms + partial-mandatory-kwds partial-optional-kwds + partial-ranges))) + (define blame-party-info (get-blame-party-info orig-blame)) (λ (val neg-party) (if has-rest? (check-procedure/more val mtd? dom-length mandatory-keywords optional-keywords orig-blame neg-party) (check-procedure val mtd? dom-length optionals-length mandatory-keywords optional-keywords orig-blame neg-party)) - (define chap/imp-func (apply func orig-blame neg-party val the-args)) + (define chap/imp-func (apply func orig-blame neg-party blame-party-info val the-args)) (if post (wrapper val @@ -597,9 +630,8 @@ val chap/imp-func impersonator-prop:contracted ctc - impersonator-prop:application-mark (cons contract-key - ;; is this right? - partial-ranges))))))) + impersonator-prop:application-mark + (cons tail-contract-key (list* neg-party blame-party-info rngs-ctc)))))))) (define (->-name ctc) (single-arrow-name-maker @@ -811,19 +843,22 @@ [(kwd-ctcs ...) (map (λ (x) (syntax-property x 'racket/contract:negative-position this->)) (syntax->list kwd-ctcs))] [(kwds ...) kwds] + [(rng-ctc-x) (generate-temporaries '(rng-ctc-x))] [use-any? use-any?]) (with-syntax ([mtd? (and (syntax-parameter-value #'making-a-method) #t)] [->m-ctc? (and (syntax-parameter-value #'method-contract?) #t)] [outer-lambda - #`(lambda (blame neg-party val dom-names ... kwd-names ... rng-names ...) + #`(lambda (blame neg-party blame-party-info val rng-ctc-x + dom-names ... kwd-names ... rng-names ...) #,(create-chaperone - #'blame #'neg-party #'val #f #f + #'blame #'neg-party #'blame-party-info #'val #f #f (syntax->list #'(this-params ...)) (syntax->list #'(dom-names ...)) null #f (map list (syntax->list #'(kwds ...)) (syntax->list #'(kwd-names ...))) null - (if (syntax->datum #'use-any?) #f (syntax->list #'(rng-names ...)))))]) + (if (syntax->datum #'use-any?) #f (syntax->list #'(rng-names ...))) + #'rng-ctc-x))]) (syntax-property (syntax/loc stx (build--> '-> @@ -976,6 +1011,7 @@ [->m-ctc? (and (syntax-parameter-value #'method-contract?) #t)] [(rng-proj ...) (generate-temporaries (or rng-ctc '()))] [(rng ...) (generate-temporaries (or rng-ctc '()))] + [(rng-ctc-x) (generate-temporaries '(rng-ctc-x))] [(this-parameter ...) (make-this-parameters (car (generate-temporaries '(this))))]) (quasisyntax/loc stx @@ -996,7 +1032,7 @@ #''()) #,(if rng-ctc #f #t) mtd? ->m-ctc? - (λ (blame neg-party f + (λ (blame neg-party blame-party-info f rng-ctc-x mandatory-dom-proj ... #,@(if rest-ctc #'(rest-proj) @@ -1006,7 +1042,7 @@ optional-dom-kwd-proj ... rng-proj ...) #,(create-chaperone - #'blame #'neg-party #'f pre post + #'blame #'neg-party #'blame-party-info #'f pre post (syntax->list #'(this-parameter ...)) (syntax->list #'(mandatory-dom-proj ...)) (syntax->list #'(optional-dom-proj ...)) @@ -1015,7 +1051,8 @@ (syntax->list #'(mandatory-dom-kwd-proj ...))) (map list (syntax->list #'(optional-dom-kwd ...)) (syntax->list #'(optional-dom-kwd-proj ...))) - (if rng-ctc (syntax->list #'(rng-proj ...)) #f)))))))))))])) + (if rng-ctc (syntax->list #'(rng-proj ...)) #f) + #'rng-ctc-x))))))))))])) (define (convert-pre-post/desc-to-boolean pre? b) (cond diff --git a/racket/collects/racket/contract/private/case-arrow.rkt b/racket/collects/racket/contract/private/case-arrow.rkt index 83eca5e086..f51e1862ef 100644 --- a/racket/collects/racket/contract/private/case-arrow.rkt +++ b/racket/collects/racket/contract/private/case-arrow.rkt @@ -52,27 +52,29 @@ [_ (raise-syntax-error #f "expected ->" stx case)])) -(define-for-syntax (parse-out-case stx case n) - (let-values ([(doms rst rng) (separate-out-doms/rst/rng stx case)]) - (with-syntax ([(dom-proj-x ...) (generate-temporaries doms)] +(define-for-syntax (parse-out-case stx neg-party blame-party-info case n) + (let-values ([(dom-ctc-exprs rst-ctc-expr rng-ctc-exprs) (separate-out-doms/rst/rng stx case)]) + (with-syntax ([(dom-proj-x ...) (generate-temporaries dom-ctc-exprs)] [(rst-proj-x) (generate-temporaries '(rest-proj-x))] - [(rng-proj-x ...) (generate-temporaries (if rng rng '()))]) - (with-syntax ([(dom-formals ...) (generate-temporaries doms)] + [(rng-proj-x ...) (generate-temporaries (if rng-ctc-exprs rng-ctc-exprs '()))] + [(rng-ctcs-x) (generate-temporaries '(rng-ctc-x))]) + (with-syntax ([(dom-formals ...) (generate-temporaries dom-ctc-exprs)] [(rst-formal) (generate-temporaries '(rest-param))] - [(rng-id ...) (if rng - (generate-temporaries rng) + [(rng-id ...) (if rng-ctc-exprs + (generate-temporaries rng-ctc-exprs) '())] [(this-parameter ...) (make-this-parameters (car (generate-temporaries '(this))))]) - #`(#,doms - #,rst - #,(if rng #`(list #,@rng) #f) - #,(length (syntax->list doms)) ;; spec - (dom-proj-x ... #,@(if rst #'(rst-proj-x) #'())) + #`(#,dom-ctc-exprs + #,rst-ctc-expr + #,(if rng-ctc-exprs #`(list #,@rng-ctc-exprs) #f) + #,(length (syntax->list dom-ctc-exprs)) ;; spec + (dom-proj-x ... #,@(if rst-ctc-expr #'(rst-proj-x) #'())) (rng-proj-x ...) - (this-parameter ... dom-formals ... . #,(if rst #'rst-formal '())) + rng-ctcs-x + (this-parameter ... dom-formals ... . #,(if rst-ctc-expr #'rst-formal '())) #,(cond - [rng + [rng-ctc-exprs (let ([rng-checkers (list #`(case-lambda [(rng-id ...) (values/drop (rng-proj-x rng-id neg-party) ...)] @@ -81,19 +83,21 @@ #,(length (syntax->list #'(rng-id ...))) args #,n)]))] - [rng-length (length (syntax->list rng))]) - (if rst - (check-tail-contract #'(rng-proj-x ...) rng-checkers + [rng-length (length (syntax->list rng-ctc-exprs))]) + (if rst-ctc-expr + (check-tail-contract #'rng-ctcs-x + blame-party-info neg-party + rng-checkers (λ (rng-checks) #`(apply values #,@rng-checks this-parameter ... (dom-proj-x dom-formals neg-party) ... (rst-proj-x rst-formal neg-party)))) (check-tail-contract - #'(rng-proj-x ...) rng-checkers + #'rng-ctcs-x blame-party-info neg-party rng-checkers (λ (rng-checks) #`(values/drop #,@rng-checks this-parameter ... (dom-proj-x dom-formals neg-party) ...)))))] - [rst + [rst-ctc-expr #`(apply values this-parameter ... (dom-proj-x dom-formals neg-party) ... (rst-proj-x rst-formal neg-party))] @@ -106,30 +110,33 @@ [(_ cases ...) (let () (define name (syntax-local-infer-name stx)) - (with-syntax ([(((dom-proj ...) - rst-proj - rng-proj + (with-syntax ([(((dom-ctc-expr ...) + rst-ctc-expr + rng-ctc-exprs spec (dom-proj-x ...) (rng-proj-x ...) + rng-ctcs-x formals body) ...) (for/list ([x (in-list (syntax->list #'(cases ...)))] [n (in-naturals)]) - (parse-out-case stx x n))] + (parse-out-case stx #'neg-party #'blame-party-info x n))] [mctc? (and (syntax-parameter-value #'method-contract?) #t)]) #`(syntax-parameterize ((making-a-method #f)) (build-case-> - (list (list dom-proj ...) ...) - (list rst-proj ...) - (list rng-proj ...) + (list (list dom-ctc-expr ...) ...) + (list rst-ctc-expr ...) + (list rng-ctc-exprs ...) '(spec ...) mctc? (λ (chk wrapper blame + blame-party-info ctc + rng-ctcs-x ... #,@(apply append (map syntax->list (syntax->list #'((dom-proj-x ...) ...)))) #,@(apply append (map syntax->list (syntax->list #'((rng-proj-x ...) ...))))) (λ (f neg-party) @@ -139,12 +146,12 @@ (if name #`(let ([#,name #,case-lam]) #,name) case-lam)) - (list (list rng-proj-x ...) ...) - f blame neg-party wrapper ctc + f blame neg-party blame-party-info wrapper ctc chk #,(and (syntax-parameter-value #'making-a-method) #t))))))))])) -(define (put-it-together the-case-lam range-projections f blame neg-party wrapper ctc chk mtd?) +(define (put-it-together the-case-lam f blame neg-party blame-party-info wrapper ctc chk mtd?) (chk f mtd?) + (define rng-ctcs (base-case->-rng-ctcs ctc)) (define checker (make-keyword-procedure (raise-no-keywords-error f blame neg-party) @@ -152,14 +159,15 @@ (with-contract-continuation-mark (cons blame neg-party) (apply the-case-lam args))))) - (define same-rngs (same-range-projections range-projections)) + (define same-rngs (same-range-contracts rng-ctcs)) (if same-rngs (wrapper f checker impersonator-prop:contracted ctc impersonator-prop:blame (blame-add-missing-party blame neg-party) - impersonator-prop:application-mark (cons contract-key same-rngs)) + impersonator-prop:application-mark + (cons tail-contract-key (list* neg-party blame-party-info same-rngs))) (wrapper f checker @@ -184,13 +192,17 @@ (define (case->-proj wrapper) (λ (ctc) (define dom-ctcs+case-nums (get-case->-dom-ctcs+case-nums ctc)) - (define rng-late-neg-ctcs (map get/build-late-neg-projection (get-case->-rng-ctcs ctc))) + (define rng-ctcs (get-case->-rng-ctcs ctc)) + (define rng-lol-ctcs (base-case->-rng-ctcs ctc)) + (define rng-late-neg-ctcs (map get/build-late-neg-projection rng-ctcs)) (define rst-ctcs (base-case->-rst-ctcs ctc)) (define specs (base-case->-specs ctc)) (λ (blame) (define dom-blame (blame-add-context blame "the domain of" #:swap? #t)) (define rng-blame (blame-add-context blame "the range of")) - (define projs (append (map (λ (f) ((cdr f) + (define blame-party-info (get-blame-party-info blame)) + (define projs (append rng-lol-ctcs + (map (λ (f) ((cdr f) (blame-add-context (blame-add-context blame @@ -231,6 +243,7 @@ chk wrapper blame + blame-party-info ctc projs)))) @@ -303,18 +316,23 @@ (define (get-case->-rng-ctcs ctc) (for/fold ([acc '()]) - ([x (in-list (base-case->-rng-ctcs ctc))] - #:when x) + ([x (in-list (base-case->-rng-ctcs ctc))] + #:when x) (append acc x))) ;; Takes a list of (listof projection), and returns one of the ;; lists if all the lists contain the same projections. If the list is ;; null, it returns #f. -(define (same-range-projections rng-ctcss) - (if (null? rng-ctcss) - #f - (let* ([fst (car rng-ctcss)] - [all-same? (for/and ([ps (in-list (cdr rng-ctcss))]) - (and (= (length fst) (length ps)) - (andmap procedure-closure-contents-eq? fst ps)))]) - (and all-same? fst)))) +(define (same-range-contracts rng-ctcss) + (cond + [(null? rng-ctcss) #f] + [else + (define fst (car rng-ctcss)) + (and (for/and ([ps (in-list (cdr rng-ctcss))]) + (and ps + (= (length fst) (length ps)) + (for/and ([c (in-list ps)] + [fst-c (in-list fst)]) + (and (contract-stronger? c fst-c) + (contract-stronger? fst-c c))))) + fst)])) diff --git a/racket/collects/racket/contract/private/opt-guts.rkt b/racket/collects/racket/contract/private/opt-guts.rkt index aca87b6150..9ac523fe3a 100644 --- a/racket/collects/racket/contract/private/opt-guts.rkt +++ b/racket/collects/racket/contract/private/opt-guts.rkt @@ -23,6 +23,7 @@ opt/info-add-blame-context opt/info-change-val opt/info-positive-blame + opt/info-negative-blame opt/unknown opt-error-name @@ -164,6 +165,10 @@ (if (opt/info-swap-blame? oi) #`(blame-positive #,(opt/info-blame-original-id oi)) #`(blame-negative #,(opt/info-blame-original-id oi)))) +(define (opt/info-negative-blame oi) + (if (opt/info-swap-blame? oi) + #`(blame-negative #,(opt/info-blame-original-id oi)) + #`(blame-positive #,(opt/info-blame-original-id oi)))) ;; opt/info-swap-blame : opt/info -> opt/info ;; swaps pos and neg diff --git a/racket/collects/racket/contract/private/opters.rkt b/racket/collects/racket/contract/private/opters.rkt index d1e0104929..64c4e97b25 100644 --- a/racket/collects/racket/contract/private/opters.rkt +++ b/racket/collects/racket/contract/private/opters.rkt @@ -576,7 +576,9 @@ (syntax-case stx () [(x) #'x] [(x ...) #'(values x ...)])) - #`(let* ([cont-mark-value (cons #,(opt/info-positive-blame opt/info) '#,rngs)] + #`(let* ([cont-mark-value (list* #,(opt/info-positive-blame opt/info) + #,(opt/info-negative-blame opt/info) + '#,rngs)] [exact-proc (case-lambda [(dom-arg ...) (let-values ([(rng-checker dom-vars ...) diff --git a/racket/collects/racket/contract/private/prop.rkt b/racket/collects/racket/contract/private/prop.rkt index 4964594e3e..89b2ad36b0 100644 --- a/racket/collects/racket/contract/private/prop.rkt +++ b/racket/collects/racket/contract/private/prop.rkt @@ -115,42 +115,50 @@ (define trail (make-parameter #f)) (define (contract-struct-stronger? a b) - (define prop (contract-struct-property a)) - (define stronger? (contract-property-stronger prop)) (cond - [(let ([th (trail)]) - (and th - (for/or ([(a2 bs-h) (in-hash th)]) - (and (eq? a a2) - (for/or ([(b2 _) (in-hash bs-h)]) - (eq? b b2)))))) - #t] - [(or (prop:recursive-contract? a) (prop:recursive-contract? b)) - (parameterize ([trail (or (trail) (make-hasheq))]) - (define trail-h (trail)) - (let ([a-h (hash-ref trail-h a #f)]) - (cond - [a-h - (hash-set! a-h b #t)] - [else - (define a-h (make-hasheq)) - (hash-set! trail-h a a-h) - (hash-set! a-h b #t)])) - (contract-struct-stronger? (if (prop:recursive-contract? a) - ((prop:recursive-contract-unroll a) a) - a) - (if (prop:recursive-contract? b) - ((prop:recursive-contract-unroll b) b) - b)))] + [(equal? a b) #t] [else - (let loop ([b b]) - (cond - [(stronger? a b) #t] - [(prop:orc-contract? b) - (define sub-contracts ((prop:orc-contract-get-subcontracts b) b)) - (for/or ([sub-contract (in-list sub-contracts)]) - (loop sub-contract))] - [else #f]))])) + (define prop (contract-struct-property a)) + (define stronger? (contract-property-stronger prop)) + (cond + [(stronger? a b) + ;; optimistically try skip some of the more complex work below + #t] + [(let ([th (trail)]) + (and th + (for/or ([(a2 bs-h) (in-hash th)]) + (and (eq? a a2) + (for/or ([(b2 _) (in-hash bs-h)]) + (eq? b b2)))))) + #t] + [(or (prop:recursive-contract? a) (prop:recursive-contract? b)) + (parameterize ([trail (or (trail) (make-hasheq))]) + (define trail-h (trail)) + (let ([a-h (hash-ref trail-h a #f)]) + (cond + [a-h + (hash-set! a-h b #t)] + [else + (define a-h (make-hasheq)) + (hash-set! trail-h a a-h) + (hash-set! a-h b #t)])) + (contract-struct-stronger? (if (prop:recursive-contract? a) + ((prop:recursive-contract-unroll a) a) + a) + (if (prop:recursive-contract? b) + ((prop:recursive-contract-unroll b) b) + b)))] + [else + (let loop ([b b]) + (cond + [(stronger? a b) + #t] + [(prop:orc-contract? b) + (define sub-contracts ((prop:orc-contract-get-subcontracts b) b)) + (for/or ([sub-contract (in-list sub-contracts)]) + (loop sub-contract))] + [else + #f]))])])) (define (contract-struct-generate c) (define prop (contract-struct-property c)) From 1b6705f3d9c6141ebcb50612bf4437c6734f9be8 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 26 Dec 2015 17:01:22 -0600 Subject: [PATCH 241/369] typo --- pkgs/racket-doc/scribblings/reference/extflonums.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/extflonums.scrbl b/pkgs/racket-doc/scribblings/reference/extflonums.scrbl index 309d3dadc6..4419129db3 100644 --- a/pkgs/racket-doc/scribblings/reference/extflonums.scrbl +++ b/pkgs/racket-doc/scribblings/reference/extflonums.scrbl @@ -116,7 +116,7 @@ Like @racket[flsin], @racket[flcos], @racket[fltan], @racket[flasin], The first four are like @racket[->fl], @racket[fl->exact], @racket[fl->real], @racket[inexact->exact], but for @tech{extflonums}. The @racket[extfl->inexact] function converts a @tech{extflonum} to -its closest @racket{flonum} approximation.} +its closest @tech{flonum} approximation.} @; ------------------------------------------------------------------------ From daf19869de0e0c512305c389695ba929697cfb5a Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 26 Dec 2015 22:05:29 -0600 Subject: [PATCH 242/369] chaperone-hash-set fixes --- pkgs/racket-doc/scribblings/reference/sets.scrbl | 8 ++++---- pkgs/racket-test-core/tests/racket/set.rktl | 5 +++++ racket/collects/racket/private/set-types.rkt | 9 +++++++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/sets.scrbl b/pkgs/racket-doc/scribblings/reference/sets.scrbl index 8f8aefc29c..966eb7238e 100644 --- a/pkgs/racket-doc/scribblings/reference/sets.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sets.scrbl @@ -699,11 +699,11 @@ Supported for any @racket[st] that @supp{supports} @racket[set->stream]. [ref-proc (-> set? any/c any/c)] [add-proc (-> set? any/c any/c)] [remove-proc (-> set? any/c any/c)] - [clear-proc (or/c #f (-> set? any))] + [clear-proc (or/c #f (-> set? any)) #f] [prop impersonator-property?] [prop-val any/c] ... ...) (and/c set? impersonator?)]{ - Impersonates @racket[set], redirecting via the given procedures. + Impersonates @racket[st], redirecting via the given procedures. The @racket[ref-proc] procedure is called whenever an element is extracted from @racket[st]. Its first argument @@ -737,11 +737,11 @@ Supported for any @racket[st] that @supp{supports} @racket[set->stream]. [ref-proc (-> set? any/c any/c)] [add-proc (-> set? any/c any/c)] [remove-proc (-> set? any/c any/c)] - [clear-proc (or/c #f (-> set? any))] + [clear-proc (or/c #f (-> set? any)) #f] [prop impersonator-property?] [prop-val any/c] ... ...) (and/c set? chaperone?)]{ - Chaperones @racket[set]. Like @racket[impersonate-hash-set] but with + Chaperones @racket[st]. Like @racket[impersonate-hash-set] but with the constraints that the results of the @racket[ref-proc], @racket[add-proc], and @racket[remove-proc] must be @racket[chaperone-of?] their second arguments. Also, the input diff --git a/pkgs/racket-test-core/tests/racket/set.rktl b/pkgs/racket-test-core/tests/racket/set.rktl index 3322a3d996..c1a3eb5c5c 100644 --- a/pkgs/racket-test-core/tests/racket/set.rktl +++ b/pkgs/racket-test-core/tests/racket/set.rktl @@ -631,5 +631,10 @@ (λ (s e) (+ e 1)) (λ (s l) l) (λ (s l) l)))) +(test #t even? + (set-first (impersonate-hash-set (weak-set 1 3 5) + (λ (s e) (+ e 1)) + (λ (s l) l) + (λ (s l) l)))) (report-errs) diff --git a/racket/collects/racket/private/set-types.rkt b/racket/collects/racket/private/set-types.rkt index 7192549c45..08f52577ee 100644 --- a/racket/collects/racket/private/set-types.rkt +++ b/racket/collects/racket/private/set-types.rkt @@ -403,10 +403,15 @@ remove-proc clear-proc+props) (define who (if impersonate? 'impersonate-hash-set 'chaperone-hash-set)) - (unless (if impersonate? (set-mutable? s) (or (set? s) (set-mutable? s))) + (unless (if impersonate? + (or (set-mutable? s) (set-weak? s)) + (or (set? s) (set-mutable? s) (set-weak? s))) (apply raise-argument-error who - (if impersonate? "set-mutable?" (format "~s" '(or/c set? set-mutable?))) + (format "~s" + (if impersonate? + '(or/c set-mutable? set-weak?) + '(or/c set? set-mutable? set-weak?))) 0 s ref-proc add-proc clear-proc+props)) (unless (and (procedure? ref-proc) (procedure-arity-includes? ref-proc 2)) From 8f2874e4b53805e75556fd71b57f3e63ed413e54 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 26 Dec 2015 22:35:16 -0600 Subject: [PATCH 243/369] fix impersonator properties for chaperone-hash-set and impersonate-hash-set --- pkgs/racket-test-core/tests/racket/set.rktl | 21 +++++++ racket/collects/racket/private/set-types.rkt | 64 ++++++++++++-------- 2 files changed, 59 insertions(+), 26 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/set.rktl b/pkgs/racket-test-core/tests/racket/set.rktl index c1a3eb5c5c..2965ec0e7b 100644 --- a/pkgs/racket-test-core/tests/racket/set.rktl +++ b/pkgs/racket-test-core/tests/racket/set.rktl @@ -636,5 +636,26 @@ (λ (s e) (+ e 1)) (λ (s l) l) (λ (s l) l)))) +(let-values ([(impersonator-prop:p has-impersonator-prop:p? get-impersonator-prop:p) + (make-impersonator-property 'p)]) + (let ([s (chaperone-hash-set (set) (λ (s l) l) (λ (s l) l) (λ (s l) l) impersonator-prop:p 11)]) + (test #t has-impersonator-prop:p? s))) + +(let-values ([(impersonator-prop:p has-impersonator-prop:p? get-impersonator-prop:p) + (make-impersonator-property 'p)]) + (let ([s (chaperone-hash-set (set) (λ (s l) l) (λ (s l) l) (λ (s l) l) impersonator-prop:p 11)]) + (test 11 get-impersonator-prop:p s))) + +(let-values ([(impersonator-prop:p has-impersonator-prop:p? get-impersonator-prop:p) + (make-impersonator-property 'p)]) + (let ([s (impersonate-hash-set (weak-set) (λ (s l) l) (λ (s l) l) (λ (s l) l) + impersonator-prop:p 11)]) + (test #t has-impersonator-prop:p? s))) + +(let-values ([(impersonator-prop:p has-impersonator-prop:p? get-impersonator-prop:p) + (make-impersonator-property 'p)]) + (let ([s (impersonate-hash-set (mutable-set) (λ (s l) l) (λ (s l) l) (λ (s l) l) + impersonator-prop:p 11)]) + (test 11 get-impersonator-prop:p s))) (report-errs) diff --git a/racket/collects/racket/private/set-types.rkt b/racket/collects/racket/private/set-types.rkt index 08f52577ee..222ef87996 100644 --- a/racket/collects/racket/private/set-types.rkt +++ b/racket/collects/racket/private/set-types.rkt @@ -344,7 +344,7 @@ remove-proc . clear-proc+props) - (define-values (clear-proc args) + (define-values (clear-proc prop-args) (check-chap/imp-args #f s ref-proc @@ -357,19 +357,21 @@ "~s did not return a chaperone of ~e, got ~e" who original new)) new) - (update-custom-set-table - s - (apply - chaperone-hash - (custom-set-table s) - (λ (hash key) (values (check-it 'ref-proc key (ref-proc (update-custom-set-table s hash) key)) - (λ (hash key val) val))) - (λ (hash key val) (values (check-it 'add-proc key (add-proc (update-custom-set-table s hash) key)) - val)) - (λ (hash key) (check-it 'remove-proc key (remove-proc (update-custom-set-table s hash) key))) - (λ (hash key) (check-it 'ref-proc key (ref-proc (update-custom-set-table s hash) key))) - (and clear-proc (λ (hash) (clear-proc (update-custom-set-table s hash)))) - args))) + (add-impersonator-properties + (update-custom-set-table + s + (chaperone-hash + (custom-set-table s) + (λ (hash key) + (values (check-it 'ref-proc key (ref-proc (update-custom-set-table s hash) key)) + (λ (hash key val) val))) + (λ (hash key val) + (values (check-it 'add-proc key (add-proc (update-custom-set-table s hash) key)) + val)) + (λ (hash key) (check-it 'remove-proc key (remove-proc (update-custom-set-table s hash) key))) + (λ (hash key) (check-it 'ref-proc key (ref-proc (update-custom-set-table s hash) key))) + (and clear-proc (λ (hash) (clear-proc (update-custom-set-table s hash)))))) + prop-args)) (define (impersonate-hash-set s ref-proc @@ -377,24 +379,34 @@ remove-proc . clear-proc+props) - (define-values (clear-proc args) + (define-values (clear-proc prop-args) (check-chap/imp-args #t s ref-proc add-proc remove-proc clear-proc+props)) - (update-custom-set-table - s - (apply - impersonate-hash - (custom-set-table s) - (λ (hash key) (values (ref-proc (update-custom-set-table s hash) key) (λ (hash key val) val))) - (λ (hash key val) (values (add-proc (update-custom-set-table s hash) key) val)) - (λ (hash key) (remove-proc (update-custom-set-table s hash) key)) - (λ (hash key) (ref-proc (update-custom-set-table s hash) key)) - (and clear-proc (λ (hash) (clear-proc (update-custom-set-table s hash)))) - args))) + (add-impersonator-properties + (update-custom-set-table + s + (impersonate-hash + (custom-set-table s) + (λ (hash key) (values (ref-proc (update-custom-set-table s hash) key) (λ (hash key val) val))) + (λ (hash key val) (values (add-proc (update-custom-set-table s hash) key) val)) + (λ (hash key) (remove-proc (update-custom-set-table s hash) key)) + (λ (hash key) (ref-proc (update-custom-set-table s hash) key)) + (and clear-proc (λ (hash) (clear-proc (update-custom-set-table s hash)))))) + prop-args)) + +(define (add-impersonator-properties without-props prop-args) + (cond + [(null? prop-args) without-props] + [(immutable-custom-set? without-props) + (apply chaperone-struct without-props struct:immutable-custom-set prop-args)] + [(weak-custom-set? without-props) + (apply chaperone-struct without-props struct:weak-custom-set prop-args)] + [else + (apply chaperone-struct without-props struct:mutable-custom-set prop-args)])) (define (check-chap/imp-args impersonate? s From bc12019af417bc54664479ba5994924c75e79b8e Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 27 Dec 2015 21:02:20 -0600 Subject: [PATCH 244/369] allow the interposition procedures to all be #f in chaperone-hash-set and impersonate-hash-set --- .../scribblings/reference/sets.scrbl | 16 ++-- pkgs/racket-test-core/tests/racket/set.rktl | 10 +++ racket/collects/racket/private/set-types.rkt | 82 ++++++++++++------- 3 files changed, 71 insertions(+), 37 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/sets.scrbl b/pkgs/racket-doc/scribblings/reference/sets.scrbl index 966eb7238e..03b10fd6ae 100644 --- a/pkgs/racket-doc/scribblings/reference/sets.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sets.scrbl @@ -696,9 +696,9 @@ Supported for any @racket[st] that @supp{supports} @racket[set->stream]. } @defproc[(impersonate-hash-set [st mutable-set?] - [ref-proc (-> set? any/c any/c)] - [add-proc (-> set? any/c any/c)] - [remove-proc (-> set? any/c any/c)] + [ref-proc (or/c #f (-> set? any/c any/c))] + [add-proc (or/c #f (-> set? any/c any/c))] + [remove-proc (or/c #f (-> set? any/c any/c))] [clear-proc (or/c #f (-> set? any)) #f] [prop impersonator-property?] [prop-val any/c] ... ...) @@ -718,6 +718,10 @@ Supported for any @racket[st] that @supp{supports} @racket[set->stream]. from @racket[st]. Its first argument is the set and its second argument is the element being removed. The result of the procedure is the element that actually gets removed from the set. + + If any of the @racket[ref-proc], @racket[add-proc], or @racket[remove-proc] arguments + is @racket[#f], then all three must be and there must be at least one property supplied. + In that case, a more efficient chaperone wrapper is created. If @racket[clear-proc] is not @racket[#f], it must accept @racket[set] as an argument and is result is ignored. The fact that @racket[clear-proc] @@ -734,9 +738,9 @@ Supported for any @racket[st] that @supp{supports} @racket[set->stream]. } @defproc[(chaperone-hash-set [st (or/c set? mutable-set?)] - [ref-proc (-> set? any/c any/c)] - [add-proc (-> set? any/c any/c)] - [remove-proc (-> set? any/c any/c)] + [ref-proc (or/c #f (-> set? any/c any/c))] + [add-proc (or/c #f (-> set? any/c any/c))] + [remove-proc (or/c #f (-> set? any/c any/c))] [clear-proc (or/c #f (-> set? any)) #f] [prop impersonator-property?] [prop-val any/c] ... ...) diff --git a/pkgs/racket-test-core/tests/racket/set.rktl b/pkgs/racket-test-core/tests/racket/set.rktl index 2965ec0e7b..6270e66779 100644 --- a/pkgs/racket-test-core/tests/racket/set.rktl +++ b/pkgs/racket-test-core/tests/racket/set.rktl @@ -658,4 +658,14 @@ impersonator-prop:p 11)]) (test 11 get-impersonator-prop:p s))) +(let-values ([(impersonator-prop:p has-impersonator-prop:p? get-impersonator-prop:p) + (make-impersonator-property 'p)]) + (let ([s (chaperone-hash-set (set) #f #f #f impersonator-prop:p 11)]) + (test #t has-impersonator-prop:p? s))) + +(let-values ([(impersonator-prop:p has-impersonator-prop:p? get-impersonator-prop:p) + (make-impersonator-property 'p)]) + (let ([s (impersonate-hash-set (mutable-set) #f #f #f impersonator-prop:p 11)]) + (test 11 get-impersonator-prop:p s))) + (report-errs) diff --git a/racket/collects/racket/private/set-types.rkt b/racket/collects/racket/private/set-types.rkt index 222ef87996..4a0539060d 100644 --- a/racket/collects/racket/private/set-types.rkt +++ b/racket/collects/racket/private/set-types.rkt @@ -358,19 +358,21 @@ who original new)) new) (add-impersonator-properties - (update-custom-set-table - s - (chaperone-hash - (custom-set-table s) - (λ (hash key) - (values (check-it 'ref-proc key (ref-proc (update-custom-set-table s hash) key)) - (λ (hash key val) val))) - (λ (hash key val) - (values (check-it 'add-proc key (add-proc (update-custom-set-table s hash) key)) - val)) - (λ (hash key) (check-it 'remove-proc key (remove-proc (update-custom-set-table s hash) key))) - (λ (hash key) (check-it 'ref-proc key (ref-proc (update-custom-set-table s hash) key))) - (and clear-proc (λ (hash) (clear-proc (update-custom-set-table s hash)))))) + (if ref-proc + (update-custom-set-table + s + (chaperone-hash + (custom-set-table s) + (λ (hash key) + (values (check-it 'ref-proc key (ref-proc (update-custom-set-table s hash) key)) + (λ (hash key val) val))) + (λ (hash key val) + (values (check-it 'add-proc key (add-proc (update-custom-set-table s hash) key)) + val)) + (λ (hash key) (check-it 'remove-proc key (remove-proc (update-custom-set-table s hash) key))) + (λ (hash key) (check-it 'ref-proc key (ref-proc (update-custom-set-table s hash) key))) + (and clear-proc (λ (hash) (clear-proc (update-custom-set-table s hash)))))) + s) prop-args)) (define (impersonate-hash-set s @@ -387,15 +389,18 @@ remove-proc clear-proc+props)) (add-impersonator-properties - (update-custom-set-table - s - (impersonate-hash - (custom-set-table s) - (λ (hash key) (values (ref-proc (update-custom-set-table s hash) key) (λ (hash key val) val))) - (λ (hash key val) (values (add-proc (update-custom-set-table s hash) key) val)) - (λ (hash key) (remove-proc (update-custom-set-table s hash) key)) - (λ (hash key) (ref-proc (update-custom-set-table s hash) key)) - (and clear-proc (λ (hash) (clear-proc (update-custom-set-table s hash)))))) + (if ref-proc + (update-custom-set-table + s + (impersonate-hash + (custom-set-table s) + (λ (hash key) (values (ref-proc (update-custom-set-table s hash) key) + (λ (hash key val) val))) + (λ (hash key val) (values (add-proc (update-custom-set-table s hash) key) val)) + (λ (hash key) (remove-proc (update-custom-set-table s hash) key)) + (λ (hash key) (ref-proc (update-custom-set-table s hash) key)) + (and clear-proc (λ (hash) (clear-proc (update-custom-set-table s hash)))))) + s) prop-args)) (define (add-impersonator-properties without-props prop-args) @@ -425,24 +430,34 @@ '(or/c set-mutable? set-weak?) '(or/c set? set-mutable? set-weak?))) 0 s ref-proc add-proc clear-proc+props)) - (unless (and (procedure? ref-proc) - (procedure-arity-includes? ref-proc 2)) + (unless (or (not ref-proc) + (and (procedure? ref-proc) + (procedure-arity-includes? ref-proc 2))) (apply raise-argument-error who - "(procedure-arity-includes/c 2)" + "(or/c #f (procedure-arity-includes/c 2))" 1 s ref-proc add-proc clear-proc+props)) - (unless (and (procedure? add-proc) - (procedure-arity-includes? add-proc 2)) + (unless (or (not add-proc) + (and (procedure? add-proc) + (procedure-arity-includes? add-proc 2))) (apply raise-argument-error who - "(procedure-arity-includes/c 2)" + "(or/c #f (procedure-arity-includes/c 2))" 2 s ref-proc add-proc clear-proc+props)) - (unless (and (procedure? remove-proc) - (procedure-arity-includes? remove-proc 2)) + (unless (or (not remove-proc) + (and (procedure? remove-proc) + (procedure-arity-includes? remove-proc 2))) (apply raise-argument-error who - "(procedure-arity-includes/c 2)" + "(or/c #f (procedure-arity-includes/c 2))" 3 s ref-proc add-proc clear-proc+props)) + (when (or (not ref-proc) (not add-proc) (not remove-proc)) + (unless (and (not ref-proc) (not add-proc) (not remove-proc)) + (raise-arguments-error who + "if one of ref-proc, add-proc, or remove-proc is #f, they must all be" + "ref-proc" ref-proc + "add-proc" add-proc + "remove-proc" remove-proc))) (unless (null? clear-proc+props) (unless (or (not (car clear-proc+props)) (and (procedure? (car clear-proc+props)) @@ -472,6 +487,11 @@ "impersonator-property?" (+ i (if supplied-clear-proc? 1 0) 4) s ref-proc add-proc clear-proc+props))) + (unless ref-proc + (when (null? args) + (raise-arguments-error + who + "when ref-proc, add-proc, and remove-proc are #f, at least one property must be supplied"))) (values clear-proc args)) (define (set-check-compatible name s1 s2) From b3d05de304832a3f8cf46684c6ab779e8b070490 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 27 Dec 2015 21:52:16 -0600 Subject: [PATCH 245/369] improvements to set/c - use chaperone-hash-set for set/c when the contract allows only hash-sets - add a #:lazy flag to allow explicit choice of when to use laziness (but have a backwards-compatible default that, roughly, eschews laziness only when the resulting contract would be flat) --- .../scribblings/reference/sets.scrbl | 29 +- .../tests/racket/contract/name.rkt | 3 +- .../racket-test/tests/racket/contract/set.rkt | 110 +++++++- racket/collects/racket/set.rkt | 255 ++++++++++++------ 4 files changed, 303 insertions(+), 94 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/sets.scrbl b/pkgs/racket-doc/scribblings/reference/sets.scrbl index 03b10fd6ae..ff5523751f 100644 --- a/pkgs/racket-doc/scribblings/reference/sets.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sets.scrbl @@ -203,17 +203,20 @@ named by the @racket[sym]s. 'dont-care] [#:kind kind (or/c 'dont-care 'immutable 'mutable 'weak 'mutable-or-weak) - 'immutable]) + 'immutable] + [#:lazy? lazy? any/c + (not (and (equal? kind 'immutable) + (flat-contract? elem/c)))]) contract?]{ Constructs a contract that recognizes sets whose elements match - @racket[contract]. + @racket[elem/c]. If @racket[kind] is @racket['immutable], @racket['mutable], or @racket['weak], the resulting contract accepts only @tech{hash sets} that are respectively immutable, mutable with strongly-held keys, or mutable with weakly-held keys. If @racket[kind] is @racket['mutable-or-weak], the - resulting contract accepts any mutable @racket{hash sets}, regardless of + resulting contract accepts any mutable @tech{hash sets}, regardless of key-holding strength. If @racket[cmp] is @racket['equal], @racket['eqv], or @racket['eq], the @@ -221,12 +224,30 @@ named by the @racket[sym]s. using @racket[equal?], @racket[eqv?], or @racket[eq?], respectively. If @racket[cmp] is @racket['eqv] or @racket['eq], then @racket[elem/c] must - be a flat contract. + be a @tech{flat contract}. If @racket[cmp] and @racket[kind] are both @racket['dont-care], then the resulting contract will accept any kind of set, not just @tech{hash sets}. + If @racket[lazy?] is not @racket[#f], then the elements of the set are not checked + immediately by the contract and only the set itself is checked (according to the + @racket[cmp] and @racket[kind] arguments). If @racket[lazy?] is + @racket[#f], then the elements are checked immediately by the contract. + The @racket[lazy?] argument is ignored when the set contract accepts generic sets + (i.e., when @racket[cmp] and @racket[kind] are both @racket['dont-care]); in that + case, the value being checked in that case is a @racket[list?], then the contract + is not lazy otherwise the contract is lazy. + + If @racket[kind] allows mutable sets (i.e., is @racket['dont-care], + @racket['mutable], @racket['weak], or + @racket['mutable-or-weak]) and @racket[lazy?] is @racket[#f], then the elements + are checked both immediately and when they are accessed from the set. + + The result contract will be a @tech{flat contract} when @racket[elem/c] is a @tech{flat + contract}, @racket[lazy?] is @racket[#f], and @racket[kind] is @racket['immutable]. + The result will be a @tech{chaperone contract} when @racket[elem/c] is a + @tech{chaperone contract}. } @section{Generic Set Interface} diff --git a/pkgs/racket-test/tests/racket/contract/name.rkt b/pkgs/racket-test/tests/racket/contract/name.rkt index d81b3b79ed..a035a9d0cb 100644 --- a/pkgs/racket-test/tests/racket/contract/name.rkt +++ b/pkgs/racket-test/tests/racket/contract/name.rkt @@ -393,7 +393,8 @@ (test-name '(set/c char? #:cmp 'eq) (set/c char? #:cmp 'eq)) (test-name '(set/c (set/c char?) #:cmp 'eqv) (set/c (set/c char? #:cmp 'dont-care) #:cmp 'eqv)) (test-name '(set/c (-> char? char?) #:cmp 'equal) (set/c (-> char? char?) #:cmp 'equal)) - + (test-name '(set/c (-> integer? boolean?)) (set/c (-> integer? boolean?))) + (test-name 'α (let ([α (new-∀/c)]) α)) (test-name 'α (let ([α (new-∀/c #f)]) α)) (test-name 'β (let ([α (new-∀/c 'β)]) α)) diff --git a/pkgs/racket-test/tests/racket/contract/set.rkt b/pkgs/racket-test/tests/racket/contract/set.rkt index c64b97e3df..a5a0c150d0 100644 --- a/pkgs/racket-test/tests/racket/contract/set.rkt +++ b/pkgs/racket-test/tests/racket/contract/set.rkt @@ -109,4 +109,112 @@ '(contract (set/c integer? #:kind 'mutable) (mutable-set 0) 'pos 'neg) - (contract-eval '(mutable-set 0)))) + (contract-eval '(mutable-set 0))) + + + (test/pos-blame + 'set/c17 + '(let () + (struct binary-set [integer] + #:transparent + #:methods gen:set + [(define (set-member? st i) + (bitwise-bit-set? (binary-set-integer st) i)) + (define (set-add st i) + (binary-set (bitwise-ior (binary-set-integer st) + (arithmetic-shift 1 i)))) + (define (set-remove st i) + (binary-set (bitwise-and (binary-set-integer st) + (bitwise-not (arithmetic-shift 1 i)))))]) + (contract (set/c integer?) + (binary-set 5) + 'pos 'neg))) + + (test/spec-passed + 'set/c19 + '(let () + (struct binary-set [integer] + #:transparent + #:methods gen:set + [(define (set-member? st i) + (bitwise-bit-set? (binary-set-integer st) i)) + (define (set-add st i) + (binary-set (bitwise-ior (binary-set-integer st) + (arithmetic-shift 1 i)))) + (define (set-remove st i) + (binary-set (bitwise-and (binary-set-integer st) + (bitwise-not (arithmetic-shift 1 i)))))]) + (contract (set/c integer? #:kind 'dont-care) + (binary-set 5) + 'pos 'neg))) + + (test/spec-passed + 'set/c20 + '(let () + (struct binary-set [integer] + #:transparent + #:methods gen:set + [(define (set-member? st i) + (bitwise-bit-set? (binary-set-integer st) i)) + (define (set-add st i) + (binary-set (bitwise-ior (binary-set-integer st) + (arithmetic-shift 1 i)))) + (define (set-remove st i) + (binary-set (bitwise-and (binary-set-integer st) + (bitwise-not (arithmetic-shift 1 i)))))]) + (contract (set/c boolean? #:kind 'dont-care #:lazy? #t) + (binary-set 5) + 'pos 'neg))) + + (test/spec-passed + 'set/c21 + '(let* ([c (set/c (-> integer? integer?))] + [s (contract c (set (λ (x) x)) 'pos 'neg)]) + (and (has-contract? s) + (equal? (value-contract s) c)))) + + (test/spec-passed + 'set/c22 + '(contract (set/c (-> integer? integer?) #:lazy? #t) + (set #f) 'pos 'neg)) + + (test/pos-blame + 'set/c23 + '(set-first + (contract (set/c (-> integer? integer?) #:lazy? #t) + (set #f) 'pos 'neg))) + + (test/pos-blame + 'set/c24 + '(contract (set/c (-> integer? integer?) #:lazy? #f) + (set #f) 'pos 'neg)) + + (test/spec-passed + 'set/c25 + '(contract (set/c integer? #:lazy? #t) + (set #f) 'pos 'neg)) + + (test/pos-blame + 'set/c26 + '(set-first + (contract (set/c integer? #:lazy? #t) + (set #f) 'pos 'neg))) + + (test/pos-blame + 'set/c27 + '(contract (set/c integer? #:lazy? #f) + (set #f) 'pos 'neg)) + + (test/neg-blame + 'set/c28 + '(let ([s (contract (set/c integer? #:lazy? #t) + (set #f) 'pos 'neg)]) + (set-add! s "x"))) + + (test/neg-blame + 'set/c29 + '(let ([s (contract (set/c integer? #:lazy? #f) + (set 0) 'pos 'neg)]) + (set-add! s "x"))) + + ) diff --git a/racket/collects/racket/set.rkt b/racket/collects/racket/set.rkt index 60c9eb9068..d039e34a1d 100644 --- a/racket/collects/racket/set.rkt +++ b/racket/collects/racket/set.rkt @@ -12,9 +12,14 @@ (all-from-out racket/private/set-types) set/c) -(define (set/c elem/c - #:cmp [cmp 'dont-care] - #:kind [kind 'immutable]) +(define/subexpression-pos-prop/name + real-set/c-name (set/c elem/c + #:cmp [cmp 'dont-care] + #:kind [kind 'immutable] + #:lazy? [_lazy? + (not (and (equal? kind 'immutable) + (flat-contract? elem/c)))]) + (define lazy? (and _lazy? #t)) (define cmp/c (case cmp [(dont-care) any/c] @@ -22,8 +27,8 @@ [(eqv) set-eqv?] [(eq) set-eq?] [else (raise-arguments-error 'set/c - "invalid #:cmp argument" - "#:cmp argument" cmp)])) + "invalid #:cmp argument" + "#:cmp argument" cmp)])) (define kind/c (case kind [(dont-care) any/c] @@ -47,14 +52,15 @@ (raise-argument-error 'set/c "chaperone-contract?" elem/c))]) (cond [(and (eq? kind 'immutable) + (not lazy?) (flat-contract? elem/c)) - (flat-set-contract elem/c cmp kind)] + (flat-set-contract elem/c cmp kind lazy?)] [(chaperone-contract? elem/c) - (chaperone-set-contract elem/c cmp kind)] + (chaperone-set-contract elem/c cmp kind lazy?)] [else - (impersonator-set-contract elem/c cmp kind)])) + (impersonator-set-contract elem/c cmp kind lazy?)])) -(struct set-contract [elem/c cmp kind]) +(struct set-contract [elem/c cmp kind lazy?]) (define (set-contract-name ctc) (define elem/c (set-contract-elem/c ctc)) @@ -66,7 +72,11 @@ `[#:cmp (quote ,cmp)]) ,@(if (eq? kind 'immutable) `[] - `[#:kind (quote ,kind)]))) + `[#:kind (quote ,kind)]) + ,@(if (equal? (set-contract-lazy? ctc) + (flat-contract? elem/c)) + '() + `(#:lazy? ,(set-contract-lazy? ctc))))) (define (set-contract-first-order ctc) (define cmp (set-contract-cmp ctc)) @@ -116,83 +126,153 @@ (define (set-contract-late-neg-projection chaperone-ctc?) (lambda (ctc) - (define elem/c (set-contract-elem/c ctc)) - (define cmp (set-contract-cmp ctc)) - (define kind (set-contract-kind ctc)) - (lambda (blame) - (define (method sym c) - (define name (contract-name c)) - (define str (format "method ~a with contract ~.s" sym name)) - (define b2 (blame-add-context blame str)) - ((contract-late-neg-projection c) b2)) - (define-syntax (redirect stx) - (syntax-case stx () - [(_ [id expr] ...) - (with-syntax ([(proj-id ...) (generate-temporaries #'(id ...))]) - #'(let ([proj-id (method 'id expr)] ...) - (λ (x neg-party) - (redirect-generics chaperone-ctc? - gen:set x [id (λ (x) (proj-id x neg-party))] ...))))])) - (define me (if chaperone-contract? - (make-chaperone-contract - #:name (set-contract-name ctc) - #:stronger set-contract-stronger - #:late-neg-projection - (λ (blame) (λ (val neg-party) (do-redirect val neg-party)))) - (make-contract - #:name (set-contract-name ctc) - #:stronger set-contract-stronger - #:late-neg-projection - (λ (blame) (λ (val neg-party) (do-redirect val neg-party)))))) - (define do-redirect - (redirect - [set-member? (-> generic-set? elem/c boolean?)] - [set-empty? (or/c (-> generic-set? boolean?) #f)] - [set-count (or/c (-> generic-set? exact-nonnegative-integer?) #f)] - [set=? (or/c (-> generic-set? me boolean?) #f)] - [subset? (or/c (-> generic-set? me boolean?) #f)] - [proper-subset? (or/c (-> generic-set? me boolean?) #f)] - [set-map (or/c (-> generic-set? (-> elem/c any/c) list?) #f)] - [set-for-each (or/c (-> generic-set? (-> elem/c any) void?) #f)] - [set-copy (or/c (-> generic-set? generic-set?) #f)] - [in-set (or/c (-> generic-set? sequence?) #f)] - [set->list (or/c (-> generic-set? (listof elem/c)) #f)] - [set->stream (or/c (-> generic-set? stream?) #f)] - [set-first (or/c (-> generic-set? elem/c) #f)] - [set-rest (or/c (-> generic-set? me) #f)] - [set-add (or/c (-> generic-set? elem/c me) #f)] - [set-remove (or/c (-> generic-set? elem/c me) #f)] - [set-clear (or/c (-> generic-set? me) #f)] - [set-copy-clear (or/c (-> generic-set? generic-set?) #f)] - [set-union - (or/c (->* [generic-set?] [] #:rest (listof me) me) #f)] - [set-intersect - (or/c (->* [generic-set?] [] #:rest (listof me) me) #f)] - [set-subtract - (or/c (->* [generic-set?] [] #:rest (listof me) me) #f)] - [set-symmetric-difference - (or/c (->* [generic-set?] [] #:rest (listof me) me) #f)] - [set-add! (or/c (-> generic-set? elem/c void?) #f)] - [set-remove! (or/c (-> generic-set? elem/c void?) #f)] - [set-clear! (or/c (-> generic-set? void?) #f)] - [set-union! - (or/c (->* [generic-set?] [] #:rest (listof me) void?) #f)] - [set-intersect! - (or/c (->* [generic-set?] [] #:rest (listof me) void?) #f)] - [set-subtract! - (or/c (->* [generic-set?] [] #:rest (listof me) void?) #f)] - [set-symmetric-difference! - (or/c (->* [generic-set?] [] #:rest (listof me) void?) #f)])) - (define proj - ((contract-projection elem/c) - (blame-add-context blame "an element of"))) - (lambda (x neg-party) - (set-contract-check cmp kind blame neg-party x) + (cond + [(allows-generic-sets? ctc) + (generic-set-late-neg-projection ctc chaperone-ctc?)] + [else + (hash-set-late-neg-projection ctc chaperone-ctc?)]))) + +(define (allows-generic-sets? ctc) + (and (equal? 'dont-care (set-contract-kind ctc)) + (equal? 'dont-care (set-contract-cmp ctc)))) + +(define (hash-set-late-neg-projection ctc chaperone-ctc?) + (define elem/c (set-contract-elem/c ctc)) + (define cmp (set-contract-cmp ctc)) + (define kind (set-contract-kind ctc)) + (define late-neg-ele-proj (contract-late-neg-projection elem/c)) + (define lazy? (set-contract-lazy? ctc)) + (λ (blame) + (define late-neg-pos-proj (late-neg-ele-proj (blame-add-element-context blame #f))) + (define late-neg-neg-proj (late-neg-ele-proj (blame-add-element-context blame #t))) + (define set/c-lazy-late-neg-proj + (λ (val neg-party) + (set-contract-check cmp kind blame neg-party val) + (define (pos-interpose val ele) (late-neg-pos-proj ele neg-party)) (cond - [(list? x) - (map proj x)] + [(set? val) + (chaperone-hash-set + val + pos-interpose + (λ (val ele) ele) + pos-interpose + impersonator-prop:contracted + ctc)] [else - (do-redirect x neg-party)]))))) + (chaperone-hash-set + val + pos-interpose + (λ (val ele) (late-neg-neg-proj ele neg-party)) + pos-interpose + impersonator-prop:contracted + ctc)]))) + (cond + [lazy? set/c-lazy-late-neg-proj] + [else + (λ (val neg-party) + (set-contract-check cmp kind blame neg-party val) + (define w/chaperone + (cond + [(set? val) val] + [else + (chaperone-hash-set + val + (λ (val ele) ele) + (λ (val ele) (late-neg-neg-proj ele neg-party)) + (λ (val ele) ele))])) + (chaperone-hash-set + (for/set ([ele (in-set w/chaperone)]) + (late-neg-pos-proj ele neg-party)) + (chaperone-hash-set + val + #f #f #f + impersonator-prop:contracted + ctc)))]))) + + +(define (generic-set-late-neg-projection ctc chaperone-ctc?) + (define elem/c (set-contract-elem/c ctc)) + (define cmp (set-contract-cmp ctc)) + (define kind (set-contract-kind ctc)) + (define lazy? (set-contract-lazy? ctc)) + (lambda (blame) + (define (method sym c) + (define name (contract-name c)) + (define str (format "method ~a with contract ~.s" sym name)) + (define b2 (blame-add-context blame str)) + ((contract-late-neg-projection c) b2)) + (define-syntax (redirect stx) + (syntax-case stx () + [(_ [id expr] ...) + (with-syntax ([(proj-id ...) (generate-temporaries #'(id ...))]) + #'(let ([proj-id (method 'id expr)] ...) + (λ (x neg-party) + (redirect-generics chaperone-ctc? + gen:set x [id (λ (x) (proj-id x neg-party))] ...))))])) + (define me (if chaperone-contract? + (make-chaperone-contract + #:name (set-contract-name ctc) + #:stronger set-contract-stronger + #:late-neg-projection + (λ (blame) (λ (val neg-party) (do-redirect val neg-party)))) + (make-contract + #:name (set-contract-name ctc) + #:stronger set-contract-stronger + #:late-neg-projection + (λ (blame) (λ (val neg-party) (do-redirect val neg-party)))))) + (define do-redirect + (redirect + [set-member? (-> generic-set? elem/c boolean?)] + [set-empty? (or/c (-> generic-set? boolean?) #f)] + [set-count (or/c (-> generic-set? exact-nonnegative-integer?) #f)] + [set=? (or/c (-> generic-set? me boolean?) #f)] + [subset? (or/c (-> generic-set? me boolean?) #f)] + [proper-subset? (or/c (-> generic-set? me boolean?) #f)] + [set-map (or/c (-> generic-set? (-> elem/c any/c) list?) #f)] + [set-for-each (or/c (-> generic-set? (-> elem/c any) void?) #f)] + [set-copy (or/c (-> generic-set? generic-set?) #f)] + [in-set (or/c (-> generic-set? sequence?) #f)] + [set->list (or/c (-> generic-set? (listof elem/c)) #f)] + [set->stream (or/c (-> generic-set? stream?) #f)] + [set-first (or/c (-> generic-set? elem/c) #f)] + [set-rest (or/c (-> generic-set? me) #f)] + [set-add (or/c (-> generic-set? elem/c me) #f)] + [set-remove (or/c (-> generic-set? elem/c me) #f)] + [set-clear (or/c (-> generic-set? me) #f)] + [set-copy-clear (or/c (-> generic-set? generic-set?) #f)] + [set-union + (or/c (->* [generic-set?] [] #:rest (listof me) me) #f)] + [set-intersect + (or/c (->* [generic-set?] [] #:rest (listof me) me) #f)] + [set-subtract + (or/c (->* [generic-set?] [] #:rest (listof me) me) #f)] + [set-symmetric-difference + (or/c (->* [generic-set?] [] #:rest (listof me) me) #f)] + [set-add! (or/c (-> generic-set? elem/c void?) #f)] + [set-remove! (or/c (-> generic-set? elem/c void?) #f)] + [set-clear! (or/c (-> generic-set? void?) #f)] + [set-union! + (or/c (->* [generic-set?] [] #:rest (listof me) void?) #f)] + [set-intersect! + (or/c (->* [generic-set?] [] #:rest (listof me) void?) #f)] + [set-subtract! + (or/c (->* [generic-set?] [] #:rest (listof me) void?) #f)] + [set-symmetric-difference! + (or/c (->* [generic-set?] [] #:rest (listof me) void?) #f)])) + (define proj + ((contract-late-neg-projection elem/c) (blame-add-element-context blame #f))) + (lambda (x neg-party) + (set-contract-check cmp kind blame neg-party x) + (cond + [(list? x) + (for/list ([e (in-list x)]) + (proj e neg-party))] + [else + (do-redirect x neg-party)])))) + + +(define (blame-add-element-context blame swap?) + (blame-add-context blame "an element of" #:swap? swap?)) (define (flat-set-contract-first-order ctc) (define set-passes? (set-contract-first-order ctc)) @@ -206,10 +286,9 @@ (define elem/c (set-contract-elem/c ctc)) (define cmp (set-contract-cmp ctc)) (define kind (set-contract-kind ctc)) + (define mk-elem/c-proj (contract-late-neg-projection elem/c)) (lambda (b) - (define proj - ((contract-late-neg-projection elem/c) - (blame-add-context b "an element of"))) + (define proj (mk-elem/c-proj (blame-add-context b "an element of"))) (lambda (x neg-party) (set-contract-check cmp kind b neg-party x) (for ([e (in-set x)]) From afa01fa7633ad4a81a8aecf50d4d5fb55db9a0d9 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 25 Dec 2015 20:14:13 -0600 Subject: [PATCH 246/369] allow optimizations around `procedure-specialize` Although `procedure-specialize` should be useful in places where inlining does not apply, allowing inlining and related optimizations through it, anyway. --- .../tests/racket/optimize.rktl | 22 ++++++++++++++++++ racket/src/racket/src/fun.c | 14 +++++++---- racket/src/racket/src/optimize.c | 23 +++++++++++++++++++ racket/src/racket/src/schpriv.h | 1 + 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index f1eb1b85a4..4a67138c57 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -1922,6 +1922,28 @@ (define (g y) (+ y 1)))) + +(test-comp '(let () + (define (f x) + (procedure-specialize + (lambda (y) (+ x y)))) + ((f 10) 12)) + '22) + +(test-comp '(let () + (define (f x) + (procedure-specialize + (lambda (y) (+ x y)))) + (procedure? (f 10))) + '#t) + +(test-comp '(let ([f (procedure-specialize + (lambda (y) (+ 1 y)))]) + (list f (procedure-arity-includes? f 1))) + '(let ([f (procedure-specialize + (lambda (y) (+ 1 y)))]) + (list f #t))) + (test-comp '(values 10) 10) (test-comp '(let ([x (values 10)]) diff --git a/racket/src/racket/src/fun.c b/racket/src/racket/src/fun.c index b1aff09b65..f28ba52c48 100644 --- a/racket/src/racket/src/fun.c +++ b/racket/src/racket/src/fun.c @@ -79,6 +79,7 @@ READ_ONLY Scheme_Object scheme_void[1]; /* the void constant */ READ_ONLY Scheme_Object *scheme_values_func; /* the function bound to `values' */ READ_ONLY Scheme_Object *scheme_procedure_p_proc; READ_ONLY Scheme_Object *scheme_procedure_arity_includes_proc; +READ_ONLY Scheme_Object *scheme_procedure_specialize_proc; READ_ONLY Scheme_Object *scheme_void_proc; READ_ONLY Scheme_Object *scheme_void_p_proc; READ_ONLY Scheme_Object *scheme_check_not_undefined_proc; @@ -594,11 +595,14 @@ scheme_init_fun (Scheme_Env *env) "procedure-closure-contents-eq?", 2, 2, 1), env); - scheme_add_global_constant("procedure-specialize", - scheme_make_prim_w_arity(procedure_specialize, - "procedure-specialize", - 1, 1), - env); + + REGISTER_SO(scheme_procedure_specialize_proc); + o = scheme_make_prim_w_arity(procedure_specialize, + "procedure-specialize", + 1, 1); + scheme_procedure_specialize_proc = o; + scheme_add_global_constant("procedure-specialize", o, env); + scheme_add_global_constant("chaperone-procedure", scheme_make_prim_w_arity(chaperone_procedure, "chaperone-procedure", diff --git a/racket/src/racket/src/optimize.c b/racket/src/racket/src/optimize.c index 8040c496e5..6457f0f9e6 100644 --- a/racket/src/racket/src/optimize.c +++ b/racket/src/racket/src/optimize.c @@ -289,6 +289,19 @@ static void note_match(int actual, int expected, Optimize_Info *warn_info) } } +static Scheme_Object *extract_specialized_proc(Scheme_Object *le, Scheme_Object *default_val) +{ + if (SAME_TYPE(SCHEME_TYPE(le), scheme_application2_type)) { + Scheme_App2_Rec *app = (Scheme_App2_Rec *)le; + if (SAME_OBJ(app->rator, scheme_procedure_specialize_proc)) { + if (SCHEME_PROCP(app->rand) || IS_COMPILED_PROC(app->rand)) + return app->rand; + } + } + + return default_val; +} + int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved, Optimize_Info *opt_info, Optimize_Info *warn_info, int min_id_depth, int id_offset, int no_id) @@ -469,6 +482,9 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved, && (SCHEME_INT_VAL(app->rand) >= 0)) && IN_FIXNUM_RANGE_ON_ALL_PLATFORMS(SCHEME_INT_VAL(app->rand))) { return 1; + } else if (SAME_OBJ(app->rator, scheme_procedure_specialize_proc)) { + if ((vals == 1 || vals == -1) && extract_specialized_proc(o, NULL)) + return 1; } else if (SCHEME_PRIMP(app->rator)) { if (!(SCHEME_PRIM_PROC_FLAGS(app->rator) & SCHEME_PRIM_IS_MULTI_RESULT) || SAME_OBJ(scheme_values_func, app->rator)) { @@ -1775,6 +1791,8 @@ Scheme_Object *optimize_for_inline(Optimize_Info *info, Scheme_Object *le, int a if (already_opt) extract_tail_inside(&le, &prev, &id_offset); + le = extract_specialized_proc(le, le); + if (SAME_TYPE(SCHEME_TYPE(le), scheme_compiled_unclosed_procedure_type)) { /* Found a `((lambda' */ single_use = 1; @@ -2480,6 +2498,8 @@ static Scheme_Object *rator_implies_predicate(Scheme_Object *rator, int argc) return scheme_box_p_proc; else if (SAME_OBJ(rator, scheme_void_proc)) return scheme_void_p_proc; + else if (SAME_OBJ(rator, scheme_procedure_specialize_proc)) + return scheme_procedure_p_proc; { Scheme_Object *p; @@ -6393,6 +6413,9 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline, i } } + if (value) + value = extract_specialized_proc(value, value); + if (value && (scheme_compiled_propagate_ok(value, body_info))) { int cnt; diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index f1ea327d3a..a4ed95e79e 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -455,6 +455,7 @@ extern Scheme_Object *scheme_apply_proc; extern Scheme_Object *scheme_values_func; extern Scheme_Object *scheme_procedure_p_proc; extern Scheme_Object *scheme_procedure_arity_includes_proc; +extern Scheme_Object *scheme_procedure_specialize_proc; extern Scheme_Object *scheme_void_proc; extern Scheme_Object *scheme_void_p_proc; extern Scheme_Object *scheme_syntax_p_proc; From cefcbdf8022ca60fcfa3b6b8d95b14b6fd99f73d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 28 Dec 2015 06:17:15 -0700 Subject: [PATCH 247/369] Windows: ensure 'kill subprocesses end with Racket Use a job object to ensure that subprocesses that are meant to be killed by the current custodian are reliably terminated if Racket exits for any reason. --- racket/src/racket/include/schthread.h | 2 ++ racket/src/racket/src/env.c | 4 +++ racket/src/racket/src/port.c | 37 ++++++++++++++++++++++++--- racket/src/racket/src/schpriv.h | 1 + 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/racket/src/racket/include/schthread.h b/racket/src/racket/include/schthread.h index 817f6a3c3e..2bf55034d5 100644 --- a/racket/src/racket/include/schthread.h +++ b/racket/src/racket/include/schthread.h @@ -202,6 +202,7 @@ typedef struct Thread_Local_Variables { struct Scheme_Custodian *new_port_cust_; #if (defined(__WIN32__) || defined(WIN32) || defined(_WIN32)) void *scheme_break_semaphore_; + void *process_job_object_; #else int external_event_fd_; int put_external_event_fd_; @@ -598,6 +599,7 @@ XFORM_GC_VARIABLE_STACK_THROUGH_THREAD_LOCAL; #define locked_fd_process_map XOA (scheme_get_thread_local_variables()->locked_fd_process_map_) #define new_port_cust XOA (scheme_get_thread_local_variables()->new_port_cust_) #define scheme_break_semaphore XOA (scheme_get_thread_local_variables()->scheme_break_semaphore_) +#define process_job_object XOA (scheme_get_thread_local_variables()->process_job_object_) #define external_event_fd XOA (scheme_get_thread_local_variables()->external_event_fd_) #define put_external_event_fd XOA (scheme_get_thread_local_variables()->put_external_event_fd_) #define read_string_byte_buffer XOA (scheme_get_thread_local_variables()->read_string_byte_buffer_) diff --git a/racket/src/racket/src/env.c b/racket/src/racket/src/env.c index 6c4a9730b8..6b91ab4701 100644 --- a/racket/src/racket/src/env.c +++ b/racket/src/racket/src/env.c @@ -656,6 +656,10 @@ void scheme_place_instance_destroy(int force) else scheme_run_atexit_closers_on_all(force_more_closed_after); +#ifdef WINDOWS_PROCESSES + scheme_release_process_job_object(); +#endif + scheme_release_file_descriptor(); scheme_end_futures_per_place(); diff --git a/racket/src/racket/src/port.c b/racket/src/racket/src/port.c index 44d3c0e930..c5202e4205 100644 --- a/racket/src/racket/src/port.c +++ b/racket/src/racket/src/port.c @@ -9417,6 +9417,17 @@ static Scheme_Object *do_subprocess_kill(Scheme_Object *_sp, Scheme_Object *kill return NULL; } +#ifdef WINDOWS_PROCESSES +void scheme_release_process_job_object(void) +{ + if (process_job_object) { + TerminateJobObject((HANDLE)process_job_object, 1); + CloseHandle((HANDLE)process_job_object); + process_job_object = NULL; + } +} +#endif + static void kill_subproc(Scheme_Object *o, void *data) { (void)do_subprocess_kill(o, scheme_true, 0); @@ -9569,10 +9580,10 @@ static char *cmdline_protect(char *s) static intptr_t mz_spawnv(char *command, const char * const *argv, int exact_cmdline, intptr_t sin, intptr_t sout, intptr_t serr, int *pid, - int new_process_group, + int new_process_group, Scheme_Object *cust_mode, void *env, char *wd) { - int i, l, len = 0; + int i, l, len = 0, use_jo; intptr_t cr_flag; char *cmdline; STARTUPINFOW startup; @@ -9617,10 +9628,30 @@ static intptr_t mz_spawnv(char *command, const char * const *argv, cr_flag |= CREATE_NEW_PROCESS_GROUP; cr_flag |= CREATE_UNICODE_ENVIRONMENT; + use_jo = SCHEME_SYMBOLP(cust_mode) && !strcmp(SCHEME_SYM_VAL(cust_mode), "kill"); + if (use_jo) { + /* Use a job object to ensure that the new process will be terminated + if this process ends for any reason (including a crash) */ + if (!process_job_object) { + GC_CAN_IGNORE JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli; + + process_job_object = (void*)CreateJobObject(NULL, NULL); + + memset(&jeli, 0, sizeof(jeli)); + jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + SetInformationJobObject((HANDLE)process_job_object, + JobObjectExtendedLimitInformation, + &jeli, + sizeof(jeli)); + } + } + if (CreateProcessW(WIDE_PATH_COPY(command), WIDE_PATH_COPY(cmdline), NULL, NULL, 1 /*inherit*/, cr_flag, env, WIDE_PATH_COPY(wd), &startup, &info)) { + if (use_jo) + AssignProcessToJobObject((HANDLE)process_job_object, info.hProcess); CloseHandle(info.hThread); *pid = info.dwProcessId; return (intptr_t)info.hProcess; @@ -9952,7 +9983,7 @@ static Scheme_Object *subprocess(int c, Scheme_Object *args[]) from_subprocess[1], err_subprocess[1], &pid, - new_process_group, + new_process_group, cust_mode, env, SCHEME_BYTE_STR_VAL(tcd)); if (spawn_status != -1) diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index a4ed95e79e..b536986f5d 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -417,6 +417,7 @@ void scheme_init_exn_config(void); #endif #ifdef WINDOWS_PROCESSES void scheme_init_thread_memory(void); +void scheme_release_process_job_object(void); #endif void scheme_init_module_resolver(void); From e08188aeda8c419b741313ef34ef0e49ac6eb6a4 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 28 Dec 2015 07:37:04 -0600 Subject: [PATCH 248/369] add source for "racket-playsound.exe" --- racket/src/native-libs/README.txt | 3 +++ racket/src/native-libs/playsound.c | 10 ++++++++++ 2 files changed, 13 insertions(+) create mode 100644 racket/src/native-libs/playsound.c diff --git a/racket/src/native-libs/README.txt b/racket/src/native-libs/README.txt index 8d174f7e68..5ce71afdc7 100644 --- a/racket/src/native-libs/README.txt +++ b/racket/src/native-libs/README.txt @@ -155,6 +155,9 @@ More details for Windows: uses `-static-libgcc' and `-static-libstdc++' to statically link those libraries. Use "depends.exe" to check DLL dependencies. + * The extra "playsound.c" program is meant to be compiled to + "racket-playsound.exe" for the "gui" library. + More details for Mac OS X: * 32-bit binaries are built for 10.5 and up. 64-bit binaries are diff --git a/racket/src/native-libs/playsound.c b/racket/src/native-libs/playsound.c new file mode 100644 index 0000000000..329fb3b50f --- /dev/null +++ b/racket/src/native-libs/playsound.c @@ -0,0 +1,10 @@ +#include + +/* Doesn't attempt to parse the command line in the usual way. + Instead, the whole command-line is used as a path of a + sound file to play. */ + +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR ignored, int nCmdShow) +{ + return PlaySoundW(GetCommandLineW(), NULL, SND_SYNC); +} From 50405a2ca97f814612500649561d57c80ef02a15 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 28 Dec 2015 16:58:08 -0600 Subject: [PATCH 249/369] fix chaperone-hash-set and impersonate-hash-set for custom-set-types --- pkgs/racket-test-core/tests/racket/set.rktl | 31 ++++++ racket/collects/racket/private/set-types.rkt | 102 ++++++++++++++----- 2 files changed, 109 insertions(+), 24 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/set.rktl b/pkgs/racket-test-core/tests/racket/set.rktl index 6270e66779..b01efb26aa 100644 --- a/pkgs/racket-test-core/tests/racket/set.rktl +++ b/pkgs/racket-test-core/tests/racket/set.rktl @@ -636,6 +636,37 @@ (λ (s e) (+ e 1)) (λ (s l) l) (λ (s l) l)))) + +(test #t zero? + (let ([ele #f]) + (set-first (impersonate-hash-set (weak-set 0) + (λ (s e) (set! ele e)) + (λ (s l) l) + (λ (s l) l))) + ele)) +(test #t zero? + (let ([ele #f]) + (define-custom-set-types set2 equal? equal-hash-code) + (define ele #f) + (set-first + (chaperone-hash-set (set-add (make-immutable-set2) 0) + (λ (s e) (set! ele e) e) + (λ (s l) l) + (λ (s l) l))) + ele)) +(test #t zero? + (let ([ele #f]) + (define-custom-set-types set2 equal? equal-hash-code) + (define ele #f) + (define s (make-weak-set2)) + (set-add! s 0) + (set-first + (impersonate-hash-set s + (λ (s e) (set! ele e) e) + (λ (s l) l) + (λ (s l) l))) + ele)) + (let-values ([(impersonator-prop:p has-impersonator-prop:p? get-impersonator-prop:p) (make-impersonator-property 'p)]) (let ([s (chaperone-hash-set (set) (λ (s l) l) (λ (s l) l) (λ (s l) l) impersonator-prop:p 11)]) diff --git a/racket/collects/racket/private/set-types.rkt b/racket/collects/racket/private/set-types.rkt index 4a0539060d..823a37c57f 100644 --- a/racket/collects/racket/private/set-types.rkt +++ b/racket/collects/racket/private/set-types.rkt @@ -357,24 +357,67 @@ "~s did not return a chaperone of ~e, got ~e" who original new)) new) + + (define (chaperone-hash-set-hash-ref-proc hash key) + (values (check-it 'ref-proc key (ref-proc (update-custom-set-table s hash) key)) + (λ (hash key val) val))) + (define (chaperone-hash-set-hash-set-proc hash key val) + (values (check-it 'add-proc key (add-proc (update-custom-set-table s hash) key)) + val)) + (define (chaperone-hash-set-hash-remove-proc hash key) + (check-it 'remove-proc key (remove-proc (update-custom-set-table s hash) key))) + (define (chaperone-hash-set-hash-key-proc hash key) + (check-it 'ref-proc key (ref-proc (update-custom-set-table s hash) key))) + (define chaperone-hash-set-hash-clear-proc + (and clear-proc (λ (hash) (clear-proc (update-custom-set-table s hash))))) (add-impersonator-properties (if ref-proc - (update-custom-set-table - s - (chaperone-hash - (custom-set-table s) - (λ (hash key) - (values (check-it 'ref-proc key (ref-proc (update-custom-set-table s hash) key)) - (λ (hash key val) val))) - (λ (hash key val) - (values (check-it 'add-proc key (add-proc (update-custom-set-table s hash) key)) - val)) - (λ (hash key) (check-it 'remove-proc key (remove-proc (update-custom-set-table s hash) key))) - (λ (hash key) (check-it 'ref-proc key (ref-proc (update-custom-set-table s hash) key))) - (and clear-proc (λ (hash) (clear-proc (update-custom-set-table s hash)))))) + (chap-or-imp-hash-set s + chaperone-hash + chaperone-hash-set-hash-ref-proc + chaperone-hash-set-hash-set-proc + chaperone-hash-set-hash-remove-proc + chaperone-hash-set-hash-key-proc + chaperone-hash-set-hash-clear-proc) s) prop-args)) +(define (chap-or-imp-hash-set s + chaperone-or-impersonate-hash + c/i-hash-set-hash-ref-proc + c/i-hash-set-hash-set-proc + c/i-hash-set-hash-remove-proc + c/i-hash-set-hash-key-proc + c/i-hash-set-hash-clear-proc) + (define rewrap + (and (custom-set-spec s) + (custom-spec-wrap (custom-set-spec s)))) + (update-custom-set-table + s + (if (custom-set-spec s) + (chaperone-or-impersonate-hash + (custom-set-table s) + (λ (hash key) + (define-values (a b) + (c/i-hash-set-hash-ref-proc hash (custom-elem-contents key))) + (values (rewrap a) b)) + (λ (hash key val) + (define-values (a b) + (c/i-hash-set-hash-set-proc hash key (custom-elem-contents key))) + (values (rewrap a) b)) + (λ (hash key) + (rewrap (c/i-hash-set-hash-remove-proc hash (custom-elem-contents key)))) + (λ (hash key) + (rewrap (c/i-hash-set-hash-key-proc hash (custom-elem-contents key)))) + c/i-hash-set-hash-clear-proc) + (chaperone-or-impersonate-hash + (custom-set-table s) + c/i-hash-set-hash-ref-proc + c/i-hash-set-hash-set-proc + c/i-hash-set-hash-remove-proc + c/i-hash-set-hash-key-proc + c/i-hash-set-hash-clear-proc)))) + (define (impersonate-hash-set s ref-proc add-proc @@ -388,18 +431,29 @@ add-proc remove-proc clear-proc+props)) + (define impersonate-hash-set-hash-ref-proc + (λ (hash key) (values (ref-proc (update-custom-set-table s hash) key) + (λ (hash key val) val)))) + (define impersonate-hash-set-hash-set-proc + (λ (hash key val) (values (add-proc (update-custom-set-table s hash) key) val))) + (define impersonate-hash-set-hash-remove-proc + (λ (hash key) (remove-proc (update-custom-set-table s hash) key))) + (define impersonate-hash-set-hash-key-proc + (λ (hash key) (ref-proc (update-custom-set-table s hash) key))) + (define impersonate-hash-set-hash-clear-proc + (and clear-proc (λ (hash) (clear-proc (update-custom-set-table s hash))))) + (define rewrap + (and (custom-set-spec s) + (custom-spec-wrap (custom-set-spec s)))) (add-impersonator-properties (if ref-proc - (update-custom-set-table - s - (impersonate-hash - (custom-set-table s) - (λ (hash key) (values (ref-proc (update-custom-set-table s hash) key) - (λ (hash key val) val))) - (λ (hash key val) (values (add-proc (update-custom-set-table s hash) key) val)) - (λ (hash key) (remove-proc (update-custom-set-table s hash) key)) - (λ (hash key) (ref-proc (update-custom-set-table s hash) key)) - (and clear-proc (λ (hash) (clear-proc (update-custom-set-table s hash)))))) + (chap-or-imp-hash-set s + impersonate-hash + impersonate-hash-set-hash-ref-proc + impersonate-hash-set-hash-set-proc + impersonate-hash-set-hash-remove-proc + impersonate-hash-set-hash-key-proc + impersonate-hash-set-hash-clear-proc) s) prop-args)) @@ -547,7 +601,7 @@ (sequence-map custom-elem-contents keys) keys)) -(struct custom-elem [contents]) +(struct custom-elem [contents] #:transparent) (struct custom-spec [elem? wrap intern]) From ff31b015051c28d9ecc843854c22081b43fdf28a Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 28 Dec 2015 16:58:35 -0600 Subject: [PATCH 250/369] add some error checking for custom set type constructors --- racket/collects/racket/private/set-types.rkt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/racket/collects/racket/private/set-types.rkt b/racket/collects/racket/private/set-types.rkt index 823a37c57f..a9c3ee96bf 100644 --- a/racket/collects/racket/private/set-types.rkt +++ b/racket/collects/racket/private/set-types.rkt @@ -866,6 +866,8 @@ (define (immutable-custom-set-maker spec name) (define (proc [st '()]) + (unless (stream? st) + (raise-argument-error name "stream?" st)) (dprintf "~a\n" name) (define table (for/fold ([table (make-immutable-hash)]) ([x (in-stream st)]) @@ -876,6 +878,8 @@ (define (imperative-custom-set-maker spec name make-table make-set) (define (proc [st '()]) + (unless (stream? st) + (raise-argument-error name "stream?" st)) (dprintf "~a\n" name) (define table (make-table)) (for ([x (in-stream st)]) From f7465f81f1ebf9e0e403f329e0f164aac25a0292 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 28 Dec 2015 21:52:56 -0600 Subject: [PATCH 251/369] convert stream/c to late-neg-projection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also, tune the projection to get a few modest performance gains. This program gets about 20% faster: #lang racket (define s (contract (stream/c exact-nonnegative-integer?) (in-naturals) 'pos 'neg)) (time (for ([x (in-range 1000)]) (for/fold ([s s]) ([x (in-range 100)]) (stream-rest s)))) and this program gets about 15% faster: #lang racket (define f (contract (-> (stream/c exact-nonnegative-integer?) any) (λ (x) 1) 'pos 'neg)) (define l (make-list 10000 0)) (time (for ([x (in-range 1000)]) (f l) (f l) (f l) (f l) (f l))) --- racket/collects/racket/stream.rkt | 61 ++++++++++++++++--------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/racket/collects/racket/stream.rkt b/racket/collects/racket/stream.rkt index 18d0b17bf7..a2d9220c78 100644 --- a/racket/collects/racket/stream.rkt +++ b/racket/collects/racket/stream.rkt @@ -240,45 +240,46 @@ (define (add-stream-context blame) (blame-add-context blame "a value generated by")) -(define (check-stream/c ctc val blame) - (unless (stream? val) - (raise-blame-error blame val '(expected "a stream" given: "~e") val))) - (define (stream/c-stronger? a b) (contract-stronger? (base-stream/c-content a) (base-stream/c-content b))) -; streams are lazy, so we need to contract the rest of the stream lazily (which can be a list) -(define (contract-stream-rest v ctc blame) +(define ((late-neg-projection impersonate/chaperone-stream) ctc) (define elem-ctc (base-stream/c-content ctc)) - (define new-ctc (if (list? v) (listof elem-ctc) ctc)) - (((contract-projection new-ctc) blame) v)) - -(define ((ho-projection impersonate/chaperone-stream) ctc) - (let ([elem-ctc (base-stream/c-content ctc)]) - (λ (blame) - (define stream-blame (add-stream-context blame)) - (define pos-elem-proj ((contract-projection elem-ctc) stream-blame)) - (λ (val) - (check-stream/c ctc val stream-blame) - (if (list? val) - (contract-stream-rest val ctc stream-blame) - (impersonate/chaperone-stream - val - (λ (v) (pos-elem-proj v)) - (λ (v) (contract-stream-rest v ctc stream-blame)) - impersonator-prop:contracted ctc - impersonator-prop:blame stream-blame)))))) + (define listof-elem-ctc (listof elem-ctc)) + (define elem-ctc-late-neg (get/build-late-neg-projection elem-ctc)) + (define listof-elem-ctc-late-neg (get/build-late-neg-projection listof-elem-ctc)) + (λ (blame) + (define stream-blame (add-stream-context blame)) + (define elem-ctc-late-neg-acceptor (elem-ctc-late-neg stream-blame)) + (define listof-elem-ctc-neg-acceptor (listof-elem-ctc-late-neg stream-blame)) + (define (stream/c-late-neg-proj-val-acceptor val neg-party) + (unless (stream? val) + (raise-blame-error blame #:missing-party neg-party + val '(expected "a stream" given: "~e") val)) + (if (list? val) + (listof-elem-ctc-neg-acceptor val neg-party) + (impersonate/chaperone-stream + val + (λ (v) (elem-ctc-late-neg-acceptor v neg-party)) + (λ (v) + (if (list? v) + (listof-elem-ctc-neg-acceptor v neg-party) + (stream/c-late-neg-proj-val-acceptor v neg-party))) + impersonator-prop:contracted ctc + impersonator-prop:blame stream-blame))) + stream/c-late-neg-proj-val-acceptor)) (struct base-stream/c (content)) (struct chaperone-stream/c base-stream/c () #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract - (build-chaperone-contract-property - #:name stream/c-name - #:first-order stream? - #:stronger stream/c-stronger? - #:projection (ho-projection chaperone-stream))) + (parameterize ([skip-projection-wrapper? #t]) + (build-chaperone-contract-property + #:name stream/c-name + #:first-order stream? + #:stronger stream/c-stronger? + #:late-neg-projection (late-neg-projection chaperone-stream)))) (struct impersonator-stream/c base-stream/c () #:property prop:custom-write custom-write-property-proc @@ -287,7 +288,7 @@ #:name stream/c-name #:first-order stream? #:stronger stream/c-stronger? - #:projection (ho-projection impersonate-stream))) + #:late-neg-projection (late-neg-projection impersonate-stream))) (define (stream/c elem) (define ctc (coerce-contract 'stream/c elem)) From a44ce40b5658b1b79cb9f9b1446413feb972df3a Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 28 Dec 2015 22:17:39 -0600 Subject: [PATCH 252/369] fix a bug in 50405a2ca --- pkgs/racket-test-core/tests/racket/set.rktl | 11 +++++++++++ racket/collects/racket/private/set-types.rkt | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test-core/tests/racket/set.rktl b/pkgs/racket-test-core/tests/racket/set.rktl index b01efb26aa..084d8fd574 100644 --- a/pkgs/racket-test-core/tests/racket/set.rktl +++ b/pkgs/racket-test-core/tests/racket/set.rktl @@ -667,6 +667,17 @@ (λ (s l) l))) ele)) +(test #t zero? + (let () + (define-custom-set-types set2 equal? equal-hash-code) + (set-first + (set-add (chaperone-hash-set + (make-immutable-set2) + (λ (a b) b) + (λ (a b) b) + (λ (a b) b)) + 0)))) + (let-values ([(impersonator-prop:p has-impersonator-prop:p? get-impersonator-prop:p) (make-impersonator-property 'p)]) (let ([s (chaperone-hash-set (set) (λ (s l) l) (λ (s l) l) (λ (s l) l) impersonator-prop:p 11)]) diff --git a/racket/collects/racket/private/set-types.rkt b/racket/collects/racket/private/set-types.rkt index a9c3ee96bf..ca6c3af38c 100644 --- a/racket/collects/racket/private/set-types.rkt +++ b/racket/collects/racket/private/set-types.rkt @@ -403,7 +403,7 @@ (values (rewrap a) b)) (λ (hash key val) (define-values (a b) - (c/i-hash-set-hash-set-proc hash key (custom-elem-contents key))) + (c/i-hash-set-hash-set-proc hash (custom-elem-contents key) val)) (values (rewrap a) b)) (λ (hash key) (rewrap (c/i-hash-set-hash-remove-proc hash (custom-elem-contents key)))) From d4ca8256407d6e367c65c0ed3f5832595b72ecec Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 29 Dec 2015 06:56:20 -0600 Subject: [PATCH 253/369] fix set/c name method --- racket/collects/racket/set.rkt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/racket/collects/racket/set.rkt b/racket/collects/racket/set.rkt index d039e34a1d..ea4ccc1a37 100644 --- a/racket/collects/racket/set.rkt +++ b/racket/collects/racket/set.rkt @@ -16,9 +16,7 @@ real-set/c-name (set/c elem/c #:cmp [cmp 'dont-care] #:kind [kind 'immutable] - #:lazy? [_lazy? - (not (and (equal? kind 'immutable) - (flat-contract? elem/c)))]) + #:lazy? [_lazy? (lazy-default kind elem/c)]) (define lazy? (and _lazy? #t)) (define cmp/c (case cmp @@ -62,6 +60,10 @@ (struct set-contract [elem/c cmp kind lazy?]) +(define (lazy-default kind elem/c) + (not (and (equal? kind 'immutable) + (flat-contract? elem/c)))) + (define (set-contract-name ctc) (define elem/c (set-contract-elem/c ctc)) (define cmp (set-contract-cmp ctc)) @@ -74,7 +76,7 @@ `[] `[#:kind (quote ,kind)]) ,@(if (equal? (set-contract-lazy? ctc) - (flat-contract? elem/c)) + (lazy-default kind elem/c)) '() `(#:lazy? ,(set-contract-lazy? ctc))))) From 26560240f15085d2a884cbc973043dc2235b076d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 28 Dec 2015 10:14:30 -0600 Subject: [PATCH 254/369] adjust "racket-playsound.exe" return code --- racket/src/native-libs/playsound.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/src/native-libs/playsound.c b/racket/src/native-libs/playsound.c index 329fb3b50f..8b3cce47b8 100644 --- a/racket/src/native-libs/playsound.c +++ b/racket/src/native-libs/playsound.c @@ -6,5 +6,5 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR ignored, int nCmdShow) { - return PlaySoundW(GetCommandLineW(), NULL, SND_SYNC); + return !PlaySoundW(GetCommandLineW(), NULL, SND_SYNC | SND_NODEFAULT); } From a516304f6b3d7469399dc5402fe68397460be41a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 29 Dec 2015 07:01:57 -0600 Subject: [PATCH 255/369] fix specialization over a nested `lambda` --- .../tests/racket/optimize.rktl | 21 +++++++++++++ racket/src/racket/src/jit.c | 30 +++++++++++++------ racket/src/racket/src/jit.h | 2 +- racket/src/racket/src/jitcall.c | 2 +- racket/src/racket/src/jitinline.c | 4 +-- racket/src/racket/src/jitstate.c | 13 ++++---- 6 files changed, 52 insertions(+), 20 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index 4a67138c57..1aa59ed2a5 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -5064,6 +5064,27 @@ (dup rep)))) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check specialization with a capturing lambda: + +(let () + (define (f x) + (procedure-specialize + (lambda (y) + (lambda () (+ x y))))) + (set! f f) + (test 11 ((f 10) 1))) + + +(let () + (define (f x) + (set! x (add1 x)) + (procedure-specialize + (lambda (y) + (lambda () (+ x y))))) + (set! f f) + (test 12 ((f 10) 1))) + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/racket/src/racket/src/jit.c b/racket/src/racket/src/jit.c index 82f68277da..52b8c9704d 100644 --- a/racket/src/racket/src/jit.c +++ b/racket/src/racket/src/jit.c @@ -1275,7 +1275,7 @@ static int generate_closure(Scheme_Closure_Data *data, jit_movi_l(JIT_R1, init_word); jit_str_l(JIT_R0, JIT_R1); } - scheme_mz_load_retained(jitter, JIT_R1, code, 0); + scheme_mz_load_retained(jitter, JIT_R1, code); jit_stxi_p((intptr_t)&((Scheme_Native_Closure *)0x0)->code, JIT_R0, JIT_R1); return 1; @@ -1285,7 +1285,7 @@ static int generate_closure(Scheme_Closure_Data *data, JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); mz_prepare(1); - scheme_mz_load_retained(jitter, JIT_R0, code, 0); + scheme_mz_load_retained(jitter, JIT_R0, code); jit_pusharg_p(JIT_R0); { GC_CAN_IGNORE jit_insn *refr USED_ONLY_FOR_FUTURES; @@ -1302,13 +1302,25 @@ static int generate_closure_fill(Scheme_Closure_Data *data, /* Fill in closure */ int j, size, pos; mzshort *map; + Scheme_Object *v; size = data->closure_size; map = data->closure_map; jit_addi_p(JIT_R2, JIT_R0, &((Scheme_Native_Closure *)0x0)->vals); for (j = 0; j < size; j++) { CHECK_LIMIT(); - pos = mz_remap(map[j]); - jit_ldxi_p(JIT_R1, JIT_RUNSTACK, WORDS_TO_BYTES(pos)); + + if (SCHEME_NATIVE_CLOSURE_DATA_FLAGS(jitter->nc->code) & NATIVE_SPECIALIZED) + v = extract_closure_local(map[j], jitter, 1); + else + v = NULL; + + if (v) { + /* capture value directly within specialized */ + scheme_mz_load_retained(jitter, JIT_R1, v); + } else { + pos = mz_remap(map[j]); + jit_ldxi_p(JIT_R1, JIT_RUNSTACK, WORDS_TO_BYTES(pos)); + } jit_stxi_p(WORDS_TO_BYTES(j), JIT_R2, JIT_R1); } return 1; @@ -1435,7 +1447,7 @@ static int generate_case_closure(Scheme_Object *obj, mz_jit_state *jitter, int t JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); mz_prepare(1); - scheme_mz_load_retained(jitter, JIT_R0, ndata, 0); + scheme_mz_load_retained(jitter, JIT_R0, ndata); jit_pusharg_p(JIT_R0); { GC_CAN_IGNORE jit_insn *refr USED_ONLY_FOR_FUTURES; @@ -2056,7 +2068,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w Scheme_Object *b; mz_rs_sync_fail_branch(); b = scheme_extract_global(obj, jitter->nc, 0); - scheme_mz_load_retained(jitter, JIT_R2, b, 1); + scheme_mz_load_retained(jitter, JIT_R2, b); } else { /* Load global array: */ pos = mz_remap(SCHEME_TOPLEVEL_DEPTH(obj)); @@ -2175,7 +2187,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w pos = mz_remap(SCHEME_LOCAL_POS(obj)); if (!result_ignored) { if (specialized) - scheme_mz_load_retained(jitter, JIT_R0, specialized, 1); + scheme_mz_load_retained(jitter, JIT_R0, specialized); else mz_rs_ldxi(JIT_R0, pos); jit_ldr_p(target, JIT_R0); @@ -2879,7 +2891,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w if (ab) { pos = mz_remap(lv->position); if (specialized) - scheme_mz_load_retained(jitter, JIT_R2, specialized, 1); + scheme_mz_load_retained(jitter, JIT_R2, specialized); else mz_rs_ldxi(JIT_R2, pos); jit_str_p(JIT_R2, JIT_R0); @@ -3357,7 +3369,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w } } - scheme_mz_load_retained(jitter, target, obj, 0); + scheme_mz_load_retained(jitter, target, obj); END_JIT_DATA(19); return 1; diff --git a/racket/src/racket/src/jit.h b/racket/src/racket/src/jit.h index 70ccaf1ea1..5d097e6011 100644 --- a/racket/src/racket/src/jit.h +++ b/racket/src/racket/src/jit.h @@ -1366,7 +1366,7 @@ int scheme_stack_safety(mz_jit_state *jitter, int cnt, int offset); #ifdef USE_FLONUM_UNBOXING int scheme_mz_flostack_pos(mz_jit_state *jitter, int i); #endif -void scheme_mz_load_retained(mz_jit_state *jitter, int rs, void *o, int non_obj); +void scheme_mz_load_retained(mz_jit_state *jitter, int rs, void *o); void scheme_mz_runstack_skipped(mz_jit_state *jitter, int n); void scheme_mz_runstack_unskipped(mz_jit_state *jitter, int n); diff --git a/racket/src/racket/src/jitcall.c b/racket/src/racket/src/jitcall.c index d44ec7513e..fc2d056fa2 100644 --- a/racket/src/racket/src/jitcall.c +++ b/racket/src/racket/src/jitcall.c @@ -479,7 +479,7 @@ int scheme_generate_tail_call(mz_jit_state *jitter, int num_rands, int direct_na if (direct_native && direct_to_code) { __END_SHORT_JUMPS__(num_rands < 100); /* load closure pointer into R0: */ - scheme_mz_load_retained(jitter, JIT_R0, direct_to_code, 0); + scheme_mz_load_retained(jitter, JIT_R0, direct_to_code); /* jump directly: */ (void)jit_jmpi(direct_to_code->code->u.tail_code); /* no slow path in this mode */ diff --git a/racket/src/racket/src/jitinline.c b/racket/src/racket/src/jitinline.c index 32743f1cf9..efea7983fd 100644 --- a/racket/src/racket/src/jitinline.c +++ b/racket/src/racket/src/jitinline.c @@ -2561,7 +2561,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i && !SCHEME_FALSEP(a1) && !SCHEME_VOIDP(a1) && !SAME_OBJ(a1, scheme_true)) { - scheme_mz_load_retained(jitter, JIT_R1, a1, 0); + scheme_mz_load_retained(jitter, JIT_R1, a1); ref = jit_bner_p(jit_forward(), JIT_R0, JIT_R1); /* In case true is a fall-through, note that the test didn't disturb R0: */ @@ -3848,7 +3848,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i ref = jit_bnei_p(jit_forward(), JIT_R0, scheme_undefined); __END_TINY_JUMPS__(1); - scheme_mz_load_retained(jitter, JIT_R1, app->rand2, 0); + scheme_mz_load_retained(jitter, JIT_R1, app->rand2); if (IS_NAMED_PRIM(rator, "check-not-unsafe-undefined")) (void)jit_calli(sjc.call_check_not_defined_code); else diff --git a/racket/src/racket/src/jitstate.c b/racket/src/racket/src/jitstate.c index 09e7a14fed..029c07628c 100644 --- a/racket/src/racket/src/jitstate.c +++ b/racket/src/racket/src/jitstate.c @@ -70,15 +70,14 @@ int scheme_mz_retain_it(mz_jit_state *jitter, void *v) return jitter->retained; } -void scheme_mz_load_retained(mz_jit_state *jitter, int rs, void *obj, int non_obj) +void scheme_mz_load_retained(mz_jit_state *jitter, int rs, void *obj) /* obj is a pointer, but not necesarily tagged (in CGC) */ { - if (non_obj - || (!SCHEME_INTP((Scheme_Object *)obj) - && !SAME_OBJ((Scheme_Object *)obj, scheme_true) - && !SAME_OBJ((Scheme_Object *)obj, scheme_false) - && !SAME_OBJ((Scheme_Object *)obj, scheme_void) - && !SAME_OBJ((Scheme_Object *)obj, scheme_null))) { + if (!SCHEME_INTP((Scheme_Object *)obj) + && !SAME_OBJ((Scheme_Object *)obj, scheme_true) + && !SAME_OBJ((Scheme_Object *)obj, scheme_false) + && !SAME_OBJ((Scheme_Object *)obj, scheme_void) + && !SAME_OBJ((Scheme_Object *)obj, scheme_null)) { #ifdef JIT_PRECISE_GC int retptr; void *p; From 7056cd5f2abfbf9d6ed75d5ba98789a6a0e92cc2 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 29 Dec 2015 11:15:31 -0600 Subject: [PATCH 256/369] improve ->i in the case that the dependent contract turns out to be a predicate. In that case, just call it instead of creating all of the extra junk that would normally be created by coercing the predicate to a contract and invoking it --- .../racket/contract/private/arr-i.rkt | 28 +++++++++++++------ .../collects/racket/contract/private/guts.rkt | 15 ++++++---- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/racket/collects/racket/contract/private/arr-i.rkt b/racket/collects/racket/contract/private/arr-i.rkt index bd04b22e2e..bd9fbd4382 100644 --- a/racket/collects/racket/contract/private/arr-i.rkt +++ b/racket/collects/racket/contract/private/arr-i.rkt @@ -1089,17 +1089,29 @@ evaluted left-to-right.) (begin-encourage-inline (define (un-dep/chaperone orig-ctc obj blame neg-party) - (let ([ctc (coerce-contract '->i orig-ctc)]) - (unless (chaperone-contract? ctc) - (raise-argument-error '->i - "chaperone-contract?" - orig-ctc)) - (((get/build-late-neg-projection ctc) blame) obj neg-party)))) + (cond + [(and (procedure? orig-ctc) + (procedure-arity-includes? orig-ctc 1)) + (if (orig-ctc obj) + obj + (raise-predicate-blame-error-failure blame obj neg-party + (object-name orig-ctc)))] + [else + (define ctc (coerce-chaperone-contract '->i orig-ctc)) + (((get/build-late-neg-projection ctc) blame) obj neg-party)]))) (begin-encourage-inline (define (un-dep orig-ctc obj blame neg-party) - (let ([ctc (coerce-contract '->i orig-ctc)]) - (((get/build-late-neg-projection ctc) blame) obj neg-party)))) + (cond + [(and (procedure? orig-ctc) + (procedure-arity-includes? orig-ctc 1)) + (if (orig-ctc obj) + obj + (raise-predicate-blame-error-failure blame obj neg-party + (object-name orig-ctc)))] + [else + (define ctc (coerce-contract '->i orig-ctc)) + (((get/build-late-neg-projection ctc) blame) obj neg-party)]))) (define-for-syntax (mk-used-indy-vars an-istx) (let ([vars (make-free-identifier-mapping)]) diff --git a/racket/collects/racket/contract/private/guts.rkt b/racket/collects/racket/contract/private/guts.rkt index 7a8f4ba1fc..b21feca9a6 100644 --- a/racket/collects/racket/contract/private/guts.rkt +++ b/racket/collects/racket/contract/private/guts.rkt @@ -74,7 +74,9 @@ contract-first-order-okay-to-give-up? contract-first-order-try-less-hard - contract-first-order-only-try-so-hard) + contract-first-order-only-try-so-hard + + raise-predicate-blame-error-failure) (define (contract-custom-write-property-proc stct port mode) (define (write-prefix) @@ -617,10 +619,7 @@ (λ (v neg-party) (if (p? v) v - (raise-blame-error blame v #:missing-party neg-party - '(expected: "~s" given: "~e") - name - v)))))) + (raise-predicate-blame-error-failure blame v neg-party name)))))) #:generate (λ (ctc) (let ([generate (predicate-contract-generate ctc)]) (cond @@ -635,6 +634,12 @@ #:list-contract? (λ (ctc) (or (equal? (predicate-contract-pred ctc) null?) (equal? (predicate-contract-pred ctc) empty?))))) +(define (raise-predicate-blame-error-failure blame v neg-party predicate-name) + (raise-blame-error blame v #:missing-party neg-party + '(expected: "~s" given: "~e") + predicate-name + v)) + (define (check-flat-named-contract predicate) (coerce-flat-contract 'flat-named-contract predicate)) (define (check-flat-contract predicate) (coerce-flat-contract 'flat-contract predicate)) (define (build-flat-contract name pred [generate #f]) From 2c5aa96031ab2835db56ff910aea5a01c99f2095 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 29 Dec 2015 11:25:45 -0600 Subject: [PATCH 257/369] change some potentially error-prone provide all-from-outs to explicit provides and make set load its implementation via relative requires --- racket/collects/racket/set.rkt | 45 +++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/racket/collects/racket/set.rkt b/racket/collects/racket/set.rkt index ea4ccc1a37..5ddafc515f 100644 --- a/racket/collects/racket/set.rkt +++ b/racket/collects/racket/set.rkt @@ -2,14 +2,51 @@ (require racket/contract/base racket/contract/combinator - racket/private/set - racket/private/set-types + "private/set.rkt" + "private/set-types.rkt" racket/generic racket/private/for (for-syntax racket/base)) -(provide (all-from-out racket/private/set) - (all-from-out racket/private/set-types) +(provide gen:set generic-set? set-implements? + + set-empty? set-member? set-count + set=? subset? proper-subset? + set-map set-for-each + set-copy set-copy-clear + set->list set->stream set-first set-rest + set-add set-remove set-clear + set-union set-intersect set-subtract set-symmetric-difference + set-add! set-remove! set-clear! + set-union! set-intersect! set-subtract! set-symmetric-difference! + + in-set + set-implements/c + + set seteq seteqv + weak-set weak-seteq weak-seteqv + mutable-set mutable-seteq mutable-seteqv + list->set list->seteq list->seteqv + list->weak-set list->weak-seteq list->weak-seteqv + list->mutable-set list->mutable-seteq list->mutable-seteqv + set-eq? set-eqv? set-equal? + set-weak? set-mutable? set? + for/set for/seteq for/seteqv + for*/set for*/seteq for*/seteqv + for/weak-set for/weak-seteq for/weak-seteqv + for*/weak-set for*/weak-seteq for*/weak-seteqv + for/mutable-set for/mutable-seteq for/mutable-seteqv + for*/mutable-set for*/mutable-seteq for*/mutable-seteqv + + define-custom-set-types + make-custom-set-types + make-custom-set + make-weak-custom-set + make-mutable-custom-set + + chaperone-hash-set + impersonate-hash-set + set/c) (define/subexpression-pos-prop/name From 22adc0253b8f29affbc9aa06ac4c5782003ab9f3 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 29 Dec 2015 11:26:17 -0600 Subject: [PATCH 258/369] change sets generics so they default to supplying the optional argument if the given procedure accepts it --- racket/collects/racket/private/set-types.rkt | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/racket/collects/racket/private/set-types.rkt b/racket/collects/racket/private/set-types.rkt index ca6c3af38c..942c877440 100644 --- a/racket/collects/racket/private/set-types.rkt +++ b/racket/collects/racket/private/set-types.rkt @@ -794,26 +794,26 @@ (struct wrapped-elem custom-elem [] #:methods gen:equal+hash [(define equal-proc - (if (procedure-arity-includes? =? 2) - (lambda (a b f) - (=? (custom-elem-contents a) - (custom-elem-contents b))) + (if (procedure-arity-includes? =? 3) (lambda (a b f) (=? (custom-elem-contents a) (custom-elem-contents b) - f)))) + f)) + (lambda (a b f) + (=? (custom-elem-contents a) + (custom-elem-contents b))))) (define hash-proc - (if (procedure-arity-includes? hc1 1) + (if (procedure-arity-includes? hc1 2) (lambda (a f) - (hc1 (custom-elem-contents a))) + (hc1 (custom-elem-contents a) f)) (lambda (a f) - (hc1 (custom-elem-contents a) f)))) + (hc1 (custom-elem-contents a))))) (define hash2-proc - (if (procedure-arity-includes? hc2 1) + (if (procedure-arity-includes? hc2 2) (lambda (a f) - (hc2 (custom-elem-contents a))) + (hc2 (custom-elem-contents a) f)) (lambda (a f) - (hc2 (custom-elem-contents a) f))))]) + (hc2 (custom-elem-contents a)))))]) (custom-spec elem? wrapped-elem (make-weak-hasheq))) (define (default-hc x f) 1) From 56ea9f8b9a7f476ae5fed613d671daf1c6e41dd0 Mon Sep 17 00:00:00 2001 From: Mira Leung Date: Wed, 29 Apr 2015 22:17:24 -0700 Subject: [PATCH 259/369] Specify names of missing fields for match on structs --- racket/collects/racket/match/parse-helper.rkt | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/racket/collects/racket/match/parse-helper.rkt b/racket/collects/racket/match/parse-helper.rkt index 3b5508f870..feaaf5ebf9 100644 --- a/racket/collects/racket/match/parse-helper.rkt +++ b/racket/collects/racket/match/parse-helper.rkt @@ -125,13 +125,32 @@ => (lambda (ps) (unless (= (length ps) (length acc)) - (raise-syntax-error - 'match - (format "~a structure ~a: expected ~a but got ~a" - "wrong number for fields for" - (syntax->datum struct-name) (length acc) - (length ps)) - stx pats)) + (when (< (length acc) (length ps)) + (raise-syntax-error + 'match + (format "~a structure ~a: expected ~a but got ~a" + "excess number of fields for" + (syntax->datum struct-name) (length acc) + (length ps)) + stx pats)) + (when (> (length acc) (length ps)) + (raise-syntax-error + 'match + (format + "~a structure ~a: expected ~a but got ~a; ~a ~a" + "insufficient number of fields for" + (syntax->datum struct-name) (length acc) + (length ps) + "missing fields" + (list-tail + (map (lambda (field) + (string->symbol + (substring (symbol->string (syntax->datum field)) + (add1 (string-length + (symbol->string (syntax->datum struct-name))))))) + acc) + (length ps))) + stx pats))) (map parse ps))] [else (raise-syntax-error 'match From 404c5b2699bef8846122572e0ccb42be08c53898 Mon Sep 17 00:00:00 2001 From: Mira Leung Date: Thu, 30 Apr 2015 18:03:29 -0700 Subject: [PATCH 260/369] Better code style for f3d888 --- racket/collects/racket/match/parse-helper.rkt | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/racket/collects/racket/match/parse-helper.rkt b/racket/collects/racket/match/parse-helper.rkt index feaaf5ebf9..b6ccec1cd9 100644 --- a/racket/collects/racket/match/parse-helper.rkt +++ b/racket/collects/racket/match/parse-helper.rkt @@ -136,21 +136,16 @@ (when (> (length acc) (length ps)) (raise-syntax-error 'match - (format - "~a structure ~a: expected ~a but got ~a; ~a ~a" - "insufficient number of fields for" - (syntax->datum struct-name) (length acc) - (length ps) - "missing fields" - (list-tail - (map (lambda (field) - (string->symbol - (substring (symbol->string (syntax->datum field)) - (add1 (string-length - (symbol->string (syntax->datum struct-name))))))) - acc) - (length ps))) - stx pats))) + (format "~a structure ~a: expected ~a but got ~a; ~a ~a" + "insufficient number of fields for" + (syntax->datum struct-name) (length acc) + (length ps) + "missing fields" + (list-tail + (for/list [(i acc)] + (symbol->string (syntax->datum i))) + (length ps))) + stx pats))) (map parse ps))] [else (raise-syntax-error 'match From e2bd1b51bce5946fbccfd9f07223cb6285c0d5f0 Mon Sep 17 00:00:00 2001 From: Mira Leung Date: Sun, 3 May 2015 12:42:32 -0700 Subject: [PATCH 261/369] Using in-list in for/list --- racket/collects/racket/match/parse-helper.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/racket/match/parse-helper.rkt b/racket/collects/racket/match/parse-helper.rkt index b6ccec1cd9..5614f36a04 100644 --- a/racket/collects/racket/match/parse-helper.rkt +++ b/racket/collects/racket/match/parse-helper.rkt @@ -142,7 +142,7 @@ (length ps) "missing fields" (list-tail - (for/list [(i acc)] + (for/list [(i (in-list acc))] (symbol->string (syntax->datum i))) (length ps))) stx pats))) From 893bb567620d6b65848cb4c0828c1cce38cbd9bc Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Tue, 29 Dec 2015 16:01:22 -0500 Subject: [PATCH 262/369] Rename to make it clear what to run. --- pkgs/racket-test/tests/match/{plt-match-tests.rkt => main.rkt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename pkgs/racket-test/tests/match/{plt-match-tests.rkt => main.rkt} (100%) diff --git a/pkgs/racket-test/tests/match/plt-match-tests.rkt b/pkgs/racket-test/tests/match/main.rkt similarity index 100% rename from pkgs/racket-test/tests/match/plt-match-tests.rkt rename to pkgs/racket-test/tests/match/main.rkt From 4bdde405f65b2b60a6f24d14a9b6dc1d6ba366cd Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 29 Dec 2015 15:46:04 -0600 Subject: [PATCH 263/369] improve the way that 'struct-out' cooperates with the rest of the contract system, creating and using a slightly more legitmate blame record and calling into the late-neg projections instead of using `contract` --- .../racket/contract/private/provide.rkt | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/racket/collects/racket/contract/private/provide.rkt b/racket/collects/racket/contract/private/provide.rkt index f3f699fb61..bd943af7bb 100644 --- a/racket/collects/racket/contract/private/provide.rkt +++ b/racket/collects/racket/contract/private/provide.rkt @@ -910,9 +910,11 @@ ;; directly here in the expansion makes this very expensive at compile time ;; when there are a lot of provide/contract clause using structs (define -struct:struct-name - (make-pc-struct-type 'struct-name + (make-pc-struct-type #,pos-module-source-id + 'struct-name struct-name-srcloc struct:struct-name + '(#,@field-names) field-contract-ids ...)) (provide (rename-out [-struct:struct-name struct:struct-name])))))))))) @@ -1115,9 +1117,18 @@ (define-syntax (provide/contract-for-contract-out stx) (provide/contract-for-whom stx 'contract-out)) -(define (make-pc-struct-type struct-name srcloc struct:struct-name . ctcs) +(define (make-pc-struct-type pos-module-source struct-name srcloc struct-type field-names . ctcs) + (define blame + (make-blame (build-source-location srcloc) struct-type (λ () `(substruct-of ,struct-name)) + pos-module-source #f #t)) + (define late-neg-acceptors + (for/list ([ctc (in-list ctcs)] + [field-name (in-list field-names)]) + ((get/build-late-neg-projection ctc) + (blame-add-context blame + (format "the ~a field of" field-name))))) (chaperone-struct-type - struct:struct-name + struct-type (λ (a b c d e f g h) (values a b c d e f g h)) (λ (x) x) (λ args @@ -1131,12 +1142,7 @@ null] [else (cons (car args) (loop (cdr args)))]))) (apply values - (map (λ (ctc val) - (contract ctc - val - 'not-enough-info-for-blame - 'not-enough-info-for-blame - name - srcloc)) - ctcs + (map (λ (late-neg-acceptors val) + (late-neg-acceptors val 'not-enough-info-for-blame)) + late-neg-acceptors vals))))) From 757adac56869143635d6feb1bc914b759ab9191e Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 29 Dec 2015 16:13:01 -0600 Subject: [PATCH 264/369] make #f always convert into the same (eq?) contract --- racket/collects/racket/contract/private/guts.rkt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/racket/collects/racket/contract/private/guts.rkt b/racket/collects/racket/contract/private/guts.rkt index b21feca9a6..a73ca22453 100644 --- a/racket/collects/racket/contract/private/guts.rkt +++ b/racket/collects/racket/contract/private/guts.rkt @@ -302,6 +302,7 @@ #f (memq x the-known-good-contracts))])] [(null? x) list/c-empty] + [(not x) false/c-contract] [(or (symbol? x) (boolean? x) (keyword? x)) (make-eq-contract x (if (name-default? name) @@ -477,6 +478,8 @@ ((predicate-contract-pred that) this-val)))) #:list-contract? (λ (c) (null? (eq-contract-val c))))) +(define false/c-contract (make-eq-contract #f #f)) + (define-struct equal-contract (val name) #:property prop:custom-write contract-custom-write-property-proc #:property prop:flat-contract From 46ace3172f02f0a43d05693521203fb2a3007e87 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 29 Dec 2015 20:28:22 -0600 Subject: [PATCH 265/369] clean up interaction between strict set/c contracts and mutable sets --- .../racket-test/tests/racket/contract/set.rkt | 40 +++++++++-- racket/collects/racket/set.rkt | 70 ++++++++----------- 2 files changed, 65 insertions(+), 45 deletions(-) diff --git a/pkgs/racket-test/tests/racket/contract/set.rkt b/pkgs/racket-test/tests/racket/contract/set.rkt index a5a0c150d0..1678137129 100644 --- a/pkgs/racket-test/tests/racket/contract/set.rkt +++ b/pkgs/racket-test/tests/racket/contract/set.rkt @@ -166,12 +166,20 @@ (binary-set 5) 'pos 'neg))) - (test/spec-passed + (test/spec-passed/result 'set/c21 '(let* ([c (set/c (-> integer? integer?))] [s (contract c (set (λ (x) x)) 'pos 'neg)]) (and (has-contract? s) - (equal? (value-contract s) c)))) + (equal? (value-contract s) c))) + #t) + + (test/spec-passed/result + 'set/c2b + '(let* ([c (set/c (-> integer? integer?))] + [s (contract c (set (λ (x) x)) 'pos 'neg)]) + (has-blame? s)) + #t) (test/spec-passed 'set/c22 @@ -207,14 +215,34 @@ (test/neg-blame 'set/c28 - '(let ([s (contract (set/c integer? #:lazy? #t) - (set #f) 'pos 'neg)]) + '(let ([s (contract (set/c integer? #:lazy? #t #:kind 'dont-care) + (mutable-set #f) 'pos 'neg)]) (set-add! s "x"))) (test/neg-blame 'set/c29 - '(let ([s (contract (set/c integer? #:lazy? #f) - (set 0) 'pos 'neg)]) + '(let ([s (contract (set/c integer? #:lazy? #f #:kind 'mutable) + (mutable-set 0) 'pos 'neg)]) (set-add! s "x"))) + + (test/spec-passed + 'set/c30 + '(let () + (define-custom-set-types set2 equal?) + (set-add + (contract (set/c (-> integer? integer?)) + (make-immutable-set2) + 'pos 'neg) + add1))) + + (test/spec-passed + 'set/c30 + '(let () + (define-custom-set-types set2 equal?) + (set-add + (contract (set/c (-> integer? integer?)) + (make-immutable-set2) + 'pos 'neg) + add1))) ) diff --git a/racket/collects/racket/set.rkt b/racket/collects/racket/set.rkt index 5ddafc515f..301cfe134c 100644 --- a/racket/collects/racket/set.rkt +++ b/racket/collects/racket/set.rkt @@ -184,50 +184,42 @@ (λ (blame) (define late-neg-pos-proj (late-neg-ele-proj (blame-add-element-context blame #f))) (define late-neg-neg-proj (late-neg-ele-proj (blame-add-element-context blame #t))) - (define set/c-lazy-late-neg-proj - (λ (val neg-party) + (cond + [lazy? + (λ (val neg-party) (set-contract-check cmp kind blame neg-party val) (define (pos-interpose val ele) (late-neg-pos-proj ele neg-party)) - (cond - [(set? val) - (chaperone-hash-set - val - pos-interpose - (λ (val ele) ele) - pos-interpose - impersonator-prop:contracted - ctc)] - [else - (chaperone-hash-set - val - pos-interpose - (λ (val ele) (late-neg-neg-proj ele neg-party)) - pos-interpose - impersonator-prop:contracted - ctc)]))) - (cond - [lazy? set/c-lazy-late-neg-proj] + (chaperone-hash-set + val + pos-interpose + (λ (val ele) (late-neg-neg-proj ele neg-party)) + pos-interpose + impersonator-prop:contracted ctc + impersonator-prop:blame (cons blame neg-party)))] [else (λ (val neg-party) (set-contract-check cmp kind blame neg-party val) - (define w/chaperone - (cond - [(set? val) val] - [else - (chaperone-hash-set - val - (λ (val ele) ele) - (λ (val ele) (late-neg-neg-proj ele neg-party)) - (λ (val ele) ele))])) - (chaperone-hash-set - (for/set ([ele (in-set w/chaperone)]) - (late-neg-pos-proj ele neg-party)) - (chaperone-hash-set - val - #f #f #f - impersonator-prop:contracted - ctc)))]))) - + (cond + [(set? val) + (chaperone-hash-set + (for/fold ([s (set-clear val)]) + ([e (in-set val)]) + (set-add s (late-neg-pos-proj e neg-party))) + #f #f #f + impersonator-prop:contracted ctc + impersonator-prop:blame (cons blame neg-party))] + [else + (define (pos-interpose val ele) (late-neg-pos-proj ele neg-party)) + (for ([ele (in-list (set->list val))]) + (set-remove! val ele) + (set-add! val (late-neg-pos-proj ele neg-party))) + (chaperone-hash-set + val + pos-interpose + (λ (val ele) (late-neg-neg-proj ele neg-party)) + pos-interpose + impersonator-prop:contracted ctc + impersonator-prop:blame (cons blame neg-party))]))]))) (define (generic-set-late-neg-projection ctc chaperone-ctc?) (define elem/c (set-contract-elem/c ctc)) From a5b3d6b3d08015957dcff7991be617eae12df2c9 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 29 Dec 2015 21:46:06 -0600 Subject: [PATCH 266/369] uncopy some code --- .../racket/contract/private/arr-i.rkt | 38 ++++++++----------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/racket/collects/racket/contract/private/arr-i.rkt b/racket/collects/racket/contract/private/arr-i.rkt index bd9fbd4382..6393b98bbb 100644 --- a/racket/collects/racket/contract/private/arr-i.rkt +++ b/racket/collects/racket/contract/private/arr-i.rkt @@ -1088,30 +1088,24 @@ evaluted left-to-right.) #`(f #,@argument-list))) (begin-encourage-inline + (define (un-dep/maybe-chaperone orig-ctc obj blame neg-party chaperone?) + (cond + [(and (procedure? orig-ctc) + (procedure-arity-includes? orig-ctc 1)) + (if (orig-ctc obj) + obj + (raise-predicate-blame-error-failure blame obj neg-party + (object-name orig-ctc)))] + [else + (define ctc (if chaperone? + (coerce-chaperone-contract '->i orig-ctc) + (coerce-contract '->i orig-ctc))) + (((get/build-late-neg-projection ctc) blame) obj neg-party)])) (define (un-dep/chaperone orig-ctc obj blame neg-party) - (cond - [(and (procedure? orig-ctc) - (procedure-arity-includes? orig-ctc 1)) - (if (orig-ctc obj) - obj - (raise-predicate-blame-error-failure blame obj neg-party - (object-name orig-ctc)))] - [else - (define ctc (coerce-chaperone-contract '->i orig-ctc)) - (((get/build-late-neg-projection ctc) blame) obj neg-party)]))) - -(begin-encourage-inline + (un-dep/maybe-chaperone orig-ctc obj blame neg-party #t)) + (define (un-dep orig-ctc obj blame neg-party) - (cond - [(and (procedure? orig-ctc) - (procedure-arity-includes? orig-ctc 1)) - (if (orig-ctc obj) - obj - (raise-predicate-blame-error-failure blame obj neg-party - (object-name orig-ctc)))] - [else - (define ctc (coerce-contract '->i orig-ctc)) - (((get/build-late-neg-projection ctc) blame) obj neg-party)]))) + (un-dep/maybe-chaperone orig-ctc obj blame neg-party #f))) (define-for-syntax (mk-used-indy-vars an-istx) (let ([vars (make-free-identifier-mapping)]) From f2f38cdf4ac67302f5d3191404d53d2e7c8aa36b Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 30 Dec 2015 09:28:30 -0600 Subject: [PATCH 267/369] remove overly aggressive use of procedure-specialize --- racket/collects/racket/contract/private/orc.rkt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/racket/collects/racket/contract/private/orc.rkt b/racket/collects/racket/contract/private/orc.rkt index b8455f226c..dcb8bfc566 100644 --- a/racket/collects/racket/contract/private/orc.rkt +++ b/racket/collects/racket/contract/private/orc.rkt @@ -70,8 +70,7 @@ [(null? rst) fst-pred] [else (let ([r (loop (car rst) (cdr rst))]) - (procedure-specialize - (λ (x) (or (fst-pred x) (r x)))))])))])) + (λ (x) (or (fst-pred x) (r x))))])))])) (define (single-or/c-late-neg-projection ctc) (define c-proj (get/build-late-neg-projection (single-or/c-ho-ctc ctc))) From 1c3422d420962ea4aa5695e996cc2115909836eb Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Wed, 30 Dec 2015 10:39:45 -0500 Subject: [PATCH 268/369] Fix CI tests for match test move. --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 69b233f44b..515e07b3d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,7 +42,7 @@ script: - raco test -l tests/net/encoders - raco test -l tests/openssl/basic - raco test -l tests/openssl/https -- raco test -l tests/match/plt-match-tests +- raco test -l tests/match/main - raco test -l tests/zo-path - raco test -l tests/xml/test - raco test -l tests/db/all-tests diff --git a/appveyor.yml b/appveyor.yml index 06073a1ea8..d60c45daf4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -24,7 +24,7 @@ test_script: - racket\raco.exe test -l tests/net/encoders - racket\raco.exe test -l tests/openssl/basic - racket\raco.exe test -l tests/openssl/https -- racket\raco.exe test -l tests/match/plt-match-tests +- racket\raco.exe test -l tests/match/main - racket\raco.exe test -l tests/zo-path - racket\raco.exe test -l tests/xml/test From a97aa8389bce8a30eec27e6f53c649d3f38ee267 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 30 Dec 2015 13:50:21 -0600 Subject: [PATCH 269/369] port id-table/c to flat-neg projection --- racket/collects/syntax/id-table.rkt | 44 +++++++++++++++-------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/racket/collects/syntax/id-table.rkt b/racket/collects/syntax/id-table.rkt index a9fb980bef..1a70a3986c 100644 --- a/racket/collects/syntax/id-table.rkt +++ b/racket/collects/syntax/id-table.rkt @@ -56,7 +56,7 @@ (let () (define (proj acc location swap) (lambda (ctc blame) - ((contract-projection (acc ctc)) + ((contract-late-neg-projection (acc ctc)) (blame-add-context blame location #:swap? swap)))) (values (proj base-id-table/c-dom "the keys of" #f) @@ -96,51 +96,53 @@ (and (contract-first-order-passes? dom-ctc k) (contract-first-order-passes? rng-ctc v)))))) - (define (check-id-table/c ctc val blame) + (define (check-id-table/c ctc val blame neg-party) (define immutable (base-id-table/c-immutable ctc)) (case immutable [(#t) (unless (immutable-idtbl? val) - (raise-blame-error blame val + (raise-blame-error blame val #:missing-party neg-party '(expected "an immutable ~a," given: "~e") 'idtbl val))] [(#f) (unless (mutable-idtbl? val) - (raise-blame-error blame val + (raise-blame-error blame val #:missing-party neg-party '(expected "a mutable ~a," given: "~e") 'idtbl val))] [(dont-care) (unless (idtbl? val) - (raise-blame-error blame val + (raise-blame-error blame val #:missing-party neg-party '(expected "a ~a," given: "~e") 'idtbl val))])) - (define (fo-projection ctc) + (define (late-neg-fo-projection ctc) (λ (blame) (define dom-proj (id-table/c-dom-pos-proj ctc blame)) (define rng-proj (id-table/c-rng-pos-proj ctc blame)) - (λ (val) - (check-id-table/c ctc val blame) + (λ (val neg-party) + (check-id-table/c ctc val blame neg-party) (for ([(k v) (in-dict val)]) - (dom-proj k) - (rng-proj v)) + (dom-proj k neg-party) + (rng-proj v neg-party)) val))) - (define (ho-projection ctc) + (define (late-neg-ho-projection ctc) (lambda (blame) (define pos-dom-proj (id-table/c-dom-pos-proj ctc blame)) (define neg-dom-proj (id-table/c-dom-neg-proj ctc blame)) (define pos-rng-proj (id-table/c-rng-pos-proj ctc blame)) (define neg-rng-proj (id-table/c-rng-neg-proj ctc blame)) - (lambda (tbl) - (check-id-table/c ctc tbl blame) + (lambda (tbl neg-party) + (check-id-table/c ctc tbl blame neg-party) ;;TODO for immutable hash tables optimize this chaperone to a flat ;;check if possible (if (immutable-idtbl? tbl) - (chaperone-immutable-id-table tbl pos-dom-proj pos-rng-proj + (chaperone-immutable-id-table tbl + (λ (val) (pos-dom-proj val neg-party)) + (λ (val) (pos-rng-proj val neg-party)) impersonator-prop:contracted ctc) (chaperone-mutable-id-table tbl - neg-dom-proj - pos-dom-proj - neg-rng-proj - pos-rng-proj + (λ (val) (neg-dom-proj val neg-party)) + (λ (val) (pos-dom-proj val neg-party)) + (λ (val) (neg-rng-proj val neg-party)) + (λ (val) (pos-rng-proj val neg-party)) impersonator-prop:contracted ctc))))) (struct flat-id-table/c base-id-table/c () @@ -149,7 +151,7 @@ (build-flat-contract-property #:name id-table/c-name #:first-order id-table/c-first-order - #:projection fo-projection)) + #:late-neg-projection late-neg-fo-projection)) (struct chaperone-id-table/c base-id-table/c () #:omit-define-syntaxes @@ -157,7 +159,7 @@ (build-chaperone-contract-property #:name id-table/c-name #:first-order id-table/c-first-order - #:projection ho-projection)) + #:late-neg-projection late-neg-ho-projection)) ;; Note: impersonator contracts not currently supported. (struct impersonator-id-table/c base-id-table/c () @@ -166,7 +168,7 @@ (build-contract-property #:name id-table/c-name #:first-order id-table/c-first-order - #:projection ho-projection)) + #:late-neg-projection late-neg-ho-projection)) (define (id-table/c key/c value/c #:immutable [immutable 'dont-care]) (define key/ctc (coerce-contract idtbl/c-symbol key/c)) From 9ee264a0eafc411fd31ef82b2027333755ab0d40 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 30 Dec 2015 14:44:01 -0600 Subject: [PATCH 270/369] improve performance of `define-generic`-created contracts and port to late-neg This program runs about 10x faster than it did before this commit, but seems to still be about 100x slower than the version where you change an-s to just be (s). #lang racket/base (require racket/contract/base racket/generic) (define-generics id [m id x]) (struct s () #:methods gen:id [(define (m g x) x)]) (define an-s (contract (id/c [m (-> any/c integer? integer?)]) (s) 'pos 'neg)) (time (for ([x (in-range 100000)]) (m an-s 2))) --- racket/collects/racket/generic.rkt | 47 +++++++++++++++++------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/racket/collects/racket/generic.rkt b/racket/collects/racket/generic.rkt index af8e535ab8..fbc9e01944 100644 --- a/racket/collects/racket/generic.rkt +++ b/racket/collects/racket/generic.rkt @@ -271,8 +271,7 @@ (define/with-syntax pred predicate) (define/with-syntax [ctc-id ...] (generate-temporaries #'(ctc-expr ...))) - (define/with-syntax [proj-id ...] - (generate-temporaries #'(ctc-expr ...))) + (define/with-syntax (late-neg-proj-id ...) (generate-temporaries #'(ctc-expr ...))) #'(let* ([ctc-id ctc-expr] ...) (make-generics-contract 'gen-name @@ -280,19 +279,21 @@ pred '(method-id ...) (list ctc-id ...) - (lambda (b x mode) - (redirect-generics/derived - original - mode - gen-name ref-gen-id - x - [method-id - (lambda (m) - (define b2 - (blame-add-context b (format "method ~a" 'method-id))) - (((contract-projection ctc-id) b2) m))] - ... - null)))))])) + (λ (mode late-neg-proj-id ...) + (λ (x neg-party) + (redirect-generics/derived + original + mode + gen-name ref-gen-id + x + [method-id + (lambda (m) + (late-neg-proj-id m neg-party))] + ... + null))))))])) + +(define (blame-add-method-context blame method-id) + (blame-add-context blame (format "method ~a" method-id))) (define (make-generics-contract ifc pfx pred mths ctcs proc) (define chaperoning? @@ -320,22 +321,26 @@ (define (generics-contract-first-order ctc) (generics-contract-predicate ctc)) -(define (generics-contract-projection mode) +(define (generics-late-neg-contract-projection mode) (lambda (c) - (lambda (b) - (lambda (x) - ((generics-contract-redirect c) b x mode))))) + (define mk-late-neg-projs (map contract-late-neg-projection (generics-contract-contracts c))) + (lambda (blame) + (define late-neg-projs + (for/list ([m (in-list (generics-contract-methods c))] + [mk-late-neg-proj (in-list mk-late-neg-projs)]) + (mk-late-neg-proj (blame-add-method-context blame m)))) + (apply (generics-contract-redirect c) mode late-neg-projs)))) (struct chaperone-generics-contract generics-contract [] #:property prop:chaperone-contract (build-chaperone-contract-property #:name generics-contract-name #:first-order generics-contract-first-order - #:projection (generics-contract-projection #t))) + #:late-neg-projection (generics-late-neg-contract-projection #t))) (struct impersonator-generics-contract generics-contract [] #:property prop:contract (build-contract-property #:name generics-contract-name #:first-order generics-contract-first-order - #:projection (generics-contract-projection #f))) + #:late-neg-projection (generics-late-neg-contract-projection #f))) From cb2af327e62a2d7d4fa3738cdb03a58fa3077102 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 30 Dec 2015 15:23:25 -0600 Subject: [PATCH 271/369] port async-channel/c to late-neg proj and drop other projection implementations (mostly to reduce the testing burden) --- racket/collects/racket/async-channel.rkt | 54 +++++++----------------- 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/racket/collects/racket/async-channel.rkt b/racket/collects/racket/async-channel.rkt index 5c8b419d34..e4249b7519 100644 --- a/racket/collects/racket/async-channel.rkt +++ b/racket/collects/racket/async-channel.rkt @@ -197,16 +197,10 @@ (define (add-async-channel-context blame) (blame-add-context blame "a value passed through")) -(define (check-async-channel/c ctc val blame) +(define (check-async-channel/c ctc val blame neg-party) (unless (async-channel? val) - (raise-blame-error blame val '(expected "an async channel" given: "~e") val))) - -(define (check-async-channel/c-np ctc val blame) - (if (async-channel? val) - #f - (λ (neg-party) - (raise-blame-error blame #:missing-party neg-party - val '(expected "an async channel" given: "~e") val)))) + (raise-blame-error blame val #:missing-party neg-party + '(expected "an async channel" given: "~e") val))) (define ((async-channel/c-first-order ctc) val) (async-channel? val)) @@ -214,33 +208,19 @@ (define (async-channel/c-stronger? a b) (contract-stronger? (base-async-channel/c-content a) (base-async-channel/c-content b))) -(define ((ho-val-first-projection impersonate/chaperone-async-channel) ctc) +(define ((late-neg-projection impersonate/chaperone-async-channel) ctc) (define elem-ctc (base-async-channel/c-content ctc)) - (define vfp (get/build-val-first-projection elem-ctc)) + (define lnp (contract-late-neg-projection elem-ctc)) (λ (blame) - (define async-channel-blame (add-async-channel-context blame)) - (define pos-elem-proj (vfp async-channel-blame)) - (define neg-elem-proj (vfp (blame-swap async-channel-blame))) - (λ (val) - (or (check-async-channel/c-np ctc val blame) - (λ (neg-party) - (impersonate/chaperone-async-channel - val - (λ (v) ((pos-elem-proj v) neg-party)) - (λ (v) ((neg-elem-proj v) neg-party)) - impersonator-prop:contracted ctc - impersonator-prop:blame (blame-add-missing-party blame neg-party))))))) - -(define ((ho-projection impersonate/chaperone-async-channel) ctc) - (let ([elem-ctc (base-async-channel/c-content ctc)]) - (λ (blame) - (let ([pos-elem-proj ((contract-projection elem-ctc) blame)] - [neg-elem-proj ((contract-projection elem-ctc) (blame-swap blame))]) - (λ (val) - (check-async-channel/c ctc val blame) - (impersonate/chaperone-async-channel val pos-elem-proj neg-elem-proj - impersonator-prop:contracted ctc - impersonator-prop:blame blame)))))) + (define pos-elem-proj (lnp blame)) + (define neg-elem-proj (lnp (blame-swap blame))) + (λ (val neg-party) + (check-async-channel/c ctc val blame neg-party) + (impersonate/chaperone-async-channel val + (λ (v) (pos-elem-proj v neg-party)) + (λ (v) (neg-elem-proj v neg-party)) + impersonator-prop:contracted ctc + impersonator-prop:blame blame)))) (struct base-async-channel/c (content)) @@ -251,8 +231,7 @@ #:name async-channel/c-name #:first-order async-channel/c-first-order #:stronger async-channel/c-stronger? - #:val-first-projection (ho-val-first-projection chaperone-async-channel) - #:projection (ho-projection chaperone-async-channel))) + #:late-neg-projection (late-neg-projection chaperone-async-channel))) (struct impersonator-async-channel/c base-async-channel/c () #:property prop:custom-write custom-write-property-proc @@ -261,8 +240,7 @@ #:name async-channel/c-name #:first-order async-channel/c-first-order #:stronger async-channel/c-stronger? - #:val-first-projection (ho-val-first-projection impersonate-async-channel) - #:projection (ho-projection impersonate-async-channel))) + #:late-neg-projection (late-neg-projection impersonate-async-channel))) (define (async-channel/c elem) (define ctc (coerce-contract 'async-channel/c elem)) From df382ca939a225d5416cd65828e6f408c6979f07 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 30 Dec 2015 17:04:38 -0600 Subject: [PATCH 272/369] improve warnings and fix small problems with contract combinator constructors --- .../collects/racket/contract/private/prop.rkt | 47 ++++++++++++++----- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/racket/collects/racket/contract/private/prop.rkt b/racket/collects/racket/contract/private/prop.rkt index 89b2ad36b0..9e95b1ce5d 100644 --- a/racket/collects/racket/contract/private/prop.rkt +++ b/racket/collects/racket/contract/private/prop.rkt @@ -282,8 +282,9 @@ (error proc-name (string-append - "expected either the #:get-projection, #:val-first-project, or #:late-neg-projection" - " to not be #f, but all three were #f"))) + "expected either the" + " #:projection, #:val-first-projection, #:late-neg-projection, or #:first-order" + " argument to not be #f, but all four were #f"))) (unless get-late-neg-projection (unless first-order? @@ -302,7 +303,7 @@ [first-order? (cond [get-late-neg-projection get-late-neg-projection] - [(and (not get-projection) (not get-val-first-projection)) + [(and (not get-projection) (not get-val-first-projection) get-first-order) (λ (c) (late-neg-first-order-projection (get-name c) (get-first-order c)))] [else #f])] [else get-late-neg-projection]) @@ -436,7 +437,7 @@ #:exercise (lambda (c) (make-flat-contract-exercise c)) #:list-contract? (λ (c) (make-flat-contract-list-contract? c)))) -(define ((build-contract mk default-name proc-name) +(define ((build-contract mk default-name proc-name first-order?) #:name [name #f] #:first-order [first-order #f] #:projection [projection #f] @@ -447,15 +448,35 @@ #:exercise [exercise (λ (ctc) (λ (fuel) (values void '())))] #:list-contract? [list-contract? (λ (ctc) #f)]) - (unless late-neg-projection - (log-racket/contract-warning - "no late-neg-projection passed to ~s~a" + (unless (or first-order + projection + val-first-projection + late-neg-projection) + (error proc-name - (build-context))) + (string-append + "expected either the" + " #:projection, #:val-first-projection, #:late-neg-projection, or #:first-order" + " argument to not be #f, but all four were #f"))) + + (unless late-neg-projection + (unless first-order? + (log-racket/contract-warning + "no late-neg-projection passed to ~s~a" + proc-name + (build-context)))) (mk (or name default-name) (or first-order any?) - projection val-first-projection late-neg-projection + projection val-first-projection + (cond + [first-order? + (cond + [late-neg-projection late-neg-projection] + [(and (not projection) (not val-first-projection) first-order) + (late-neg-first-order-projection name first-order)] + [else #f])] + [else late-neg-projection]) (or stronger as-strong?) generate exercise list-contract?)) @@ -479,21 +500,23 @@ (define make-contract (procedure-rename - (build-contract make-make-contract 'anonymous-contract 'make-contract) + (build-contract make-make-contract 'anonymous-contract 'make-contract #f) 'make-contract)) (define make-chaperone-contract (procedure-rename (build-contract make-make-chaperone-contract 'anonymous-chaperone-contract - 'make-chaperone-contract) + 'make-chaperone-contract + #f) 'make-chaperone-contract)) (define make-flat-contract (procedure-rename (build-contract make-make-flat-contract 'anonymous-flat-contract - 'make-flat-contract) + 'make-flat-contract + #t) 'make-flat-contract)) ;; property should be bound to a function that accepts the contract and From 61e21dba2290c463ca2631641c472ee2df9d7658 Mon Sep 17 00:00:00 2001 From: Benjamin Greenman Date: Wed, 30 Dec 2015 17:56:24 -0500 Subject: [PATCH 273/369] typo: is-flat-contract? -> is-list-contract? --- pkgs/racket-doc/scribblings/reference/contracts.scrbl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index fc6313f011..615ec985f2 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -2562,7 +2562,7 @@ These functions build the arguments for @racket[prop:contract], @racket[prop:chaperone-contract], and @racket[prop:flat-contract], respectively. A @deftech{contract property} specifies the behavior of a structure when used as -a contract. It is specified in terms of five accessors: @racket[get-name], +a contract. It is specified in terms of six accessors: @racket[get-name], which produces a description to @racket[write] as part of a contract violation; @racket[get-first-order], which produces a first-order predicate to be used by @racket[contract-first-order-passes?]; @racket[get-projection], which @@ -2576,7 +2576,7 @@ to indicate failure) or @racket[#f] to indicate that random generation for this contract isn't supported; @racket[exercise], which returns a function that exercises values matching the contract (e.g., if it is a function contract, it may call the function) and a list of contracts -whose values will be generated by this process; and @racket[is-flat-contract?], +whose values will be generated by this process; and @racket[is-list-contract?], which is used by @racket[flat-contract?] to determine if this contract accepts only @racket[list?]s. From 0f7a946dbab558ed69558d7d6dbad7ae2999c6ad Mon Sep 17 00:00:00 2001 From: Benjamin Greenman Date: Wed, 30 Dec 2015 18:25:21 -0500 Subject: [PATCH 274/369] put contract-property accessors in an itemlist --- .../scribblings/reference/contracts.scrbl | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index 615ec985f2..15d062c20a 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -2562,23 +2562,29 @@ These functions build the arguments for @racket[prop:contract], @racket[prop:chaperone-contract], and @racket[prop:flat-contract], respectively. A @deftech{contract property} specifies the behavior of a structure when used as -a contract. It is specified in terms of six accessors: @racket[get-name], -which produces a description to @racket[write] as part of a contract violation; -@racket[get-first-order], which produces a first-order predicate to be used by -@racket[contract-first-order-passes?]; @racket[get-projection], which -produces a blame-tracking projection defining the behavior of the contract; -@racket[stronger], which is a predicate that determines whether this contract -(passed in the first argument) is stronger than some other contract (passed -in the second argument) and whose default always returns @racket[#f]; - @racket[generate], which returns a thunk -that generates random values matching the contract (using @racket[contract-random-generate-fail]) -to indicate failure) or @racket[#f] to indicate -that random generation for this contract isn't supported; @racket[exercise], -which returns a function that exercises values matching the contract (e.g., -if it is a function contract, it may call the function) and a list of contracts -whose values will be generated by this process; and @racket[is-list-contract?], -which is used by @racket[flat-contract?] to determine if this contract -accepts only @racket[list?]s. +a contract. It is specified in terms of seven accessors: +@itemlist[ + @item{@racket[get-name] which produces a description to @racket[write] as part + of a contract violation;} + @item{@racket[get-first-order], which produces a first-order predicate to be + used by @racket[contract-first-order-passes?];} + @item{@racket[get-projection], which produces a blame-tracking projection + defining the behavior of the contract;} + @item{@racket[stronger], which is a predicate that determines whether this + contract (passed in the first argument) is stronger than some other + contract (passed in the second argument) and whose default always + returns @racket[#f];} + @item{@racket[generate], which returns a thunk that generates random values + matching the contract (using @racket[contract-random-generate-fail]) + to indicate failure) or @racket[#f] to indicate that random + generation for this contract isn't supported;} + @item{@racket[exercise], which returns a function that exercises values + matching the contract (e.g., if it is a function contract, it may call + the function) and a list of contracts whose values will be generated + by this process;} + @item{and @racket[is-list-contract?], which is used by @racket[flat-contract?] + to determine if this contract accepts only @racket[list?]s.} +] At least one of the @racket[late-neg-proj], @racket[proj], @racket[val-first-proj], or @racket[first-order] must be non-@racket[#f]. From 85c781452dd08bebb77ddfa452456336ddddb29e Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 30 Dec 2015 17:56:05 -0600 Subject: [PATCH 275/369] wording tweaks --- .../scribblings/reference/contracts.scrbl | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index 15d062c20a..ca946bb3e9 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -2550,27 +2550,22 @@ is expected to be the blame record for the contract on the value). (λ (c) (λ (fuel) (values void '())))] [#:list-contract? is-list-contract? (-> contract? boolean?) (λ (c) #f)]) contract-property?])]{ - - @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 the arguments for @racket[prop:contract], @racket[prop:chaperone-contract], and @racket[prop:flat-contract], respectively. A @deftech{contract property} specifies the behavior of a structure when used as -a contract. It is specified in terms of seven accessors: +a contract. It is specified in terms of seven properties: @itemlist[ @item{@racket[get-name] which produces a description to @racket[write] as part of a contract violation;} @item{@racket[get-first-order], which produces a first-order predicate to be used by @racket[contract-first-order-passes?];} - @item{@racket[get-projection], which produces a blame-tracking projection - defining the behavior of the contract;} - @item{@racket[stronger], which is a predicate that determines whether this + @item{@racket[get-late-neg-projection], which produces a blame-tracking projection + defining the behavior of the contract (The @racket[get-projection] + and @racket[get-val-first-projection] arguments also specify the projection, + but using a different signature. They are here for backwards compatibility.);} + @item{@racket[stronger], a predicate that determines whether this contract (passed in the first argument) is stronger than some other contract (passed in the second argument) and whose default always returns @racket[#f];} From e92b8610f2799602425410fa494a3cd6b022e3cf Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 30 Dec 2015 17:46:36 -0600 Subject: [PATCH 276/369] port id-set/c to late-neg --- racket/collects/syntax/id-set.rkt | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/racket/collects/syntax/id-set.rkt b/racket/collects/syntax/id-set.rkt index b5ea39c9c2..3ed3f2768d 100644 --- a/racket/collects/syntax/id-set.rkt +++ b/racket/collects/syntax/id-set.rkt @@ -106,40 +106,40 @@ (and (set-passes? s) (for/and ([e (in-set s)]) (elem-passes? e))))) -(define (flat-id-set-contract-projection ctc) +(define (flat-id-set-late-neg-contract-projection ctc) (define elem/c (id-set-contract-elem/c ctc)) (define idsettype (id-set-contract-idsettype ctc)) (define mutability (id-set-contract-mutability ctc)) (lambda (b) (define proj - ((contract-projection elem/c) (blame-add-context b "an element of"))) - (lambda (s) - (id-set-contract-check idsettype mutability b s) - (for ([e (in-set s)]) (proj e)) + ((contract-late-neg-projection elem/c) (blame-add-context b "an element of"))) + (lambda (s neg-party) + (id-set-contract-check idsettype mutability b s neg-party) + (for ([e (in-set s)]) (proj e neg-party)) s))) -(define (id-set-contract-projection ctc) +(define (id-set-late-neg-contract-projection ctc) (define elem/c (id-set-contract-elem/c ctc)) (define idsettype (id-set-contract-idsettype ctc)) (define mutability (id-set-contract-mutability ctc)) (lambda (b) (define neg-proj - ((contract-projection elem/c) (blame-add-context b "an element of" #:swap? #t))) - (lambda (s) - (id-set-contract-check idsettype mutability b s) + ((contract-late-neg-projection elem/c) (blame-add-context b "an element of" #:swap? #t))) + (lambda (s neg-party) + (id-set-contract-check idsettype mutability b s neg-party) (cond [(immutable-free-id-set? s) (chaperone-immutable-free-id-set - s (free-id-table/c neg-proj any/c #:immutable #t))] + s (free-id-table/c (λ (v) (neg-proj v neg-party)) any/c #:immutable #t))] [(mutable-free-id-set? s) (chaperone-mutable-free-id-set - s (free-id-table/c neg-proj any/c #:immutable #f))] + s (free-id-table/c (λ (v) (neg-proj v neg-party)) any/c #:immutable #f))] [(immutable-bound-id-set? s) (chaperone-immutable-bound-id-set - s (bound-id-table/c neg-proj any/c #:immutable #t))] + s (bound-id-table/c (λ (v) (neg-proj v neg-party)) any/c #:immutable #t))] [(mutable-bound-id-set? s) (chaperone-mutable-bound-id-set - s (bound-id-table/c neg-proj any/c #:immutable #f))])))) + s (bound-id-table/c (λ (v) (neg-proj v neg-party)) any/c #:immutable #f))])))) (struct flat-id-set-contract id-set-contract [] @@ -147,14 +147,14 @@ (build-flat-contract-property #:name id-set-contract-name #:first-order flat-id-set-contract-first-order - #:projection flat-id-set-contract-projection)) + #:late-neg-projection flat-id-set-late-neg-contract-projection)) (struct chaperone-id-set-contract id-set-contract [] #:property prop:chaperone-contract (build-chaperone-contract-property #:name id-set-contract-name #:first-order id-set-contract-first-order - #:projection id-set-contract-projection)) + #:late-neg-projection id-set-late-neg-contract-projection)) (define-syntax (provide-contracted-id-set-fns stx) (syntax-parse stx From d5f61238c2bf9453c7f022d39788985f35bc995a Mon Sep 17 00:00:00 2001 From: Andrew Kent Date: Tue, 29 Dec 2015 14:27:24 -0500 Subject: [PATCH 277/369] more *syntax/loc I was using match-let and got a syntax error that pointed to this file. After changing the match-let definition to use syntax/loc the error pointed to the exact spot causing the problem. Yay! I changed quite a few vanilla syntax-quotes to the *syntax/loc form... perhaps some do not need to? I'm not sure. added back nested syntax/loc --- racket/collects/racket/match/define-forms.rkt | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/racket/collects/racket/match/define-forms.rkt b/racket/collects/racket/match/define-forms.rkt index 2189982368..a3e438461b 100644 --- a/racket/collects/racket/match/define-forms.rkt +++ b/racket/collects/racket/match/define-forms.rkt @@ -55,8 +55,9 @@ (syntax-parse stx [(_ arg:expr (~and cl0 [(pats ...) rhs ...]) clauses ...) (with-syntax ([(ids ...) (generate-temporaries #'(pats ...))]) - #`(let-values ([(ids ...) arg]) - (match*/derived (ids ...) #,stx cl0 clauses ...)))])) + (quasisyntax/loc stx + (let-values ([(ids ...) arg]) + (match*/derived (ids ...) #,stx cl0 clauses ...))))])) (define-syntax (match-lambda stx) (syntax-parse stx @@ -89,20 +90,23 @@ [rhs (syntax->list #'(rhss ...))]) (define ids (generate-temporaries pats)) (values ids #`[#,ids #,rhs]))) - #`(let-values #,let-clauses + (quasisyntax/loc stx + (let-values #,let-clauses (match*/derived #,(append* idss) #,stx - [(patss ... ...) (let () body1 body ...)]))])) + [(patss ... ...) (let () body1 body ...)])))])) (define-syntax (match-let*-values stx) (syntax-parse stx [(_ () body1 body ...) - #'(let () body1 body ...)] + (syntax/loc stx (let () body1 body ...))] [(_ ([(pats ...) rhs] rest-pats ...) body1 body ...) (with-syntax ([(ids ...) (generate-temporaries #'(pats ...))]) - #`(let-values ([(ids ...) rhs]) + (quasisyntax/loc stx + (let-values ([(ids ...) rhs]) (match*/derived (ids ...) #,stx - [(pats ...) #,(syntax/loc stx (match-let*-values (rest-pats ...) - body1 body ...))])))])) + [(pats ...) #,(syntax/loc stx + (match-let*-values (rest-pats ...) + body1 body ...))]))))])) ;; there's lots of duplication here to handle named let ;; some factoring out would do a lot of good @@ -111,12 +115,14 @@ [(_ nm:id (~and clauses ([pat init-exp:expr] ...)) body1 body ...) (with-syntax* ([vars (generate-temporaries #'(pat ...))] - [loop-body #`(match*/derived vars #,stx - [(pat ...) (let () body1 body ...)])]) - #'(letrec ([nm (lambda vars loop-body)]) - (nm init-exp ...)))] + [loop-body (quasisyntax/loc stx + (match*/derived vars #,stx + [(pat ...) (let () body1 body ...)]))]) + (syntax/loc stx + (letrec ([nm (lambda vars loop-body)]) + (nm init-exp ...))))] [(_ ([pat init-exp:expr] ...) body1 body ...) - #`(match-let-values ([(pat) init-exp] ...) body1 body ...)])) + (syntax/loc stx (match-let-values ([(pat) init-exp] ...) body1 body ...))])) (define-syntax-rule (match-let* ([pat exp] ...) body1 body ...) (match-let*-values ([(pat) exp] ...) body1 body ...)) From 567679bf0a5dbe52fc718ad7c6242da0e46a8492 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 31 Dec 2015 09:21:11 -0700 Subject: [PATCH 278/369] {impersonate,chaperone}-hash: add `equal-key-proc` wrapper The optional `equal-key-proc` wrapper effectively interposes on calls to `equal?` and `equal-hash-code` for hash-table keys. --- pkgs/base/info.rkt | 2 +- .../scribblings/reference/chaperones.scrbl | 28 ++- .../tests/racket/chaperone.rktl | 127 +++++++++++- racket/src/racket/src/hash.c | 193 ++++++++++++++---- racket/src/racket/src/list.c | 66 ++++-- racket/src/racket/src/schpriv.h | 16 ++ racket/src/racket/src/schvers.h | 4 +- 7 files changed, 364 insertions(+), 72 deletions(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index 61f22b809d..34e6cdefb2 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.3.0.10") +(define version "6.3.0.11") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/pkgs/racket-doc/scribblings/reference/chaperones.scrbl b/pkgs/racket-doc/scribblings/reference/chaperones.scrbl index ec16c2cbbf..a846c478a3 100644 --- a/pkgs/racket-doc/scribblings/reference/chaperones.scrbl +++ b/pkgs/racket-doc/scribblings/reference/chaperones.scrbl @@ -446,6 +446,7 @@ or override impersonator-property values of @racket[box].} [remove-proc (hash? any/c . -> . any/c)] [key-proc (hash? any/c . -> . any/c)] [clear-proc (or/c #f (hash? . -> . any)) #f] + [equal-key-proc (or/c #f (hash? any/c . -> . any/c)) #f] [prop impersonator-property?] [prop-val any] ... ...) (and/c hash? impersonator?)]{ @@ -499,6 +500,19 @@ If @racket[clear-proc] is @racket[#f], then @racket[hash-clear] or @racket[hash-clear!] on the impersonator is implemented using @racket[hash-iterate-key] and @racket[hash-remove] or @racket[hash-remove!]. +If @racket[equal-key-proc] is not @racket[#f], it effectively +interposes on calls to @racket[equal?], @racket[equal-hash-code], and +@racket[equal-secondary-hash-code] for the keys of @racket[hash]. The +@racket[equal-key-proc] must accept as its arguments @racket[hash] and +a key that is either mapped by @racket[hash] or passed to +@racket[hash-ref], etc., where the latter has potentially been +adjusted by the corresponding @racket[ref-proc], etc@|.__| The result +is a value that is passed to @racket[equal?], +@racket[equal-hash-code], and @racket[equal-secondary-hash-code] as +needed to hash and compare keys. In the case of @racket[hash-set!] or +@racket[hash-set], the key that is passed to @racket[equal-key-proc] +is the one stored in the hash table for future lookup. + The @racket[hash-iterate-value], @racket[hash-map], or @racket[hash-for-each] functions use a combination of @racket[hash-iterate-key] and @racket[hash-ref]. If a key @@ -507,7 +521,10 @@ produced by @racket[key-proc] does not yield a value through Pairs of @racket[prop] and @racket[prop-val] (the number of arguments to @racket[impersonate-hash] must be odd) add impersonator properties -or override impersonator-property values of @racket[hash].} +or override impersonator-property values of @racket[hash]. + +@history[#:changed "6.3.0.11" @elem{Added the @racket[equal-key-proc] + argument.}]} @defproc[(impersonate-channel [channel channel?] @@ -802,6 +819,7 @@ the same value or a chaperone of the value that it is given. The [remove-proc (hash? any/c . -> . any/c)] [key-proc (hash? any/c . -> . any/c)] [clear-proc (or/c #f (hash? . -> . any)) #f] + [equal-key-proc (or/c #f (hash? any/c . -> . any/c)) #f] [prop impersonator-property?] [prop-val any] ... ...) (and/c hash? chaperone?)]{ @@ -811,8 +829,12 @@ and support for immutable hashes. The @racket[ref-proc] procedure must return a found value or a chaperone of the value. The @racket[set-proc] procedure must produce two values: the key that it is given or a chaperone of the key and the value that it is given or a -chaperone of the value. The @racket[remove-proc] and @racket[key-proc] -procedures must produce the given key or a chaperone of the key.} +chaperone of the value. The @racket[remove-proc], @racket[key-proc], +and @racket[equal-key-proc] +procedures must produce the given key or a chaperone of the key. + +@history[#:changed "6.3.0.11" @elem{Added the @racket[equal-key-proc] + argument.}]} @defproc[(chaperone-struct-type [struct-type struct-type?] [struct-info-proc procedure?] diff --git a/pkgs/racket-test-core/tests/racket/chaperone.rktl b/pkgs/racket-test-core/tests/racket/chaperone.rktl index ddee10417e..8275f6468e 100644 --- a/pkgs/racket-test-core/tests/racket/chaperone.rktl +++ b/pkgs/racket-test-core/tests/racket/chaperone.rktl @@ -1202,11 +1202,15 @@ (test #t chaperone? (mk)) (test #t chaperone? (mk #f)) (test #t chaperone? (mk (lambda (ht) (void)))) + (test #t chaperone? (mk (lambda (ht) (void)) (lambda (ht k) (void)))) + (test #t chaperone? (mk #f (lambda (ht k) (void)))) (err/rt-test (mk (lambda (a b) (void)))) (define-values (prop:blue blue? blue-ref) (make-impersonator-property 'blue)) (test #t chaperone? (mk prop:blue 'ok)) (test #t chaperone? (mk #f prop:blue 'ok)) - (err/rt-test (mk (lambda (a b) (void)) prop:blue 'ok))) + (test #t chaperone? (mk #f #f prop:blue 'ok)) + (err/rt-test (mk (lambda (a b) (void)) prop:blue 'ok)) + (err/rt-test (mk #f (lambda (a) (void)) prop:blue 'ok))) (for-each (lambda (make-hash) @@ -1470,7 +1474,124 @@ (define ht4 (hash-clear ht2)) (test #t values hit?) (test 0 hash-count ht4)))) - + +;; Check use of equal-key-proc argument: +(as-chaperone-or-impersonator + ([chaperone-hash impersonate-hash] + [chaperone-procedure impersonate-procedure]) + (define saw null) + (define (mk ht) + (chaperone-hash ht + (lambda (h k) + (values k + (lambda (h k v) v))) + (lambda (h k v) + (values k v)) + (lambda (h k) k) + (lambda (h k) k) + #f + (lambda (h k) (set! saw (cons k saw)) k))) + (for ([make-hash (in-list (list make-hash make-weak-hash))]) + (set! saw null) + (define ht (make-hash)) + (define cht (mk ht)) + (hash-set! cht "x" 1) + (test '("x") values saw) + (define new-x (make-string 1 #\x)) + (void (hash-ref cht new-x)) + (test '("x" "x" "x") values saw) + (test #t 'new-x (and (member new-x saw) #t)) + (set! saw null) + (hash-set! cht new-x 5) + (test '("x" "x") values saw) + (test #t 'new-x (and (member new-x saw) #t)) + (set! saw null) + (hash-remove! cht new-x) + (test '("x" "x") values saw) + (test #t 'new-x (and (member new-x saw) #t))) + (unless (eq? chaperone-hash impersonate-hash) + (for ([hash (in-list (list hash))]) + (set! saw null) + (define ht (mk (hash))) + (define ht1 (hash-set ht "x" 1)) + (test '("x") values saw) + (define new-x (make-string 1 #\x)) + (void (hash-ref ht1 new-x)) + (test '("x" "x" "x") values saw) + (test #t 'new-x (and (member new-x saw) #t)) + (set! saw null) + (void (hash-set ht1 new-x 5)) + (test '("x" "x") values saw) + (test #t 'new-x (and (member new-x saw) #t)) + (set! saw null) + (void (hash-remove ht1 new-x)) + (test '("x" "x") values saw) + (test #t 'new-x (and (member new-x saw) #t))))) + +;; Check that hash table stores given key while +;; coercing key for hashing and equality: +(let () + (define (mk ht) + (impersonate-hash ht + (lambda (h k) + (values k + (lambda (h k v) v))) + (lambda (h k v) + (values k v)) + (lambda (h k) k) + (lambda (h k) k) + #f + (lambda (h k) (inexact->exact (floor k))))) + (for ([make-hash (in-list (list make-hash make-weak-hash))]) + (define ht (make-hash)) + (define cht (mk ht)) + (hash-set! cht 1.2 'one) + (test 'one hash-ref cht 1.3 #f) + (test #f hash-ref ht 1.3 #f) + ;; Trying to find 1.2 in `ht` likely won't work, because the hash code was mangled + (test '(1.2) hash-keys ht) + (test '(1.2) hash-keys cht) + (hash-set! cht 1.3 'two) + (test 'two hash-ref cht 1.2 #f)) + (let-values ([(prop:blue blue? blue-ref) (make-impersonator-property 'blue)]) + (define (mk ht) + (chaperone-hash ht + (lambda (h k) + (values k + (lambda (h k v) v))) + (lambda (h k v) + (values k v)) + (lambda (h k) k) + (lambda (h k) k) + #f + (lambda (h k) (chaperone-vector k + (lambda (vec i v) + (if (= i 1) + (error "ONE") + v)) + (lambda (vec i v) v))))) + (define (one-exn? s) (regexp-match? #rx"ONE" (exn-message s))) + (let () + (define cht (mk (hash))) + (err/rt-test (hash-set cht (vector 1 2) 'vec) one-exn?) + (define ht1 (hash-set cht (vector 1) 'vec)) + (test 'vec hash-ref ht1 (vector 1) #f) + (test #f hash-ref ht1 (vector 2) #f)) + (for ([make-hash (in-list (list make-hash make-weak-hash))]) + (define ht (make-hash)) + (define cht (mk ht)) + (define key (vector 1 2)) + (define key7 (vector 7)) + (hash-set! cht key7 'vec7) + (test 'vec7 hash-ref cht (vector 7) #f) + (test 'vec7 hash-ref ht (vector 7) #f) + (hash-set! ht key 'vec2) + (test 'vec2 hash-ref ht (vector 1 2)) + (err/rt-test (hash-ref cht (vector 1 2) #f) one-exn?) + (test 2 length (hash-keys cht)) ; can extract keys without hashing or comparing + (test 'vec2 hash-ref ht key) + (test 'vec7 hash-ref ht key7)))) + ;; ---------------------------------------- ;; Check broken key impersonator: @@ -2062,7 +2183,7 @@ #:a "x")) ;; ---------------------------------------- -;; Check that importantor transformations are applied for printing: +;; Check that impersonator transformations are applied for printing: (let () (define ht diff --git a/racket/src/racket/src/hash.c b/racket/src/racket/src/hash.c index ab9d0fd289..8bc1043062 100644 --- a/racket/src/racket/src/hash.c +++ b/racket/src/racket/src/hash.c @@ -164,6 +164,49 @@ static void string_hash_indices(void *_key, intptr_t *_h, intptr_t *_h2) *_h2 = to_signed_hash(h2); } +/*========================================================================*/ +/* equality with wraps */ +/*========================================================================*/ + +static Scheme_Object *apply_equal_key_wraps(Scheme_Object *key, Scheme_Object *key_wraps) +{ + if (key_wraps) { + GC_CAN_IGNORE const char *who = (const char *)SCHEME_CAR(key_wraps); + Scheme_Chaperone *px; + Scheme_Object *a[2], *red; + + key_wraps = SCHEME_CDR(key_wraps); + while (!SCHEME_NULLP(key_wraps)) { + px = (Scheme_Chaperone *)SCHEME_CAR(key_wraps); + + red = SCHEME_BOX_VAL(px->redirects); + red = SCHEME_VEC_ELS(red)[5]; + + a[0] = px->prev; + a[1] = key; + key = _scheme_apply(red, 2, a); + + if (!(SCHEME_CHAPERONE_FLAGS(px) & SCHEME_CHAPERONE_IS_IMPERSONATOR) + && !scheme_chaperone_of(key, a[1])) { + scheme_wrong_chaperoned(who, "key", a[1], key); + return 0; + } + + key_wraps = SCHEME_CDR(key_wraps); + } + } + + return key; +} + +static int equal_w_key_wraps(Scheme_Object *ekey, Scheme_Object *tkey, Scheme_Object *key_wraps) +{ + if (key_wraps) + tkey = apply_equal_key_wraps(tkey, key_wraps); + + return scheme_equal(ekey, tkey); +} + /*========================================================================*/ /* normal hash table */ /*========================================================================*/ @@ -201,9 +244,10 @@ void scheme_clear_hash_table(Scheme_Hash_Table *ht) ht->mcount = 0; } -static Scheme_Object *do_hash(Scheme_Hash_Table *table, Scheme_Object *key, int set, Scheme_Object *val) +static Scheme_Object *do_hash(Scheme_Hash_Table *table, Scheme_Object *key, int set, Scheme_Object *val, + Scheme_Object *key_wraps) { - Scheme_Object *tkey, **keys; + Scheme_Object *tkey, *ekey, **keys; intptr_t hx, h2x; hash_v_t h, h2, useme = 0; uintptr_t mask; @@ -214,8 +258,12 @@ static Scheme_Object *do_hash(Scheme_Hash_Table *table, Scheme_Object *key, int if (table->make_hash_indices) { if (table->compare == scheme_compare_equal) { + if (key_wraps) + ekey = apply_equal_key_wraps(key, key_wraps); + else + ekey = key; h2 = 0; - hx = scheme_equal_hash_key(key); + hx = scheme_equal_hash_key(ekey); h = to_unsigned_hash(hx) & mask; } else { GC_CAN_IGNORE intptr_t *_h2x; @@ -240,7 +288,7 @@ static Scheme_Object *do_hash(Scheme_Hash_Table *table, Scheme_Object *key, int if (table->compare) { if (table->compare == scheme_compare_equal) { - /* Direct calls can be significant faster than indirect */ + /* Direct calls can be significantly faster than indirect */ scheme_hash_request_count++; while ((tkey = keys[HASH_TO_ARRAY_INDEX(h, mask)])) { if (SAME_PTR(tkey, GONE)) { @@ -248,7 +296,7 @@ static Scheme_Object *do_hash(Scheme_Hash_Table *table, Scheme_Object *key, int useme = h; set = 1; } - } else if (scheme_equal(tkey, key)) { + } else if (equal_w_key_wraps(ekey, tkey, key_wraps)) { if (set) { table->vals[HASH_TO_ARRAY_INDEX(h, mask)] = val; if (!val) { @@ -261,7 +309,7 @@ static Scheme_Object *do_hash(Scheme_Hash_Table *table, Scheme_Object *key, int } scheme_hash_iteration_count++; if (!h2) { - h2x = scheme_equal_hash_key2(key); + h2x = scheme_equal_hash_key2(ekey); h2 = (to_unsigned_hash(h2x) & (table->size - 1)) | 1; } h = (h + h2) & mask; @@ -346,7 +394,7 @@ static Scheme_Object *do_hash(Scheme_Hash_Table *table, Scheme_Object *key, int table->mcount = 0; for (i = 0; i < oldsize; i++) { if (oldkeys[i] && !SAME_PTR(oldkeys[i], GONE)) - do_hash(table, oldkeys[i], 2, oldvals[i]); + do_hash(table, oldkeys[i], 2, oldvals[i], key_wraps); } goto rehash_key; @@ -405,7 +453,7 @@ static Scheme_Object *do_hash_set(Scheme_Hash_Table *table, Scheme_Object *key, h = useme; else if (table->mcount * FILL_FACTOR >= table->size) { /* Use slow path to grow table: */ - return do_hash(table, key, 2, val); + return do_hash(table, key, 2, val, NULL); } else { table->mcount++; } @@ -446,7 +494,8 @@ XFORM_NONGCING static Scheme_Object *do_hash_get(Scheme_Hash_Table *table, Schem return NULL; } -void scheme_hash_set(Scheme_Hash_Table *table, Scheme_Object *key, Scheme_Object *val) +void scheme_hash_set_w_key_wraps(Scheme_Hash_Table *table, Scheme_Object *key, Scheme_Object *val, + Scheme_Object *key_wraps) { if (!table->vals) { Scheme_Object **ba; @@ -460,21 +509,32 @@ void scheme_hash_set(Scheme_Hash_Table *table, Scheme_Object *key, Scheme_Object } if (table->make_hash_indices) - do_hash(table, key, 2, val); + do_hash(table, key, 2, val, key_wraps); else do_hash_set(table, key, val); } -Scheme_Object *scheme_hash_get(Scheme_Hash_Table *table, Scheme_Object *key) +void scheme_hash_set(Scheme_Hash_Table *table, Scheme_Object *key, Scheme_Object *val) +{ + scheme_hash_set_w_key_wraps(table, key, val, NULL); +} + +Scheme_Object *scheme_hash_get_w_key_wraps(Scheme_Hash_Table *table, Scheme_Object *key, + Scheme_Object *key_wraps) { if (!table->vals) return NULL; else if (table->make_hash_indices) - return do_hash(table, key, 0, NULL); + return do_hash(table, key, 0, NULL, key_wraps); else return do_hash_get(table, key); } +Scheme_Object *scheme_hash_get(Scheme_Hash_Table *table, Scheme_Object *key) +{ + return scheme_hash_get_w_key_wraps(table, key, NULL); +} + Scheme_Object *scheme_eq_hash_get(Scheme_Hash_Table *table, Scheme_Object *key) /* Specialized to allow XFORM_NONGCING */ { @@ -692,10 +752,12 @@ allocate_bucket (Scheme_Bucket_Table *table, const char *key, void *val) } static Scheme_Bucket * -get_bucket (Scheme_Bucket_Table *table, const char *key, int add, Scheme_Bucket *b) +get_bucket (Scheme_Bucket_Table *table, const char *key, int add, Scheme_Bucket *b, + Scheme_Object *key_wraps) { intptr_t hx, h2x; hash_v_t h, h2; + void *ekey; Scheme_Bucket *bucket; Compare_Proc compare = table->compare; uintptr_t mask; @@ -705,7 +767,11 @@ get_bucket (Scheme_Bucket_Table *table, const char *key, int add, Scheme_Bucket mask = table->size - 1; if (table->make_hash_indices) { - table->make_hash_indices((void *)key, &hx, &h2x); + if (key_wraps) + ekey = apply_equal_key_wraps((Scheme_Object *)key, key_wraps); + else + ekey = (void *)key; + table->make_hash_indices(ekey, &hx, &h2x); h = to_unsigned_hash(hx) & mask; h2 = to_unsigned_hash(h2x) & mask; } else { @@ -728,7 +794,10 @@ get_bucket (Scheme_Bucket_Table *table, const char *key, int add, Scheme_Bucket reuse_bucket = h + 1; } else if (SAME_PTR(hk, key)) return bucket; - else if (compare && !compare((void *)hk, (void *)key)) + else if (key_wraps) { + if (equal_w_key_wraps((Scheme_Object *)ekey, (Scheme_Object *)hk, key_wraps)) + return bucket; + } else if (compare && !compare((void *)hk, ekey)) return bucket; } else if (add) break; @@ -747,7 +816,10 @@ get_bucket (Scheme_Bucket_Table *table, const char *key, int add, Scheme_Bucket while ((bucket = table->buckets[HASH_TO_ARRAY_INDEX(h, mask)])) { if (SAME_PTR(bucket->key, key)) return bucket; - else if (compare && !compare((void *)bucket->key, (void *)key)) + else if (key_wraps) { + if (equal_w_key_wraps((Scheme_Object *)ekey, (Scheme_Object *)bucket->key, key_wraps)) + return bucket; + } else if (compare && !compare((void *)bucket->key, (void *)key)) return bucket; scheme_hash_iteration_count++; h = (h + h2) & mask; @@ -800,12 +872,12 @@ get_bucket (Scheme_Bucket_Table *table, const char *key, int add, Scheme_Bucket if (table->weak) { for (i = 0; i < oldsize; i++) { if (old[i] && old[i]->key && HT_EXTRACT_WEAK(old[i]->key)) - get_bucket(table, (char *)HT_EXTRACT_WEAK(old[i]->key), 1, old[i]); + get_bucket(table, (char *)HT_EXTRACT_WEAK(old[i]->key), 1, old[i], key_wraps); } } else { for (i = 0; i < oldsize; i++) { if (old[i] && old[i]->key) - get_bucket(table, old[i]->key, 1, old[i]); + get_bucket(table, old[i]->key, 1, old[i], key_wraps); } } @@ -825,28 +897,35 @@ get_bucket (Scheme_Bucket_Table *table, const char *key, int add, Scheme_Bucket } Scheme_Bucket * -scheme_bucket_or_null_from_table (Scheme_Bucket_Table *table, const char *key, int add) +scheme_bucket_or_null_from_table_w_key_wraps (Scheme_Bucket_Table *table, const char *key, int add, + Scheme_Object *key_wraps) { Scheme_Bucket *b; - b = get_bucket(table, key, add, NULL); + b = get_bucket(table, key, add, NULL, key_wraps); return b; } +Scheme_Bucket * +scheme_bucket_or_null_from_table (Scheme_Bucket_Table *table, const char *key, int add) +{ + return scheme_bucket_or_null_from_table_w_key_wraps(table, key, add, NULL); +} + Scheme_Bucket * scheme_bucket_from_table (Scheme_Bucket_Table *table, const char *key) { - return scheme_bucket_or_null_from_table(table, key, 1); + return scheme_bucket_or_null_from_table_w_key_wraps(table, key, 1, NULL); } void -scheme_add_to_table (Scheme_Bucket_Table *table, const char *key, void *val, - int constant) +scheme_add_to_table_w_key_wraps (Scheme_Bucket_Table *table, const char *key, void *val, + int constant, Scheme_Object *key_wraps) { Scheme_Bucket *b; - b = get_bucket(table, key, 1, NULL); + b = get_bucket(table, key, 1, NULL, key_wraps); if (val) b->val = val; @@ -854,17 +933,25 @@ scheme_add_to_table (Scheme_Bucket_Table *table, const char *key, void *val, ((Scheme_Bucket_With_Flags *)b)->flags |= GLOB_IS_CONST; } +void +scheme_add_to_table (Scheme_Bucket_Table *table, const char *key, void *val, + int constant) +{ + scheme_add_to_table_w_key_wraps(table, key, val, constant, NULL); +} + void scheme_add_bucket_to_table(Scheme_Bucket_Table *table, Scheme_Bucket *b) { - get_bucket(table, table->weak ? (char *)HT_EXTRACT_WEAK(b->key) : b->key, 1, b); + get_bucket(table, table->weak ? (char *)HT_EXTRACT_WEAK(b->key) : b->key, 1, b, NULL); } void * -scheme_lookup_in_table (Scheme_Bucket_Table *table, const char *key) +scheme_lookup_in_table_w_key_wraps (Scheme_Bucket_Table *table, const char *key, + Scheme_Object *key_wraps) { Scheme_Bucket *bucket; - bucket = get_bucket(table, key, 0, NULL); + bucket = get_bucket(table, key, 0, NULL, key_wraps); if (bucket) return bucket->val; @@ -872,12 +959,18 @@ scheme_lookup_in_table (Scheme_Bucket_Table *table, const char *key) return NULL; } +void * +scheme_lookup_in_table (Scheme_Bucket_Table *table, const char *key) +{ + return scheme_lookup_in_table_w_key_wraps(table, key, NULL); +} + void scheme_change_in_table (Scheme_Bucket_Table *table, const char *key, void *naya) { Scheme_Bucket *bucket; - bucket = get_bucket(table, key, 0, NULL); + bucket = get_bucket(table, key, 0, NULL, NULL); if (bucket) bucket->val = naya; @@ -2607,7 +2700,8 @@ int scheme_hash_tree_index(Scheme_Hash_Tree *ht, mzlonglong pos, Scheme_Object * } static Scheme_Object *hamt_linear_search(Scheme_Hash_Tree *tree, int stype, Scheme_Object *key, - GC_CAN_IGNORE int *_i, GC_CAN_IGNORE uintptr_t *_code) + GC_CAN_IGNORE int *_i, GC_CAN_IGNORE uintptr_t *_code, + Scheme_Object *key_wraps) /* in the case of hash collisions, we put the colliding elements in a tree that uses integers as keys; we have to search through the tree for keys, but the advatange of using a HAMT (instead of a list) is @@ -2624,7 +2718,7 @@ static Scheme_Object *hamt_linear_search(Scheme_Hash_Tree *tree, int stype, Sche return found_val; } } else if (stype == scheme_hash_tree_type) { - if (scheme_equal(key, found_key)) { + if (equal_w_key_wraps(key, found_key, key_wraps)) { if (_i) *_i = i; return found_val; } @@ -2779,7 +2873,8 @@ Scheme_Object *scheme_eq_hash_tree_get(Scheme_Hash_Tree *tree, Scheme_Object *ke return NULL; } -Scheme_Object *scheme_hash_tree_get(Scheme_Hash_Tree *tree, Scheme_Object *key) +Scheme_Object *scheme_hash_tree_get_w_key_wraps(Scheme_Hash_Tree *tree, Scheme_Object *key, + Scheme_Object *key_wraps) { uintptr_t h; int stype, pos; @@ -2789,9 +2884,11 @@ Scheme_Object *scheme_hash_tree_get(Scheme_Hash_Tree *tree, Scheme_Object *key) if (stype == scheme_eq_hash_tree_type) return scheme_eq_hash_tree_get(tree, key); - else if (stype == scheme_hash_tree_type) + else if (stype == scheme_hash_tree_type) { + if (key_wraps) + key = apply_equal_key_wraps(key, key_wraps); h = to_unsigned_hash(scheme_equal_hash_key(key)); - else + } else h = to_unsigned_hash(scheme_eqv_hash_key(key)); tree = hamt_assoc(tree, h, &pos, 0); @@ -2801,10 +2898,10 @@ Scheme_Object *scheme_hash_tree_get(Scheme_Hash_Tree *tree, Scheme_Object *key) if (HASHTR_COLLISIONP(tree->els[pos])) { /* hash collision; linear search in subtree */ uintptr_t code; - return hamt_linear_search((Scheme_Hash_Tree *)tree->els[pos], stype, key, NULL, &code); + return hamt_linear_search((Scheme_Hash_Tree *)tree->els[pos], stype, key, NULL, &code, key_wraps); } else { if (stype == scheme_hash_tree_type) { - if (scheme_equal(key, tree->els[pos])) + if (equal_w_key_wraps(key, tree->els[pos], key_wraps)) return mzHAMT_VAL(tree, pos); } else { if (scheme_eqv(key, tree->els[pos])) @@ -2815,20 +2912,29 @@ Scheme_Object *scheme_hash_tree_get(Scheme_Hash_Tree *tree, Scheme_Object *key) return NULL; } -Scheme_Hash_Tree *scheme_hash_tree_set(Scheme_Hash_Tree *tree, Scheme_Object *key, Scheme_Object *val) +Scheme_Object *scheme_hash_tree_get(Scheme_Hash_Tree *tree, Scheme_Object *key) +{ + return scheme_hash_tree_get_w_key_wraps(tree, key, NULL); +} + +Scheme_Hash_Tree *scheme_hash_tree_set_w_key_wraps(Scheme_Hash_Tree *tree, Scheme_Object *key, Scheme_Object *val, + Scheme_Object *key_wraps) /* val == NULL => remove */ { uintptr_t h; Scheme_Hash_Tree *in_tree; + Scheme_Object *ekey = key; int stype, pos; stype = SCHEME_TYPE(resolve_placeholder(tree)); if (stype == scheme_eq_hash_tree_type) h = PTR_TO_LONG((Scheme_Object *)key); - else if (stype == scheme_hash_tree_type) - h = to_unsigned_hash(scheme_equal_hash_key(key)); - else + else if (stype == scheme_hash_tree_type) { + if (key_wraps) + ekey = apply_equal_key_wraps(ekey, key_wraps); + h = to_unsigned_hash(scheme_equal_hash_key(ekey)); + } else h = to_unsigned_hash(scheme_eqv_hash_key(key)); in_tree = hamt_assoc(resolve_placeholder(tree), h, &pos, 0); @@ -2847,7 +2953,7 @@ Scheme_Hash_Tree *scheme_hash_tree_set(Scheme_Hash_Tree *tree, Scheme_Object *ke int i, inc; uintptr_t code; in_tree = (Scheme_Hash_Tree *)in_tree->els[pos]; - if (hamt_linear_search(in_tree, stype, key, &i, &code)) { + if (hamt_linear_search(in_tree, stype, key, &i, &code, key_wraps)) { /* key is part of the current collision */ if (!val) { if (in_tree->count == 2) { @@ -2885,7 +2991,7 @@ Scheme_Hash_Tree *scheme_hash_tree_set(Scheme_Hash_Tree *tree, Scheme_Object *ke if (stype == scheme_eq_hash_tree_type) same = SAME_OBJ(key, in_tree->els[pos]); else if (stype == scheme_hash_tree_type) - same = scheme_equal(key, in_tree->els[pos]); + same = equal_w_key_wraps(ekey, in_tree->els[pos], key_wraps); else same = scheme_eqv(key, in_tree->els[pos]); @@ -2921,6 +3027,11 @@ Scheme_Hash_Tree *scheme_hash_tree_set(Scheme_Hash_Tree *tree, Scheme_Object *ke } } +Scheme_Hash_Tree *scheme_hash_tree_set(Scheme_Hash_Tree *tree, Scheme_Object *key, Scheme_Object *val) +{ + return scheme_hash_tree_set_w_key_wraps(tree, key, val, NULL); +} + static int hamt_equal_entries(int stype, void *eql_data, Scheme_Object *k1, Scheme_Object *v1, Scheme_Object *k2, Scheme_Object *v2) diff --git a/racket/src/racket/src/list.c b/racket/src/racket/src/list.c index d253e78449..ad9f007de0 100644 --- a/racket/src/racket/src/list.c +++ b/racket/src/racket/src/list.c @@ -2944,7 +2944,7 @@ static Scheme_Object *do_chaperone_hash(const char *name, int is_impersonator, i { Scheme_Chaperone *px; Scheme_Object *val = argv[0]; - Scheme_Object *redirects, *clear; + Scheme_Object *redirects, *clear, *equal_key_wrap; Scheme_Hash_Tree *props; int start_props = 5; @@ -2967,15 +2967,23 @@ static Scheme_Object *do_chaperone_hash(const char *name, int is_impersonator, i } else clear = scheme_false; + if ((argc > 6) && (SCHEME_FALSEP(argv[6]) || SCHEME_PROCP(argv[6]))) { + scheme_check_proc_arity2(name, 2, 6, argc, argv, 1); /* clear */ + equal_key_wrap = argv[6]; + start_props++; + } else + equal_key_wrap = scheme_false; + /* The allocation of this vector is used to detect when two chaperoned immutable hash tables can be `{chaperone,impersonator}-of?` when they're not eq. */ - redirects = scheme_make_vector(5, NULL); + redirects = scheme_make_vector(6, NULL); SCHEME_VEC_ELS(redirects)[0] = argv[1]; SCHEME_VEC_ELS(redirects)[1] = argv[2]; SCHEME_VEC_ELS(redirects)[2] = argv[3]; SCHEME_VEC_ELS(redirects)[3] = argv[4]; SCHEME_VEC_ELS(redirects)[4] = clear; + SCHEME_VEC_ELS(redirects)[5] = equal_key_wrap; redirects = scheme_box(redirects); /* so it doesn't look like a struct chaperone */ props = scheme_parse_chaperone_props(name, start_props, argc, argv); @@ -3019,7 +3027,7 @@ static Scheme_Object *transfer_chaperone(Scheme_Object *chaperone, Scheme_Object } static Scheme_Object *chaperone_hash_op(const char *who, Scheme_Object *o, Scheme_Object *k, - Scheme_Object *v, int mode); + Scheme_Object *v, int mode, Scheme_Object *key_wraps); static Scheme_Object *chaperone_hash_op_k(void) { @@ -3028,13 +3036,15 @@ static Scheme_Object *chaperone_hash_op_k(void) Scheme_Object *k = (Scheme_Object *)p->ku.k.p2; Scheme_Object *v = (Scheme_Object *)p->ku.k.p3; const char *who = (const char *)p->ku.k.p4; + Scheme_Object *key_wraps = (Scheme_Object *)p->ku.k.p5; 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; - o = chaperone_hash_op(who, o, k, v, p->ku.k.i1); + o = chaperone_hash_op(who, o, k, v, p->ku.k.i1, key_wraps); if (!o) return scheme_false; @@ -3043,7 +3053,7 @@ static Scheme_Object *chaperone_hash_op_k(void) } static Scheme_Object *chaperone_hash_op_overflow(const char *who, Scheme_Object *o, Scheme_Object *k, - Scheme_Object *v, int mode) + Scheme_Object *v, int mode, Scheme_Object *key_wraps) { Scheme_Thread *p = scheme_current_thread; @@ -3052,6 +3062,7 @@ static Scheme_Object *chaperone_hash_op_overflow(const char *who, Scheme_Object p->ku.k.p3 = (void *)v; p->ku.k.p4 = (void *)who; p->ku.k.i1 = mode; + p->ku.k.p5 = (void *)key_wraps; o = scheme_handle_stack_overflow(chaperone_hash_op_k); @@ -3062,26 +3073,30 @@ static Scheme_Object *chaperone_hash_op_overflow(const char *who, Scheme_Object } static Scheme_Object *chaperone_hash_op(const char *who, Scheme_Object *o, Scheme_Object *k, - Scheme_Object *v, int mode) + Scheme_Object *v, int mode, Scheme_Object *key_wraps) { Scheme_Object *wraps = NULL; while (1) { if (!SCHEME_NP_CHAPERONEP(o)) { + if (SCHEME_NULLP(key_wraps)) + key_wraps = NULL; + else + key_wraps = scheme_make_raw_pair((Scheme_Object *)who, key_wraps); if (mode == 0) { /* hash-ref */ if (SCHEME_HASHTP(o)) - return scheme_hash_get((Scheme_Hash_Table *)o, k); + return scheme_hash_get_w_key_wraps((Scheme_Hash_Table *)o, k, key_wraps); else if (SCHEME_HASHTRP(o)) - return scheme_hash_tree_get((Scheme_Hash_Tree *)o, k); + return scheme_hash_tree_get_w_key_wraps((Scheme_Hash_Tree *)o, k, key_wraps); else - return scheme_lookup_in_table((Scheme_Bucket_Table *)o, (const char *)k); + return scheme_lookup_in_table_w_key_wraps((Scheme_Bucket_Table *)o, (const char *)k, key_wraps); } else if ((mode == 1) || (mode == 2)) { /* hash-set! or hash-remove! */ if (SCHEME_HASHTP(o)) - scheme_hash_set((Scheme_Hash_Table *)o, k, v); + scheme_hash_set_w_key_wraps((Scheme_Hash_Table *)o, k, v, key_wraps); else if (SCHEME_HASHTRP(o)) { - o = (Scheme_Object *)scheme_hash_tree_set((Scheme_Hash_Tree *)o, k, v); + o = (Scheme_Object *)scheme_hash_tree_set_w_key_wraps((Scheme_Hash_Tree *)o, k, v, key_wraps); while (wraps) { o = transfer_chaperone(SCHEME_CAR(wraps), o); wraps = SCHEME_CDR(wraps); @@ -3089,13 +3104,13 @@ static Scheme_Object *chaperone_hash_op(const char *who, Scheme_Object *o, Schem return o; } else if (!v) { Scheme_Bucket *b; - b = scheme_bucket_or_null_from_table((Scheme_Bucket_Table *)o, (char *)k, 0); + b = scheme_bucket_or_null_from_table_w_key_wraps((Scheme_Bucket_Table *)o, (char *)k, 0, key_wraps); if (b) { HT_EXTRACT_WEAK(b->key) = NULL; b->val = NULL; } } else - scheme_add_to_table((Scheme_Bucket_Table *)o, (const char *)k, v, 0); + scheme_add_to_table_w_key_wraps((Scheme_Bucket_Table *)o, (const char *)k, v, 0, key_wraps); return scheme_void; } else if (mode == 3) return k; @@ -3119,14 +3134,21 @@ static Scheme_Object *chaperone_hash_op(const char *who, Scheme_Object *o, Schem #ifdef DO_STACK_CHECK { # include "mzstkchk.h" - return chaperone_hash_op_overflow(who, o, k, v, mode); + return chaperone_hash_op_overflow(who, o, k, v, mode, key_wraps); } #endif + if ((mode != 3) && (mode != 4)) { + red = SCHEME_BOX_VAL(px->redirects); + red = SCHEME_VEC_ELS(red)[5]; + if (!SCHEME_FALSEP(red)) + key_wraps = scheme_make_pair((Scheme_Object *)px, key_wraps); + } + if (mode == 0) orig = NULL; else if (mode == 3) { - orig = chaperone_hash_op(who, px->prev, k, v, mode); + orig = chaperone_hash_op(who, px->prev, k, v, mode, key_wraps); k = orig; } else if (mode == 2) orig = k; @@ -3196,7 +3218,7 @@ static Scheme_Object *chaperone_hash_op(const char *who, Scheme_Object *o, Schem who, red); - orig = chaperone_hash_op(who, px->prev, k, v, mode); + orig = chaperone_hash_op(who, px->prev, k, v, mode, key_wraps); if (!orig) return NULL; /* hash-ref */ @@ -3240,27 +3262,27 @@ static Scheme_Object *chaperone_hash_op(const char *who, Scheme_Object *o, Schem Scheme_Object *scheme_chaperone_hash_get(Scheme_Object *table, Scheme_Object *key) { - return chaperone_hash_op("hash-ref", table, key, NULL, 0); + return chaperone_hash_op("hash-ref", table, key, NULL, 0, scheme_null); } void scheme_chaperone_hash_set(Scheme_Object *table, Scheme_Object *key, Scheme_Object *val) { - (void)chaperone_hash_op(val ? "hash-set!" : "hash-remove!", table, key, val, val ? 1 : 2); + (void)chaperone_hash_op(val ? "hash-set!" : "hash-remove!", table, key, val, val ? 1 : 2, scheme_null); } Scheme_Object *chaperone_hash_tree_set(Scheme_Object *table, Scheme_Object *key, Scheme_Object *val) { - return chaperone_hash_op(val ? "hash-set" : "hash-remove", table, key, val, val ? 1 : 2); + return chaperone_hash_op(val ? "hash-set" : "hash-remove", table, key, val, val ? 1 : 2, scheme_null); } static Scheme_Object *chaperone_hash_key(const char *name, Scheme_Object *table, Scheme_Object *key) { - return chaperone_hash_op(name, table, key, NULL, 3); + return chaperone_hash_op(name, table, key, NULL, 3, scheme_null); } static Scheme_Object *chaperone_hash_clear(const char *name, Scheme_Object *table) { - return chaperone_hash_op(name, table, NULL, NULL, 4); + return chaperone_hash_op(name, table, NULL, NULL, 4, scheme_null); } Scheme_Object *scheme_chaperone_hash_traversal_get(Scheme_Object *table, Scheme_Object *key, @@ -3268,7 +3290,7 @@ Scheme_Object *scheme_chaperone_hash_traversal_get(Scheme_Object *table, Scheme_ { key = chaperone_hash_key("hash-table-iterate-key", table, key); *alt_key = key; - return chaperone_hash_op("hash-ref", table, key, NULL, 0); + return chaperone_hash_op("hash-ref", table, key, NULL, 0, scheme_null); } Scheme_Object *scheme_chaperone_hash_table_copy(Scheme_Object *obj) diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index b536986f5d..17b13f9bc5 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -597,6 +597,22 @@ Scheme_Object *scheme_hash_table_iterate_next(int argc, Scheme_Object *argv[]); Scheme_Object *scheme_hash_table_iterate_value(int argc, Scheme_Object *argv[]); Scheme_Object *scheme_hash_table_iterate_key(int argc, Scheme_Object *argv[]); +Scheme_Object *scheme_hash_get_w_key_wraps(Scheme_Hash_Table *table, Scheme_Object *key, + Scheme_Object *key_wraps); +void scheme_hash_set_w_key_wraps(Scheme_Hash_Table *table, Scheme_Object *key, Scheme_Object *val, + Scheme_Object *key_wraps); +Scheme_Bucket *scheme_bucket_or_null_from_table_w_key_wraps(Scheme_Bucket_Table *table, + const char *key, int add, + Scheme_Object *key_wraps); +void scheme_add_to_table_w_key_wraps(Scheme_Bucket_Table *table, const char *key, void *val, + int constant, Scheme_Object *key_wraps); +void *scheme_lookup_in_table_w_key_wraps(Scheme_Bucket_Table *table, const char *key, + Scheme_Object *key_wraps); +Scheme_Object *scheme_hash_tree_get_w_key_wraps(Scheme_Hash_Tree *tree, Scheme_Object *key, + Scheme_Object *key_wraps); +Scheme_Hash_Tree *scheme_hash_tree_set_w_key_wraps(Scheme_Hash_Tree *tree, Scheme_Object *key, Scheme_Object *val, + Scheme_Object *key_wraps); + /*========================================================================*/ /* thread state and maintenance */ /*========================================================================*/ diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 7224f9d8be..b7a833417f 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.10" +#define MZSCHEME_VERSION "6.3.0.11" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 3 #define MZSCHEME_VERSION_Z 0 -#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) From 357b692d3391c999e5b9783bf69858371dd59eb3 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 31 Dec 2015 15:33:59 -0600 Subject: [PATCH 279/369] fix typo --- pkgs/racket-doc/scribblings/reference/chaperones.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/chaperones.scrbl b/pkgs/racket-doc/scribblings/reference/chaperones.scrbl index a846c478a3..5e62f45f26 100644 --- a/pkgs/racket-doc/scribblings/reference/chaperones.scrbl +++ b/pkgs/racket-doc/scribblings/reference/chaperones.scrbl @@ -462,7 +462,7 @@ In addition, operations like @racket[hash-iterate-key] or @racket[hash-map], which extract keys from the table, use @racket[key-proc] to filter keys extracted from the table. Operations like @racket[hash-iterate-value] or -@racket[hash-iterate-map] implicitly use @racket[hash-ref] and +@racket[hash-map] implicitly use @racket[hash-ref] and therefore redirect through @racket[ref-proc]. The @racket[ref-proc] must accept @racket[hash] and a key passed From 110f1bd9b0821a42f414439b65cbc1bcc4c78775 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 31 Dec 2015 15:36:33 -0600 Subject: [PATCH 280/369] different, more likely fix --- pkgs/racket-doc/scribblings/reference/chaperones.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/chaperones.scrbl b/pkgs/racket-doc/scribblings/reference/chaperones.scrbl index 5e62f45f26..432ecf9e4c 100644 --- a/pkgs/racket-doc/scribblings/reference/chaperones.scrbl +++ b/pkgs/racket-doc/scribblings/reference/chaperones.scrbl @@ -462,7 +462,7 @@ In addition, operations like @racket[hash-iterate-key] or @racket[hash-map], which extract keys from the table, use @racket[key-proc] to filter keys extracted from the table. Operations like @racket[hash-iterate-value] or -@racket[hash-map] implicitly use @racket[hash-ref] and +@racket[hash-values] implicitly use @racket[hash-ref] and therefore redirect through @racket[ref-proc]. The @racket[ref-proc] must accept @racket[hash] and a key passed From 4c04d4afce9b71e856f4a2122770e29765d0d071 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 1 Jan 2016 12:44:12 -0600 Subject: [PATCH 281/369] Fix discussion of filter. Closes PR 15083. --- pkgs/racket-doc/scribblings/guide/lists.scrbl | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pkgs/racket-doc/scribblings/guide/lists.scrbl b/pkgs/racket-doc/scribblings/guide/lists.scrbl index c7bb8f1bac..663031eadc 100644 --- a/pkgs/racket-doc/scribblings/guide/lists.scrbl +++ b/pkgs/racket-doc/scribblings/guide/lists.scrbl @@ -74,15 +74,7 @@ by @racket[and]ing or @racket[or]ing: (ormap number? (list "a" "b" 6)) ] -The @racket[filter] function keeps elements for which the body result -is true, and discards elements for which it is @racket[#f]: - -@interaction[ -(filter string? (list "a" "b" 6)) -(filter positive? (list 1 -2 6 7 0)) -] - -The @racket[map], @racket[andmap], @racket[ormap], and @racket[filter] +The @racket[map], @racket[andmap], and @racket[ormap] functions can all handle multiple lists, instead of just a single list. The lists must all have the same length, and the given function must accept one argument for each list: @@ -93,6 +85,14 @@ must accept one argument for each list: (list 6 3 7)) ] +The @racket[filter] function keeps elements for which the body result +is true, and discards elements for which it is @racket[#f]: + +@interaction[ +(filter string? (list "a" "b" 6)) +(filter positive? (list 1 -2 6 7 0)) +] + The @racket[foldl] function generalizes some iteration functions. It uses the per-element function to both process an element and combine it with the ``current'' value, so the per-element function takes an From 8c8a76979bdac37add88ec5f6ffcf8b230bdafce Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 1 Jan 2016 12:46:14 -0600 Subject: [PATCH 282/369] Fix keyword argument name. Closes PR 15089. --- pkgs/racket-doc/scribblings/guide/define-struct.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/guide/define-struct.scrbl b/pkgs/racket-doc/scribblings/guide/define-struct.scrbl index b5481a95fc..c458eee8c3 100644 --- a/pkgs/racket-doc/scribblings/guide/define-struct.scrbl +++ b/pkgs/racket-doc/scribblings/guide/define-struct.scrbl @@ -453,7 +453,7 @@ A @racket[_struct-option] always starts with a keyword: @racket[#:auto] field option. The constructor procedure does not accept arguments for automatic fields. Automatic fields are implicitly mutable (via reflective operations), but mutator - functions are bound only if @racket[#:mutator] is also specified. + functions are bound only if @racket[#:mutable] is also specified. @defexamples[ (struct posn (x y [z #:auto]) From 923b5864a5afe49fb0a56290a62b9c5cdf8ac5ac Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 1 Jan 2016 12:51:20 -0600 Subject: [PATCH 283/369] Small guide fixes. Closes PR 15109. --- pkgs/racket-doc/scribblings/guide/io.scrbl | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pkgs/racket-doc/scribblings/guide/io.scrbl b/pkgs/racket-doc/scribblings/guide/io.scrbl index 75c2066666..e578521353 100644 --- a/pkgs/racket-doc/scribblings/guide/io.scrbl +++ b/pkgs/racket-doc/scribblings/guide/io.scrbl @@ -69,10 +69,11 @@ file: (close-output-port out) ] -Instead of having to match @racket[open-input-file] and -@racket[open-output-file] calls, most Racket programmers will instead -use @racket[call-with-output-file], which takes a function to call -with the output port; when the function returns, the port is closed. +Instead of having to match the open calls with close calls, most Racket +programmers will use the @racket[call-with-input-file] and +@racket[call-with-output-file] functions which take a function to call to carry +out the desired operation. This function gets as its only argument the port, +which is automatically opened and closed for the operation. @examples[ #:eval io-eval @@ -318,7 +319,7 @@ Other structure types created by @racket[struct], which offer more abstraction than @tech{prefab} structure types, normally @racket[write] either using @racketresultfont{#<....>} notation (for opaque structure types) or using @racketresultfont{#(....)} vector -notation (for transparent structure types). In neither can the +notation (for transparent structure types). In neither case can the result be read back in as an instance of the structure type: @interaction[ From 8b7f5bc046a838e620ddbb64af895e104509f567 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 1 Jan 2016 10:14:30 -0700 Subject: [PATCH 284/369] faster `xexpr->string` --- 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 5dbad64766..940deeee64 100644 --- a/racket/collects/xml/private/xexpr.rkt +++ b/racket/collects/xml/private/xexpr.rkt @@ -78,7 +78,7 @@ ;; xexpr->string : Xexpression -> String (define (xexpr->string xexpr) (let ([port (open-output-string)]) - (write-xml/content (xexpr->xml xexpr) port) + (write-xexpr xexpr port) (get-output-string port))) (define (string->xexpr str) From d3bb9d0412c0c51a1ced50e7e43cc46b606bfa5c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 1 Jan 2016 11:48:41 -0700 Subject: [PATCH 285/369] fix bytecode-reading time-complexity bug When a tree marshaled to bytecode form has many shared pieces, the unmarshaling process can lose track of the sharing in one place and traverse too much of the structure as pieces are loaded. --- racket/src/racket/src/mzmark_read.inc | 4 ++ racket/src/racket/src/mzmarksrc.c | 2 + racket/src/racket/src/read.c | 89 +++++++++++++++++++++------ 3 files changed, 75 insertions(+), 20 deletions(-) diff --git a/racket/src/racket/src/mzmark_read.inc b/racket/src/racket/src/mzmark_read.inc index 541c04d991..8539f2ccf0 100644 --- a/racket/src/racket/src/mzmark_read.inc +++ b/racket/src/racket/src/mzmark_read.inc @@ -50,6 +50,7 @@ static int mark_cport_MARK(void *p, struct NewGC *gc) { gcMARK2(cp->ht, gc); gcMARK2(cp->ut, gc); gcMARK2(cp->symtab, gc); + gcMARK2(cp->symtab_entries, gc); gcMARK2(cp->relto, gc); gcMARK2(cp->magic_sym, gc); gcMARK2(cp->magic_val, gc); @@ -73,6 +74,7 @@ static int mark_cport_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(cp->ht, gc); gcFIXUP2(cp->ut, gc); gcFIXUP2(cp->symtab, gc); + gcFIXUP2(cp->symtab_entries, gc); gcFIXUP2(cp->relto, gc); gcFIXUP2(cp->magic_sym, gc); gcFIXUP2(cp->magic_val, gc); @@ -195,6 +197,7 @@ static int mark_delay_load_MARK(void *p, struct NewGC *gc) { Scheme_Load_Delay *ld = (Scheme_Load_Delay *)p; gcMARK2(ld->path, gc); gcMARK2(ld->symtab, gc); + gcMARK2(ld->symtab_entries, gc); gcMARK2(ld->shared_offsets, gc); gcMARK2(ld->relto, gc); gcMARK2(ld->ut, gc); @@ -215,6 +218,7 @@ static int mark_delay_load_FIXUP(void *p, struct NewGC *gc) { Scheme_Load_Delay *ld = (Scheme_Load_Delay *)p; gcFIXUP2(ld->path, gc); gcFIXUP2(ld->symtab, gc); + gcFIXUP2(ld->symtab_entries, gc); gcFIXUP2(ld->shared_offsets, gc); gcFIXUP2(ld->relto, gc); gcFIXUP2(ld->ut, gc); diff --git a/racket/src/racket/src/mzmarksrc.c b/racket/src/racket/src/mzmarksrc.c index d099050a6d..efe40de46c 100644 --- a/racket/src/racket/src/mzmarksrc.c +++ b/racket/src/racket/src/mzmarksrc.c @@ -2274,6 +2274,7 @@ mark_cport { gcMARK2(cp->ht, gc); gcMARK2(cp->ut, gc); gcMARK2(cp->symtab, gc); + gcMARK2(cp->symtab_entries, gc); gcMARK2(cp->relto, gc); gcMARK2(cp->magic_sym, gc); gcMARK2(cp->magic_val, gc); @@ -2312,6 +2313,7 @@ mark_delay_load { Scheme_Load_Delay *ld = (Scheme_Load_Delay *)p; gcMARK2(ld->path, gc); gcMARK2(ld->symtab, gc); + gcMARK2(ld->symtab_entries, gc); gcMARK2(ld->shared_offsets, gc); gcMARK2(ld->relto, gc); gcMARK2(ld->ut, gc); diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index 26b55dd703..5ce623bfaa 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -2079,6 +2079,7 @@ static Scheme_Object *resolve_references(Scheme_Object *obj, Scheme_Object *top, Scheme_Hash_Table *dht, Scheme_Hash_Table *tht, + Scheme_Hash_Table *self_contained_ht, int clone, int tail_depth); @@ -2089,7 +2090,8 @@ static Scheme_Object *resolve_k(void) Scheme_Object *port = (Scheme_Object *)p->ku.k.p2; Scheme_Object *top = (Scheme_Object *)p->ku.k.p5; Scheme_Hash_Table *dht = (Scheme_Hash_Table *)p->ku.k.p3; - Scheme_Hash_Table *tht = (Scheme_Hash_Table *)p->ku.k.p4; + Scheme_Hash_Table *tht = (Scheme_Hash_Table *)SCHEME_CAR((Scheme_Object *)p->ku.k.p4); + Scheme_Hash_Table *self_contained_ht = (Scheme_Hash_Table *)SCHEME_CDR((Scheme_Object *)p->ku.k.p4); p->ku.k.p1 = NULL; p->ku.k.p2 = NULL; @@ -2097,7 +2099,7 @@ static Scheme_Object *resolve_k(void) p->ku.k.p4 = NULL; p->ku.k.p5 = NULL; - return resolve_references(o, port, top, dht, tht, p->ku.k.i1, p->ku.k.i2); + return resolve_references(o, port, top, dht, tht, self_contained_ht, p->ku.k.i1, p->ku.k.i2); } #endif @@ -2106,6 +2108,7 @@ static Scheme_Object *resolve_references(Scheme_Object *obj, Scheme_Object *top, Scheme_Hash_Table *dht, Scheme_Hash_Table *tht, + Scheme_Hash_Table *self_contained_ht, int clone, int tail_depth) { @@ -2120,7 +2123,9 @@ static Scheme_Object *resolve_references(Scheme_Object *obj, p->ku.k.p2 = (void *)port; p->ku.k.p5 = (void *)top; p->ku.k.p3 = (void *)dht; - p->ku.k.p4 = (void *)tht; + result = scheme_make_pair((Scheme_Object *)tht, + (Scheme_Object *)self_contained_ht); + p->ku.k.p4 = (void *)result; p->ku.k.i1 = clone; p->ku.k.i2 = tail_depth; return scheme_handle_stack_overflow(resolve_k); @@ -2149,6 +2154,10 @@ static Scheme_Object *resolve_references(Scheme_Object *obj, } } + if (self_contained_ht + && scheme_hash_get(self_contained_ht, obj)) + return obj; + result = scheme_hash_get(dht, obj); if (result) { if (SCHEME_PAIRP(result)) { @@ -2168,12 +2177,14 @@ static Scheme_Object *resolve_references(Scheme_Object *obj, result = scheme_make_pair(scheme_false, scheme_false); scheme_hash_set(dht, obj, result); - rr = resolve_references(SCHEME_CAR(obj), port, top, dht, tht, clone, tail_depth + 1); + rr = resolve_references(SCHEME_CAR(obj), port, top, dht, tht, self_contained_ht, + clone, tail_depth + 1); SCHEME_CAR(result) = rr; scheme_hash_set(tht, result, scheme_make_integer(tail_depth)); - rr = resolve_references(SCHEME_CDR(obj), port, top, dht, tht, clone, tail_depth); + rr = resolve_references(SCHEME_CDR(obj), port, top, dht, tht, self_contained_ht, + clone, tail_depth); SCHEME_CDR(result) = rr; scheme_hash_set(tht, result, NULL); @@ -2195,7 +2206,8 @@ static Scheme_Object *resolve_references(Scheme_Object *obj, } scheme_hash_set(dht, obj, result); - rr = resolve_references(SCHEME_BOX_VAL(obj), port, top, dht, tht, clone, tail_depth + 1); + rr = resolve_references(SCHEME_BOX_VAL(obj), port, top, dht, tht, self_contained_ht, + clone, tail_depth + 1); SCHEME_BOX_VAL(result) = rr; if (clone @@ -2227,7 +2239,8 @@ static Scheme_Object *resolve_references(Scheme_Object *obj, rr = prev_rr; } else { prev_v = SCHEME_VEC_ELS(obj)[i]; - rr = resolve_references(prev_v, port, top, dht, tht, clone, tail_depth + 1); + rr = resolve_references(prev_v, port, top, dht, tht, self_contained_ht, + clone, tail_depth + 1); if (!SAME_OBJ(prev_v, rr)) diff = 1; prev_rr = rr; @@ -2280,7 +2293,8 @@ static Scheme_Object *resolve_references(Scheme_Object *obj, result = (Scheme_Object *)t; scheme_hash_set(dht, obj, result); - lst = resolve_references(lst, port, top, dht, tht, clone, tail_depth + 1); + lst = resolve_references(lst, port, top, dht, tht, self_contained_ht, + clone, tail_depth + 1); for (; SCHEME_PAIRP(lst); lst = SCHEME_CDR(lst)) { a = SCHEME_CAR(lst); @@ -2312,7 +2326,8 @@ static Scheme_Object *resolve_references(Scheme_Object *obj, } orig_l = l; - l = resolve_references(l, port, top, dht, tht, clone, tail_depth + 1); + l = resolve_references(l, port, top, dht, tht, self_contained_ht, + clone, tail_depth + 1); if (SAME_OBJ(l, orig_l)) { result = obj; @@ -2347,7 +2362,8 @@ static Scheme_Object *resolve_references(Scheme_Object *obj, diff = 0; for (i = 0; i < c; i++) { prev_v = ((Scheme_Structure *)result)->slots[i]; - v = resolve_references(prev_v, port, top, dht, tht, clone, tail_depth + 1); + v = resolve_references(prev_v, port, top, dht, tht, self_contained_ht, + clone, tail_depth + 1); if (!SAME_OBJ(prev_v, v)) diff = 1; ((Scheme_Structure *)result)->slots[i] = v; @@ -2491,12 +2507,12 @@ _internal_read(Scheme_Object *port, Scheme_Object *stxsrc, int crc, int cant_fai tht = scheme_make_hash_table(SCHEME_hash_ptr); if (v) - v = resolve_references(v, port, NULL, dht, tht, clone, 0); + v = resolve_references(v, port, NULL, dht, tht, NULL, clone, 0); /* In case some placeholders were introduced by #;: */ v2 = scheme_hash_get(*ht, unresolved_uninterned_symbol); if (v2) - resolve_references(v2, port, NULL, dht, tht, clone, 0); + resolve_references(v2, port, NULL, dht, tht, NULL, clone, 0); if (!v) *ht = NULL; @@ -2585,6 +2601,7 @@ Scheme_Object *scheme_resolve_placeholders(Scheme_Object *obj) return resolve_references(obj, NULL, obj, scheme_make_hash_table(SCHEME_hash_ptr), scheme_make_hash_table(SCHEME_hash_ptr), + NULL, 1, 0); } @@ -4491,6 +4508,7 @@ typedef struct Scheme_Load_Delay { uintptr_t symtab_size; Scheme_Object **symtab; intptr_t *shared_offsets; + Scheme_Hash_Table *symtab_entries; /* `symtab` content to be skipped by resolve_references */ Scheme_Object *relto; Scheme_Unmarshal_Tables *ut; struct CPort *current_rp; @@ -4520,6 +4538,7 @@ typedef struct CPort { Scheme_Object *symtab_refs; Scheme_Unmarshal_Tables *ut; Scheme_Object **symtab; + Scheme_Hash_Table *symtab_entries; Scheme_Object *magic_sym, *magic_val; Scheme_Object *relto; intptr_t *shared_offsets; @@ -4771,6 +4790,20 @@ static Scheme_Object *read_compact_escape(CPort *port) return read_escape_from_string(s, len, port->relto, port->ht); } +static void record_symtab_self_contained(Scheme_Hash_Table *symtab_entries, Scheme_Object *v) +{ + if (SCHEME_PAIRP(v) + || SCHEME_BOXP(v) + || SCHEME_VECTORP(v) + || SCHEME_HASHTRP(v) + || SCHEME_STRUCTP(v)) { + /* Register `v` as a value that is shared through the symbol table, + so that later calls to resolve_references() can avoid re-traversing + the value. (Otherwise, bytecode reading can become quadratic-time.) */ + scheme_hash_set(symtab_entries, v, scheme_true); + } +} + static Scheme_Object *resolve_symtab_refs(Scheme_Object *v, CPort *port) { Scheme_Object *l; @@ -4783,7 +4816,8 @@ static Scheme_Object *resolve_symtab_refs(Scheme_Object *v, CPort *port) v = resolve_references(v, port->orig_port, NULL, scheme_make_hash_table(SCHEME_hash_ptr), - scheme_make_hash_table(SCHEME_hash_ptr), + scheme_make_hash_table(SCHEME_hash_ptr), + port->symtab_entries, 0, 0); l = SCHEME_CDR(v); @@ -4791,9 +4825,10 @@ static Scheme_Object *resolve_symtab_refs(Scheme_Object *v, CPort *port) l = port->symtab_refs; for (; !SCHEME_NULLP(l); l = SCHEME_CDR(l)) { - if (v) + if (v) { port->symtab[SCHEME_INT_VAL(SCHEME_CAR(SCHEME_CAR(l)))] = SCHEME_CDR(SCHEME_CAR(l)); - else { + record_symtab_self_contained(port->symtab_entries, SCHEME_CDR(SCHEME_CAR(l))); + } else { /* interrupted; discard partial constructions */ port->symtab[SCHEME_INT_VAL(SCHEME_CAR(SCHEME_CAR(l)))] = NULL; } @@ -5041,7 +5076,8 @@ static Scheme_Object *read_compact(CPort *port, int use_stack) *port->ht = NULL; v = resolve_references(v, port->orig_port, NULL, scheme_make_hash_table(SCHEME_hash_ptr), - scheme_make_hash_table(SCHEME_hash_ptr), + scheme_make_hash_table(SCHEME_hash_ptr), + port->symtab_entries, 0, 0); } @@ -5527,8 +5563,9 @@ static Scheme_Object *read_compact_quote(CPort *port, int embedded) if (*q_ht) v = resolve_references(v, port->orig_port, NULL, - scheme_make_hash_table(SCHEME_hash_ptr), - scheme_make_hash_table(SCHEME_hash_ptr), + scheme_make_hash_table(SCHEME_hash_ptr), + scheme_make_hash_table(SCHEME_hash_ptr), + port->symtab_entries, 0, 0); return v; @@ -5864,6 +5901,14 @@ static Scheme_Object *read_compiled(Scheme_Object *port, rp->symtab = symtab; rp->unsafe_ok = params->can_read_unsafe; + { + Scheme_Hash_Table *se_ht; + se_ht = scheme_make_hash_table(SCHEME_hash_ptr); + rp->symtab_entries = se_ht; + if (delay_info) + delay_info->symtab_entries = se_ht; + } + config = scheme_current_config(); dir = scheme_get_param(config, MZCONFIG_LOAD_DIRECTORY); @@ -6151,6 +6196,7 @@ Scheme_Object *scheme_load_delayed_code(int _which, Scheme_Load_Delay *_delay_in rp->ut = delay_info->ut; rp->unsafe_ok = delay_info->unsafe_ok; rp->bytecode_hash = delay_info->bytecode_hash; + rp->symtab_entries = delay_info->symtab_entries; if (delay_info->ut) delay_info->ut->rp = rp; @@ -6206,11 +6252,13 @@ Scheme_Object *scheme_load_delayed_code(int _which, Scheme_Load_Delay *_delay_in if (*ht) { v = resolve_references(v, port, NULL, scheme_make_hash_table(SCHEME_hash_ptr), - scheme_make_hash_table(SCHEME_hash_ptr), + scheme_make_hash_table(SCHEME_hash_ptr), + delay_info->symtab_entries, 0, 0); } delay_info->symtab[which] = v; + record_symtab_self_contained(delay_info->symtab_entries, v); return v; } else { @@ -6391,7 +6439,8 @@ static Scheme_Object *readtable_call(int w_char, int ch, Scheme_Object *proc, Re /* resolve references from recursive `read': */ v = resolve_references(v, port, NULL, scheme_make_hash_table(SCHEME_hash_ptr), - scheme_make_hash_table(SCHEME_hash_ptr), + scheme_make_hash_table(SCHEME_hash_ptr), + NULL, 1, 0); } From c9a1dc781e7968aed7094284624871fc9f09dfcd Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 1 Jan 2016 12:03:06 -0700 Subject: [PATCH 286/369] raco setup: use lazy ".zo" parsing for dpeendency checking Lazy ".zo" parsing make the dependency check take about half as long. --- racket/collects/setup/private/pkg-deps.rkt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/racket/collects/setup/private/pkg-deps.rkt b/racket/collects/setup/private/pkg-deps.rkt index 09138ab566..3c897ad0ce 100644 --- a/racket/collects/setup/private/pkg-deps.rkt +++ b/racket/collects/setup/private/pkg-deps.rkt @@ -368,10 +368,12 @@ (define in-mod `(lib ,(string-join (append (map path-element->string coll-path) (list base)) "/"))) + (define zo-path (build-path dir zo-f)) (define mod-code (call-with-input-file* - (build-path dir zo-f) + zo-path (lambda (i) - (parameterize ([read-accept-compiled #t]) + (parameterize ([read-accept-compiled #t] + [read-on-demand-source zo-path]) (read i))))) ;; Recur to cover submodules: (let loop ([mod-code mod-code]) From c0915b02b0a33f0370ab6244913728221ad4f017 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 1 Jan 2016 12:44:18 -0700 Subject: [PATCH 287/369] pathlist-closure, tar, and tar-gzip: add `#:path-filter` Also, add `#:skip-filtered-directory?` to `find-files`. Less significantly, adjust `pathlist-closure` to be consistent in the way that it includes a separator at the end of a directory path. --- pkgs/racket-doc/file/scribblings/tar.scrbl | 8 +- .../scribblings/reference/filesystem.scrbl | 30 ++++- .../tests/racket/filelib.rktl | 126 ++++++++++++++++++ pkgs/racket-test/tests/file/packers.rkt | 26 +++- racket/collects/file/tar.rkt | 11 +- racket/collects/racket/file.rkt | 40 ++++-- 6 files changed, 214 insertions(+), 27 deletions(-) diff --git a/pkgs/racket-doc/file/scribblings/tar.scrbl b/pkgs/racket-doc/file/scribblings/tar.scrbl index 76d4d78d9e..618a1d4d3b 100644 --- a/pkgs/racket-doc/file/scribblings/tar.scrbl +++ b/pkgs/racket-doc/file/scribblings/tar.scrbl @@ -20,6 +20,7 @@ in a link must be less than 100 bytes.} [#:follow-links? follow-links? any/c #f] [#:exists-ok? exists-ok? any/c #f] [#:path-prefix path-prefix (or/c #f path-string?) #f] + [#:path-filter path-filter (or/c #f (path? . -> . any/c)) #f] [#:get-timestamp get-timestamp (path? . -> . exact-integer?) (if timestamp @@ -48,13 +49,15 @@ date to record in the archive for each file or directory. @history[#:changed "6.0.0.3" @elem{Added the @racket[#:get-timestamp] argument.} #:changed "6.1.1.1" @elem{Added the @racket[#:exists-ok?] argument.} - #:changed "6.3.0.3" @elem{Added the @racket[#:follow-links?] argument.}]} + #:changed "6.3.0.3" @elem{Added the @racket[#:follow-links?] argument.} + #:changed "6.3.0.11" @elem{Added the @racket[#:path-filter] argument.}]} @defproc[(tar->output [paths (listof path?)] [out output-port? (current-output-port)] [#:follow-links? follow-links? any/c #f] [#:path-prefix path-prefix (or/c #f path-string?) #f] + [#:path-filter path-filter (or/c #f (path? . -> . any/c)) #f] [#:get-timestamp get-timestamp (path? . -> . exact-integer?) (if timestamp @@ -69,7 +72,8 @@ content is not automatically added, and nested directories are added without parent directories. @history[#:changed "6.0.0.3" @elem{Added the @racket[#:get-timestamp] argument.} - #:changed "6.3.0.3" @elem{Added the @racket[#:follow-links?] argument.}]} + #:changed "6.3.0.3" @elem{Added the @racket[#:follow-links?] argument.} + #:changed "6.3.0.11" @elem{Added the @racket[#:path-filter] argument.}]} @defproc[(tar-gzip [tar-file path-string?] diff --git a/pkgs/racket-doc/scribblings/reference/filesystem.scrbl b/pkgs/racket-doc/scribblings/reference/filesystem.scrbl index 93a5f5400e..cfc031b488 100644 --- a/pkgs/racket-doc/scribblings/reference/filesystem.scrbl +++ b/pkgs/racket-doc/scribblings/reference/filesystem.scrbl @@ -979,6 +979,7 @@ exists and is removed by another thread or process before @defproc[(find-files [predicate (path? . -> . any/c)] [start-path (or/c path-string? #f) #f] + [#:skip-filtered-directory? skip-filtered-directory? #f] [#:follow-links? follow-links? #f]) (listof path?)]{ @@ -999,6 +1000,10 @@ paths in the former case and relative paths in the latter. Another difference is that @racket[predicate] is not called for the current directory when @racket[start-path] is @racket[#f]. +If @racket[skip-filtered-directory?] is true, then when +@racket[predicate] returns @racket[#f] for a directory, the +directory's content is not traversed. + If @racket[follow-links?] is true, the @racket[find-files] traversal follows links, and links are not included in the result. If @racket[follow-links?] is @racket[#f], then links are not followed, @@ -1009,10 +1014,15 @@ directory, then @racket[predicate] will be called exactly once with @racket[start-path] as the argument. The @racket[find-files] procedure raises an exception if it encounters -a directory for which @racket[directory-list] fails.} +a directory for which @racket[directory-list] fails. + +@history[#:changed "6.3.0.11" @elem{Added the + @racket[#:skip-filtered-directory?] + argument.}]} @defproc[(pathlist-closure [path-list (listof path-string?)] - [#:follow-links? follow-links? #f]) + [#:path-filter path-filter (or/c #f (path? . -> . any/c)) #f] + [#:follow-links? follow-links? any/c #f]) (listof path?)]{ Given a list of paths, either absolute or relative to the current @@ -1025,17 +1035,25 @@ directory, returns a list such that twice);} @item{if a path refers to directory, all of its descendants are also - included in the result;} + included in the result, except as omitted by @racket[path-filter];} @item{ancestor directories appear before their descendants in the - result list.} + result list, as long as they are not misordered in the given + @racket[path-list].} ] +If @racket[path-filter] is a procedure, then it is applied to each +descendant of a directory. If @racket[path-filter] returns +@racket[#f], then the descendant (and any of its descendants, in the +case of a subdirectory) are omitted from the result. + If @racket[follow-links?] is true, then the traversal of directories and files follows links, and the link paths are not included in the -result. If @racket[follow-links?] is @racket[#f], then he result list -includes paths to link and the links are not followed.} +result. If @racket[follow-links?] is @racket[#f], then the result list +includes paths to link and the links are not followed. + +@history[#:changed "6.3.0.11" @elem{Added the @racket[#:path-filter] argument.}]} @defproc[(fold-files [proc (or/c (path? (or/c 'file 'dir 'link) any/c diff --git a/pkgs/racket-test-core/tests/racket/filelib.rktl b/pkgs/racket-test-core/tests/racket/filelib.rktl index afbe933490..a76c8b8754 100644 --- a/pkgs/racket-test-core/tests/racket/filelib.rktl +++ b/pkgs/racket-test-core/tests/racket/filelib.rktl @@ -223,4 +223,130 @@ ;; ---------------------------------------- +(let ([dir (make-temporary-file "pathlist~a" 'directory)]) + (define parents + (let loop ([dir dir]) + (define-values (base name dir?) (split-path dir)) + (if (path? base) + (append (loop base) (list (path->directory-path dir))) + (list dir)))) + (define (p . args) + (maybe-as-directory + args + (apply build-path dir args))) + (define (maybe-as-directory args p) + (if (regexp-match? #rx"^d" (last args)) + (path->directory-path p) + p)) + (define (touch f) + (call-with-output-file* f void)) + (touch (p "f1")) + (make-directory (p "d1")) + (make-directory (p "d2")) + (touch (p "d1" "f1")) + (touch (p "d2" "f1")) + (touch (p "d2" "f2")) + + (unless (eq? 'windows (system-type)) + (make-file-or-directory-link "d1" (p "l3")) + (make-file-or-directory-link "l3" (p "l4")) + (make-directory (p "d5")) + (make-file-or-directory-link (build-path 'up "d2" "f1") (p "d5" "l5"))) + + (make-directory (p "d6")) + (touch (p "d6" "f1")) + (make-directory (p "d6" "d7")) + (touch (p "d6" "d7" "f1")) + (touch (p "d6" "d7" "f2")) + + (define (check p parents) + (test (append + parents + (list (p "d1") + (p "d1" "f1"))) + pathlist-closure + (list (p "d1"))) + (test (append + parents + (list (p "d1") + (p "d1" "f1") + (p "f1"))) + pathlist-closure + (list (p "d1") + (p "f1"))) + (test (append + parents + (list (p "d1") + (p "d2") + (p "d2" "f2"))) + pathlist-closure + (list (p "d1") + (p "d2")) + #:path-filter (lambda (f) (not (regexp-match? #rx"f1$" f)))) + (test (append + parents + (list (p "d1") + (p "d1" "f1") + (p "d2") + (p "d2" "f2"))) + pathlist-closure + (list (p "d1") + (p "d1" "f1") + (p "d2")) + #:path-filter (lambda (f) (not (regexp-match? #rx"f1$" f)))) + (test (append + parents + (list (p "d6") + (p "d6" "f1"))) + pathlist-closure + (list (p "d6")) + #:path-filter (lambda (f) (not (regexp-match? #rx"d7$" f)))) + (unless (eq? 'windows (system-type)) + (test (append + parents + (list (p "l3"))) + pathlist-closure + (list (p "l3"))) + (test (append + parents + (list (p "l4"))) + pathlist-closure + (list (p "l4"))) + (test (append + parents + (list (p "d5") + (p "d5" "l5"))) + pathlist-closure + (list (p "d5" "l5"))) + (test (append + parents + (list (p "d1") + (p "d1" "f1"))) + pathlist-closure + (list (p "l3")) + #:follow-links? #t) + (test (append + parents + (list (p "d1") + (p "d1" "f1"))) + pathlist-closure + (list (p "l4")) + #:follow-links? #t) + (test (append + parents + (list (p "d2") + (p "d2" "f1"))) + pathlist-closure + (list (p "d5" "l5")) + #:follow-links? #t))) + + (parameterize ([current-directory dir]) + (check (lambda args (maybe-as-directory args (apply build-path args))) null)) + (check p parents) + + + (delete-directory/files dir)) + +;; ---------------------------------------- + (report-errs) diff --git a/pkgs/racket-test/tests/file/packers.rkt b/pkgs/racket-test/tests/file/packers.rkt index 2bc77569f4..2e3942c7f4 100644 --- a/pkgs/racket-test/tests/file/packers.rkt +++ b/pkgs/racket-test/tests/file/packers.rkt @@ -49,7 +49,9 @@ (and (directory-exists? dest) (compare-attributes src dest) (let* ([sort-paths (λ (l) (sort l bytesbytes))] - [srcs (sort-paths (directory-list src))] + [srcs (sort-paths (for/list ([p (in-list (directory-list src))] + #:unless (regexp-match? #rx"skip" p)) + p))] [dests (sort-paths (directory-list dest))]) (and (equal? srcs dests) (for/and ([src-item (in-list srcs)] @@ -64,7 +66,8 @@ (define (zip-tests zip unzip timestamps? #:dir-name [ex1 "ex1"] #:file-name [f2 "f2"] - #:links? [links? #f]) + #:links? [links? #f] + #:filter-path? [filter-path? #f]) (make-directory* ex1) (make-file (build-path ex1 "f1")) (make-file (build-path ex1 f2)) @@ -76,6 +79,10 @@ (make-file-or-directory-link "f1" (build-path ex1 "f1-link")) (make-file-or-directory-link "more" (build-path ex1 "more-link")) (make-file-or-directory-link "no" (build-path ex1 "no-link"))) + (when filter-path? + (make-file (build-path ex1 "skip1")) + (make-directory (build-path ex1 "skip2")) + (make-file (build-path ex1 "skip2" "nope"))) (zip "a.zip" ex1) (when timestamps? (sleep 3)) ; at least 2 seconds, plus 1 to likely change parity @@ -116,11 +123,20 @@ (zip-tests zip unzip #f) (zip-tests (make-zip #f) (make-unzip #f) 'file) (zip-tests (make-zip #t) (make-unzip #t) 'file) - (zip-tests tar untar #t #:links? #t) + (zip-tests tar untar #t #:links? (not (eq? 'windows (system-type)))) (zip-tests tar untar #t - #:links? #t + #:links? (not (eq? 'windows (system-type))) #:dir-name (make-string 64 #\d) - #:file-name (make-string 64 #\f))) + #:file-name (make-string 64 #\f)) + (zip-tests (lambda (#:path-prefix [prefix #f] . args) + (apply + tar + args + #:path-prefix prefix + #:path-filter (lambda (p) + (define-values (base name dir?) (split-path p)) + (not (regexp-match? #rx"skip" name))))) + untar #t #:filter-path? #t)) (delete-directory/files work-dir) diff --git a/racket/collects/file/tar.rkt b/racket/collects/file/tar.rkt index e0b1dde501..43a5dee977 100644 --- a/racket/collects/file/tar.rkt +++ b/racket/collects/file/tar.rkt @@ -152,13 +152,16 @@ (define (tar tar-file #:exists-ok? [exists-ok? #f] #:path-prefix [prefix #f] + #:path-filter [path-filter #f] #:follow-links? [follow-links? #f] #:get-timestamp [get-timestamp file-or-directory-modify-seconds] . paths) (when (null? paths) (error 'tar "no paths specified")) (with-output-to-file tar-file #:exists (if exists-ok? 'truncate/replace 'error) - (lambda () (tar->output (pathlist-closure paths #:follow-links? follow-links?) + (lambda () (tar->output (pathlist-closure paths + #:follow-links? follow-links? + #:path-filter path-filter) #:get-timestamp get-timestamp #:path-prefix prefix #:follow-links? follow-links?)))) @@ -168,6 +171,7 @@ (define (tar-gzip tgz-file #:exists-ok? [exists-ok? #f] #:path-prefix [prefix #f] + #:path-filter [path-filter #f] #:follow-links? [follow-links? #f] #:get-timestamp [get-timestamp file-or-directory-modify-seconds] . paths) @@ -177,7 +181,10 @@ (lambda () (let-values ([(i o) (make-pipe (* 1024 1024 32))]) (thread (lambda () - (tar->output (pathlist-closure paths #:follow-links? follow-links?) o + (tar->output (pathlist-closure paths + #:follow-links? follow-links? + #:path-filter path-filter) + o #:path-prefix prefix #:follow-links? follow-links? #:get-timestamp get-timestamp) diff --git a/racket/collects/racket/file.rkt b/racket/collects/racket/file.rkt index 4339678606..ffc28d1df6 100644 --- a/racket/collects/racket/file.rkt +++ b/racket/collects/racket/file.rkt @@ -639,24 +639,37 @@ (define (to-path s) (if (path? s) s (string->path s))) (if path (do-path (to-path path) init) (do-paths (directory-list) init))) -(define (find-files f [path #f] #:follow-links? [follow-links? #t]) +(define (find-files f [path #f] + #:follow-links? [follow-links? #t] + #:skip-filtered-directory? [skip-filtered-directory? #f]) (reverse - (fold-files (lambda (path kind acc) (if (f path) (cons path acc) acc)) + (fold-files (lambda (path kind acc) (if (f path) + (cons path acc) + (if (and skip-filtered-directory? + (eq? kind 'dir)) + (values acc #f) + acc))) null path follow-links?))) -(define (pathlist-closure paths #:follow-links? [follow-links? #f]) +(define (pathlist-closure paths + #:follow-links? [follow-links? #f] + #:path-filter [path-filter #f]) (let loop ([paths (map (lambda (p) (simplify-path - (if (and follow-links? - (link-exists? p)) - (let ([p2 (resolve-path p)]) - (if (relative-path? p2) - (let-values ([(base name dir?) (split-path p)]) - (build-path base p2)) - p2)) - p) + (let loop ([p p]) + (if (and follow-links? + (link-exists? p)) + (let ([p2 (resolve-path p)]) + (if (relative-path? p2) + (let-values ([(base name dir?) (split-path p)]) + (loop ((if dir? path->directory-path values) + (if (path? base) + (build-path base p2) + p2)))) + (loop p2))) + p)) #f)) paths)] [r '()]) @@ -669,7 +682,10 @@ [(file-exists? (car paths)) (list (car paths))] [(directory-exists? (car paths)) - (find-files void (car paths) #:follow-links? follow-links?)] + (find-files (or path-filter void) + (path->directory-path (car paths)) + #:skip-filtered-directory? #t + #:follow-links? follow-links?)] [else (error 'pathlist-closure "file/directory not found: ~a" (car paths))])]) From fd7b8b29eaa0469b89c411af9babf79fa706a0cf Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 1 Jan 2016 14:33:16 -0700 Subject: [PATCH 288/369] avoid compiler warning --- racket/src/racket/src/hash.c | 1 + 1 file changed, 1 insertion(+) diff --git a/racket/src/racket/src/hash.c b/racket/src/racket/src/hash.c index 8bc1043062..996bc1f9ac 100644 --- a/racket/src/racket/src/hash.c +++ b/racket/src/racket/src/hash.c @@ -779,6 +779,7 @@ get_bucket (Scheme_Bucket_Table *table, const char *key, int add, Scheme_Bucket lkey = PTR_TO_LONG((Scheme_Object *)key); h = lkey & mask; h2 = (lkey >> 1) & mask; + ekey = NULL; } h2 |= 0x1; From b24882fd183310ed992f0c53b559bd378f73ceaa Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Fri, 1 Jan 2016 12:21:23 -0600 Subject: [PATCH 289/369] implement the (-> any/c ... any) special case for the new -> contract combinator (new is being used in a relative sense here; it is the newer of the two -> combinators; the old one is used currently only for ->m) --- .../tests/racket/contract-rand-test.rkt | 1 + .../tests/racket/contract/flat-contracts.rkt | 5 + .../tests/racket/contract/stronger.rkt | 4 +- .../contract/private/arrow-val-first.rkt | 110 +++++++++++++----- .../racket/contract/private/arrow.rkt | 5 +- .../racket/contract/private/provide.rkt | 6 +- 6 files changed, 101 insertions(+), 30 deletions(-) diff --git a/pkgs/racket-test/tests/racket/contract-rand-test.rkt b/pkgs/racket-test/tests/racket/contract-rand-test.rkt index a53fe1eb58..785aa14f06 100644 --- a/pkgs/racket-test/tests/racket/contract-rand-test.rkt +++ b/pkgs/racket-test/tests/racket/contract-rand-test.rkt @@ -157,6 +157,7 @@ (λ () ((test-contract-generation (-> some-crazy-predicate? some-crazy-predicate?)) 11))) (check-not-exn (λ () (((test-contract-generation (-> (-> (>/c 10) (>/c 10))))) 11))) +(check-not-exn (λ () ((test-contract-generation (-> any/c any)) 1))) (check-not-exn (λ () diff --git a/pkgs/racket-test/tests/racket/contract/flat-contracts.rkt b/pkgs/racket-test/tests/racket/contract/flat-contracts.rkt index 3c538b504d..2eb2d1418f 100644 --- a/pkgs/racket-test/tests/racket/contract/flat-contracts.rkt +++ b/pkgs/racket-test/tests/racket/contract/flat-contracts.rkt @@ -71,6 +71,11 @@ (test-flat-contract #rx#".x." "axq" "x") (test-flat-contract ''() '() #f) + (test-flat-contract '(-> any/c any/c any) (λ (x y) 1) (λ (x y z) 1)) + (test-flat-contract '(->* (any/c any/c) any) (λ (x y) 1) (λ (x y z) 1)) + (test-flat-contract '(->* () any) (λ () 1) (λ (x y z w) 1)) + (test-flat-contract '(->* () () any) (λ () 1) (λ (x) 1)) + (test-flat-contract '(if/c integer? even? list?) 2 3) (test-flat-contract '(if/c integer? even? list?) '() #f) diff --git a/pkgs/racket-test/tests/racket/contract/stronger.rkt b/pkgs/racket-test/tests/racket/contract/stronger.rkt index 38d5c5d1a2..9783e91149 100644 --- a/pkgs/racket-test/tests/racket/contract/stronger.rkt +++ b/pkgs/racket-test/tests/racket/contract/stronger.rkt @@ -72,7 +72,9 @@ (-> integer? #:x integer? integer?) (-> integer? #:x integer? integer?)) (ctest #t contract-stronger? (-> #:x (>=/c 3) (>=/c 3)) (-> #:x (>=/c 3) (>=/c 2))) - + (ctest #t contract-stronger? (-> any/c any/c any) (-> any/c any/c any)) + (ctest #f contract-stronger? (-> any/c any/c any/c any) (-> any/c any/c any)) + (let ([c (contract-eval '(->* () () any))]) (test #t (contract-eval 'contract-stronger?) c c)) (let ([c (contract-eval '(->d () () any))]) diff --git a/racket/collects/racket/contract/private/arrow-val-first.rkt b/racket/collects/racket/contract/private/arrow-val-first.rkt index 8e229e3c95..5d9891fd8f 100644 --- a/racket/collects/racket/contract/private/arrow-val-first.rkt +++ b/racket/collects/racket/contract/private/arrow-val-first.rkt @@ -15,7 +15,9 @@ (provide ->2 ->*2 dynamic->* (for-syntax ->2-handled? + ->2-arity-check-only->? ->*2-handled? + ->2*-arity-check-only->? ->-valid-app-shapes ->*-valid-app-shapes) (rename-out [-predicate/c predicate/c])) @@ -25,11 +27,13 @@ [(_ args ...) (syntax-parameter-value #'arrow:making-a-method) #f] - [(_ any/c ... any) - ;; should turn into a flat contract - #f] [_ #t])) +(define-for-syntax (->2-arity-check-only->? stx) + (syntax-case stx (any any/c) + [(_ any/c ... any) (- (length (syntax->list stx)) 2)] + [_ #f])) + (define-for-syntax (->*2-handled? stx) (syntax-case stx (any values any/c) [(_ args ...) @@ -37,6 +41,12 @@ #f] [_ #t])) +(define-for-syntax (->2*-arity-check-only->? stx) + (syntax-case stx (any any/c) + [(_ (any/c ...) any) (length (syntax->list (cadr (syntax->list stx))))] + [(_ (any/c ...) () any) (length (syntax->list (cadr (syntax->list stx))))] + [_ #f])) + (define-for-syntax popular-keys ;; of the 8417 contracts that get compiled during ;; 'raco setup' of the current tree, these are all @@ -532,6 +542,9 @@ [(_ args ...) (not (->2-handled? stx)) #'(arrow:-> args ...)] + [(_ args ...) + (->2-arity-check-only->? stx) + #`(build-arity-check-only-> #,(->2-arity-check-only->? stx))] [(_ args ... rng) (let () (define this-> (gensym 'this->)) @@ -649,6 +662,10 @@ (define-syntax (->*2 stx) (cond + [(->2*-arity-check-only->? stx) + => + (λ (n) + #`(build-arity-check-only-> #,n))] [(->*2-handled? stx) (define this->* (gensym 'this->*)) (define-values (man-dom man-dom-kwds man-lets @@ -809,6 +826,18 @@ plus-one-arity-function chaperone-constructor)])) +(define (build-arity-check-only-> n) + (make-arity-check-only-> n + (build-list n (λ (_) any/c)) + '() #f #f #f #f + (λ args + (error 'arity-check-only->-plus-one-arity-function + "this function should not be called ~s" args)) + (λ args + (error 'arity-check-only->-chaperone-constructor + "this function should not be called ~s" args)) + n)) + (define (dynamic->* #:mandatory-domain-contracts [mandatory-domain-contracts '()] #:optional-domain-contracts [optional-domain-contracts '()] #:mandatory-keywords [unsorted-mandatory-keywords '()] @@ -1187,34 +1216,63 @@ (define cblame (cthis blame)) (λ (val) ((cblame val) #f)))) - #:stronger - (λ (this that) - (and (base->? that) - (= (length (base->-doms that)) - (length (base->-doms this))) - (= (base->-min-arity this) (base->-min-arity that)) - (andmap contract-stronger? (base->-doms that) (base->-doms this)) - (= (length (base->-kwd-infos this)) - (length (base->-kwd-infos that))) - (for/and ([this-kwd-info (base->-kwd-infos this)] - [that-kwd-info (base->-kwd-infos that)]) - (and (equal? (kwd-info-kwd this-kwd-info) - (kwd-info-kwd that-kwd-info)) - (contract-stronger? (kwd-info-ctc that-kwd-info) - (kwd-info-ctc this-kwd-info)))) - (if (base->-rngs this) - (and (base->-rngs that) - (andmap contract-stronger? (base->-rngs this) (base->-rngs that))) - (not (base->-rngs that))) - (not (base->-pre? this)) - (not (base->-pre? that)) - (not (base->-post? this)) - (not (base->-post? that)))) + #:stronger ->-stronger #:generate ->-generate #:exercise ->-exercise #:val-first-projection val-first-proj #:late-neg-projection late-neg-proj)) +(define (->-stronger this that) + (and (base->? that) + (= (length (base->-doms that)) + (length (base->-doms this))) + (= (base->-min-arity this) (base->-min-arity that)) + (andmap contract-stronger? (base->-doms that) (base->-doms this)) + (= (length (base->-kwd-infos this)) + (length (base->-kwd-infos that))) + (for/and ([this-kwd-info (base->-kwd-infos this)] + [that-kwd-info (base->-kwd-infos that)]) + (and (equal? (kwd-info-kwd this-kwd-info) + (kwd-info-kwd that-kwd-info)) + (contract-stronger? (kwd-info-ctc that-kwd-info) + (kwd-info-ctc this-kwd-info)))) + (if (base->-rngs this) + (and (base->-rngs that) + (andmap contract-stronger? (base->-rngs this) (base->-rngs that))) + (not (base->-rngs that))) + (not (base->-pre? this)) + (not (base->-pre? that)) + (not (base->-post? this)) + (not (base->-post? that)))) + +(define-struct (arity-check-only-> base->) (arity) + #:property + prop:flat-contract + (build-flat-contract-property + #:name base->-name + #:first-order + (λ (ctc) + (define arity (arity-check-only->-arity ctc)) + (λ (val) + (arrow:procedure-arity-includes?/no-kwds val arity))) + #:late-neg-projection + (λ (ctc) + (define arity (arity-check-only->-arity ctc)) + (λ (blame) + (λ (val neg-party) + (if (arrow:procedure-arity-includes?/no-kwds val arity) + val + (raise-blame-error + blame #:missing-party neg-party val + '(expected: "a procedure that accepts ~a non-keyword argument~a" + given: "~e") + arity + (if (= arity 1) "" "s") + val))))) + #:stronger ->-stronger + #:generate ->-generate + #:exercise ->-exercise)) + (define-struct (-> base->) () #:property prop:chaperone-contract diff --git a/racket/collects/racket/contract/private/arrow.rkt b/racket/collects/racket/contract/private/arrow.rkt index 0d9f9dea3a..c7c510a193 100644 --- a/racket/collects/racket/contract/private/arrow.rkt +++ b/racket/collects/racket/contract/private/arrow.rkt @@ -41,7 +41,8 @@ blame-add-range-context blame-add-nth-arg-context raise-no-keywords-arg - raise-wrong-number-of-args-error) + raise-wrong-number-of-args-error + procedure-arity-includes?/no-kwds) (define-syntax-parameter making-a-method #f) (define-syntax-parameter method-contract? #f) @@ -1911,6 +1912,8 @@ [(_ any/c ... any) (not (syntax-parameter-value #'making-a-method)) ;; special case the (-> any/c ... any) contracts to be first-order checks only + ;; this is now implemented by ->2 so we should get here only when we're + ;; building an ->m contract (let ([dom-len (- (length (syntax->list stx)) 2)]) #`(flat-named-contract '(-> #,@(build-list dom-len (λ (x) 'any/c)) any) diff --git a/racket/collects/racket/contract/private/provide.rkt b/racket/collects/racket/contract/private/provide.rkt index bd943af7bb..066c37d0f9 100644 --- a/racket/collects/racket/contract/private/provide.rkt +++ b/racket/collects/racket/contract/private/provide.rkt @@ -276,10 +276,12 @@ (define-values (arrow? the-valid-app-shapes) (syntax-case ctrct (->2 ->*2 ->i) [(->2 . _) - (->2-handled? ctrct) + (and (->2-handled? ctrct) + (not (->2-arity-check-only->? ctrct))) (values #t (->-valid-app-shapes ctrct))] [(->*2 . _) - (values (->*2-handled? ctrct) + (values (and (->*2-handled? ctrct) + (not (->2*-arity-check-only->? ctrct))) (->*-valid-app-shapes ctrct))] [(->i . _) (values #t (->i-valid-app-shapes ctrct))] [_ (values #f #f)])) From 2529e63b74f96a81f17fbe3eeeff77403ac6a947 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Fri, 1 Jan 2016 19:46:45 -0600 Subject: [PATCH 290/369] make stronger recognize any/c on the right as stronger than any flat contracts --- .../tests/racket/contract/stronger.rkt | 21 +++++++++++-------- .../collects/racket/contract/private/misc.rkt | 1 + .../collects/racket/contract/private/prop.rkt | 8 +++++++ 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/pkgs/racket-test/tests/racket/contract/stronger.rkt b/pkgs/racket-test/tests/racket/contract/stronger.rkt index 9783e91149..dc30bfc608 100644 --- a/pkgs/racket-test/tests/racket/contract/stronger.rkt +++ b/pkgs/racket-test/tests/racket/contract/stronger.rkt @@ -10,6 +10,7 @@ (contract-eval '(define-contract-struct triple (a b c))) (ctest #t contract-stronger? any/c any/c) + (ctest #t contract-stronger? integer? any/c) (ctest #t contract-stronger? (integer-in 0 4) (integer-in 0 4)) (ctest #t contract-stronger? (integer-in 1 3) (integer-in 0 4)) (ctest #f contract-stronger? (integer-in 0 4) (integer-in 1 3)) @@ -74,6 +75,8 @@ (ctest #t contract-stronger? (-> #:x (>=/c 3) (>=/c 3)) (-> #:x (>=/c 3) (>=/c 2))) (ctest #t contract-stronger? (-> any/c any/c any) (-> any/c any/c any)) (ctest #f contract-stronger? (-> any/c any/c any/c any) (-> any/c any/c any)) + (ctest #t contract-stronger? (-> (-> any/c) integer?) (-> (-> any/c) any/c)) + (ctest #f contract-stronger? (-> (-> any/c) any/c) (-> (-> any/c) integer?)) (let ([c (contract-eval '(->* () () any))]) (test #t (contract-eval 'contract-stronger?) c c)) @@ -89,8 +92,8 @@ (->* () integer? #:post (zero? (random 10))) (->* () integer? #:post (zero? (random 10)))) - (ctest #t contract-stronger? (or/c null? any/c) (or/c null? any/c)) - (ctest #f contract-stronger? (or/c null? any/c) (or/c boolean? any/c)) + (ctest #t contract-stronger? (or/c null? #f) (or/c null? #f)) + (ctest #f contract-stronger? (or/c null? #f) (or/c boolean? #f)) (ctest #t contract-stronger? (or/c null? boolean?) (or/c null? boolean?)) (ctest #t contract-stronger? (or/c null? boolean?) (or/c boolean? null?)) (ctest #t contract-stronger? @@ -111,8 +114,8 @@ (ctest #f contract-stronger? (-> (or/c #f number?)) (-> number?)) (ctest #f contract-stronger? (-> number? any/c) (-> (or/c #f number?) any/c)) - (ctest #t contract-stronger? (first-or/c null? any/c) (first-or/c null? any/c)) - (ctest #f contract-stronger? (first-or/c null? any/c) (first-or/c boolean? any/c)) + (ctest #t contract-stronger? (first-or/c null? #f) (first-or/c null? #f)) + (ctest #f contract-stronger? (first-or/c null? #f) (first-or/c boolean? #f)) (ctest #t contract-stronger? (first-or/c null? boolean?) (first-or/c null? boolean?)) (ctest #t contract-stronger? (first-or/c null? boolean?) (first-or/c boolean? null?)) (ctest #t contract-stronger? @@ -133,13 +136,13 @@ (ctest #f contract-stronger? (-> (first-or/c #f number?)) (-> number?)) (ctest #f contract-stronger? (-> number? any/c) (-> (first-or/c #f number?) any/c)) - (ctest #t contract-stronger? (first-or/c null? any/c) (or/c null? any/c)) - (ctest #f contract-stronger? (first-or/c null? any/c) (or/c boolean? any/c)) + (ctest #t contract-stronger? (first-or/c null? #f) (or/c null? #f)) + (ctest #f contract-stronger? (first-or/c null? #f) (or/c boolean? #f)) (ctest #t contract-stronger? (first-or/c null? boolean?) (or/c null? boolean?)) (ctest #t contract-stronger? (first-or/c null? boolean?) (or/c boolean? null?)) - (ctest #t contract-stronger? (or/c null? any/c) (first-or/c null? any/c)) - (ctest #f contract-stronger? (or/c null? any/c) (first-or/c boolean? any/c)) + (ctest #t contract-stronger? (or/c null? #f) (first-or/c null? #f)) + (ctest #f contract-stronger? (or/c null? #f) (first-or/c boolean? #f)) (ctest #t contract-stronger? (or/c null? boolean?) (first-or/c null? boolean?)) (ctest #t contract-stronger? (or/c null? boolean?) (first-or/c boolean? null?)) @@ -176,7 +179,7 @@ (or/c (-> string?) (-> integer? integer?)) (or/c (-> string?) (-> any/c integer?))) (ctest #f contract-stronger? - (or/c (-> string?) (-> any/c integer?)) + (or/c (-> string?) (-> #f integer?)) (or/c (-> string?) (-> integer? integer?))) (ctest #t contract-stronger? (or/c (-> string?) (-> integer? integer?) integer? boolean?) diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index 6025b72e96..7a2dbe399e 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -1447,6 +1447,7 @@ (define-struct any/c () #:property prop:custom-write custom-write-property-proc #:omit-define-syntaxes + #:property prop:any/c #f #:property prop:flat-contract (build-flat-contract-property #:late-neg-projection (λ (ctc) any/c-blame->neg-party-fn) diff --git a/racket/collects/racket/contract/private/prop.rkt b/racket/collects/racket/contract/private/prop.rkt index 9e95b1ce5d..4c51a8c21b 100644 --- a/racket/collects/racket/contract/private/prop.rkt +++ b/racket/collects/racket/contract/private/prop.rkt @@ -52,6 +52,8 @@ prop:arrow-contract-get-info (struct-out arrow-contract-info) + prop:any/c prop:any/c? + build-context) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -124,6 +126,7 @@ [(stronger? a b) ;; optimistically try skip some of the more complex work below #t] + [(and (flat-contract-struct? a) (prop:any/c? b)) #t] ;; is the flat-check needed here? [(let ([th (trail)]) (and th (for/or ([(a2 bs-h) (in-hash th)]) @@ -531,6 +534,11 @@ prop:recursive-contract-unroll) (make-struct-type-property 'prop:recursive-contract)) +;; this property's value isn't looked at; it is just a signal +;; that the contract accepts any value +(define-values (prop:any/c prop:any/c? prop:get-any/c) + (make-struct-type-property 'prop:any/c)) + ;; get-info : (-> ctc arrow-contract-info?) (define-values (prop:arrow-contract prop:arrow-contract? prop:arrow-contract-get-info) (make-struct-type-property 'prop:arrow-contract)) From 190925ee32947d323f70961f7950bd6a71227f4d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 2 Jan 2016 07:46:42 -0700 Subject: [PATCH 291/369] avoid a compiler warning --- racket/src/racket/src/hash.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/racket/src/racket/src/hash.c b/racket/src/racket/src/hash.c index 996bc1f9ac..220c16f528 100644 --- a/racket/src/racket/src/hash.c +++ b/racket/src/racket/src/hash.c @@ -276,12 +276,14 @@ static Scheme_Object *do_hash(Scheme_Hash_Table *table, Scheme_Object *key, int h = to_unsigned_hash(hx) & mask; if (_h2x) h2 = (to_unsigned_hash(h2x) & mask) | 1; + ekey = NULL; } } else { uintptr_t lkey; lkey = PTR_TO_LONG((Scheme_Object *)key); h = lkey & mask; h2 = ((lkey >> 1) & mask) | 1; + ekey = NULL; } keys = table->keys; From fdf56dfebf9473f16715657208b598c5054132df Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 2 Jan 2016 15:08:57 -0700 Subject: [PATCH 292/369] fix calculation of unexported bindings When a module defines and doesn't export it, but when the module imports and re-exports that refers to another module's definition of , then wasn't properly registered as an unexported binding. Most of the implementation change is just a clean-up of an unnecessary traversal from before the addition of a `count` field in each hash table. --- .../racket-test-core/tests/racket/module.rktl | 16 ++++++++++++ racket/src/racket/src/module.c | 26 ++++++------------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/module.rktl b/pkgs/racket-test-core/tests/racket/module.rktl index 32b05057a8..6333e70c86 100644 --- a/pkgs/racket-test-core/tests/racket/module.rktl +++ b/pkgs/racket-test-core/tests/racket/module.rktl @@ -1705,4 +1705,20 @@ case of module-leve bindings; it doesn't cover local bindings. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(module exports-x*-as-x racket/base + (define x* 5) + (provide (rename-out [x* x]))) + +(module exports-x**-as-x racket/base + (require 'exports-x*-as-x) + (define x* 5) + (define-syntax-rule (x**) x*) + (provide (rename-out [x x***]) + (rename-out [x** x]))) + +(require 'exports-x**-as-x) +(test 5 'five (x)) + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (report-errs) diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index 33ebc783a0..3c5822bf0c 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -10396,39 +10396,28 @@ static Scheme_Object **compute_indirects(Scheme_Env *genv, { int i, count, j, start, end; Scheme_Bucket **bs, *b; - Scheme_Object **exsns = pt->provide_src_names, **exis; + Scheme_Object **exsns = pt->provide_src_names, **exss = pt->provide_srcs, **exis; int exicount; Scheme_Bucket_Table *t; if (vars) { start = 0; end = pt->num_provides; /* check both vars & syntax, in case of rename transformer */ + t = genv->toplevel; } else { start = pt->num_var_provides; end = pt->num_provides; - } - - if (vars) - t = genv->toplevel; - else t = genv->syntax; - - - if (!t) - count = 0; - else { - bs = t->buckets; - for (count = 0, i = t->size; i--; ) { - b = bs[i]; - if (b && b->val) - count++; - } } + count = (t ? t->count : 0); + if (!count) { *_count = 0; return NULL; } + + bs = t->buckets; exis = MALLOC_N(Scheme_Object *, count); @@ -10441,7 +10430,8 @@ static Scheme_Object **compute_indirects(Scheme_Env *genv, /* If the name is directly provided, no need for indirect... */ for (j = start; j < end; j++) { - if (SAME_OBJ(name, exsns[j])) + if (SAME_OBJ(name, exsns[j]) + && SCHEME_FALSEP(exss[j])) break; } From 36b3493e45aba4b30c97a4fea7ee5fc931ae64da Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 2 Jan 2016 15:02:10 -0600 Subject: [PATCH 293/369] Change contracts of the form (-> any/c ... any) to not be flat contracts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The issue is what happens when the actual function has other arities. For example, if the function were (λ (x [y 1]) y) then it is not okay to simply check if procedure-arity-includes? of 1 is true (what the code used to do) because then when the function is applied to 2 arguments, the call won't fail like it should. It is possible to check and reject functions that don't have exactly the right arity, but if the contract were (-> string? any), then the function would have been allowed and only when the extra argument is supplied would the error occur. So, this commit makes it so that (-> any/c any) is like (-> string? any), but with the optimization that if the procedure accepts only one argument, then no wrapper is created. This is a backwards incompatible change because it used to be the case that (flat-contract? (-> any)) returned #t and it now returns #f. --- .../tests/racket/contract/arrow.rkt | 4 ++ .../tests/racket/contract/flat-contracts.rkt | 5 -- .../tests/racket/contract/predicates.rkt | 2 - .../contract/private/arrow-higher-order.rkt | 39 +++++++++++++-- .../contract/private/arrow-val-first.rkt | 47 ------------------- .../racket/contract/private/arrow.rkt | 23 +-------- 6 files changed, 40 insertions(+), 80 deletions(-) diff --git a/pkgs/racket-test/tests/racket/contract/arrow.rkt b/pkgs/racket-test/tests/racket/contract/arrow.rkt index c0de59f415..567b9233a4 100644 --- a/pkgs/racket-test/tests/racket/contract/arrow.rkt +++ b/pkgs/racket-test/tests/racket/contract/arrow.rkt @@ -318,6 +318,10 @@ (test/pos-blame 'contract-any/c-arrow4 '(contract (-> any/c any) (λ (x #:y y) x) 'pos 'neg)) + + (test/neg-blame + 'contract-any/c-arrow5 + '((contract (-> any/c any) (λ (x [y 1]) x) 'pos 'neg) 1 2)) (test/spec-passed 'contract-arrow-all-kwds2 diff --git a/pkgs/racket-test/tests/racket/contract/flat-contracts.rkt b/pkgs/racket-test/tests/racket/contract/flat-contracts.rkt index 2eb2d1418f..3c538b504d 100644 --- a/pkgs/racket-test/tests/racket/contract/flat-contracts.rkt +++ b/pkgs/racket-test/tests/racket/contract/flat-contracts.rkt @@ -71,11 +71,6 @@ (test-flat-contract #rx#".x." "axq" "x") (test-flat-contract ''() '() #f) - (test-flat-contract '(-> any/c any/c any) (λ (x y) 1) (λ (x y z) 1)) - (test-flat-contract '(->* (any/c any/c) any) (λ (x y) 1) (λ (x y z) 1)) - (test-flat-contract '(->* () any) (λ () 1) (λ (x y z w) 1)) - (test-flat-contract '(->* () () any) (λ () 1) (λ (x) 1)) - (test-flat-contract '(if/c integer? even? list?) 2 3) (test-flat-contract '(if/c integer? even? list?) '() #f) diff --git a/pkgs/racket-test/tests/racket/contract/predicates.rkt b/pkgs/racket-test/tests/racket/contract/predicates.rkt index 031d9baaf6..733affcb5b 100644 --- a/pkgs/racket-test/tests/racket/contract/predicates.rkt +++ b/pkgs/racket-test/tests/racket/contract/predicates.rkt @@ -15,8 +15,6 @@ (ctest #t flat-contract? (first-or/c (flat-contract integer?) (flat-contract boolean?))) (ctest #t flat-contract? (first-or/c integer? boolean?)) - (ctest #t flat-contract? (-> any/c any/c any)) - (ctest #t flat-contract? (and/c)) (ctest #t flat-contract? (and/c number? integer?)) (ctest #t flat-contract? (and/c (flat-contract number?) diff --git a/racket/collects/racket/contract/private/arrow-higher-order.rkt b/racket/collects/racket/contract/private/arrow-higher-order.rkt index 8c72a5cdde..b5590cd93a 100644 --- a/racket/collects/racket/contract/private/arrow-higher-order.rkt +++ b/racket/collects/racket/contract/private/arrow-higher-order.rkt @@ -357,6 +357,14 @@ late-neg?) (define optionals-length (- (length doms) min-arity)) (define mtd? #f) ;; not yet supported for the new contracts + (define okay-to-do-only-arity-check? + (and (not rest) + (not pre?) + (not post?) + (null? kwd-infos) + (not rngs) + (andmap any/c? doms) + (= optionals-length 0))) (λ (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)) @@ -425,19 +433,24 @@ impersonator-prop:application-mark (cons arrow:tail-contract-key (list* neg-party blame-party-info rngs))))] [else val])) - (cond [late-neg? - (λ (val neg-party) + (define (arrow-higher-order:lnp 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)]))] + (successfully-got-the-right-kind-of-function val neg-party)])) + (if okay-to-do-only-arity-check? + (λ (val neg-party) + (cond + [(procedure-arity-exactly/no-kwds val min-arity) val] + [else (arrow-higher-order:lnp val neg-party)])) + arrow-higher-order:lnp)] [else - (λ (val) + (define (arrow-higher-order:vfp val) (wrapped-extra-arg-arrow (cond [(do-arity-checking orig-blame val doms rest min-arity kwd-infos) @@ -446,4 +459,20 @@ [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)))]))) + (apply plus-one-arity-function orig-blame val plus-one-constructor-args))) + (if okay-to-do-only-arity-check? + (λ (val) + (cond + [(procedure-arity-exactly/no-kwds val min-arity) + (wrapped-extra-arg-arrow + (λ (neg-party) val) + (apply plus-one-arity-function orig-blame val plus-one-constructor-args))] + [else (arrow-higher-order:vfp val)])) + arrow-higher-order:vfp)]))) + +(define (procedure-arity-exactly/no-kwds val min-arity) + (and (procedure? val) + (equal? (procedure-arity val) min-arity) + (let-values ([(man opt) (procedure-keywords val)]) + (and (null? man) + (null? opt))))) diff --git a/racket/collects/racket/contract/private/arrow-val-first.rkt b/racket/collects/racket/contract/private/arrow-val-first.rkt index 5d9891fd8f..eeb1adffc5 100644 --- a/racket/collects/racket/contract/private/arrow-val-first.rkt +++ b/racket/collects/racket/contract/private/arrow-val-first.rkt @@ -542,9 +542,6 @@ [(_ args ...) (not (->2-handled? stx)) #'(arrow:-> args ...)] - [(_ args ...) - (->2-arity-check-only->? stx) - #`(build-arity-check-only-> #,(->2-arity-check-only->? stx))] [(_ args ... rng) (let () (define this-> (gensym 'this->)) @@ -662,10 +659,6 @@ (define-syntax (->*2 stx) (cond - [(->2*-arity-check-only->? stx) - => - (λ (n) - #`(build-arity-check-only-> #,n))] [(->*2-handled? stx) (define this->* (gensym 'this->*)) (define-values (man-dom man-dom-kwds man-lets @@ -826,18 +819,6 @@ plus-one-arity-function chaperone-constructor)])) -(define (build-arity-check-only-> n) - (make-arity-check-only-> n - (build-list n (λ (_) any/c)) - '() #f #f #f #f - (λ args - (error 'arity-check-only->-plus-one-arity-function - "this function should not be called ~s" args)) - (λ args - (error 'arity-check-only->-chaperone-constructor - "this function should not be called ~s" args)) - n)) - (define (dynamic->* #:mandatory-domain-contracts [mandatory-domain-contracts '()] #:optional-domain-contracts [optional-domain-contracts '()] #:mandatory-keywords [unsorted-mandatory-keywords '()] @@ -1244,34 +1225,6 @@ (not (base->-pre? that)) (not (base->-post? this)) (not (base->-post? that)))) - -(define-struct (arity-check-only-> base->) (arity) - #:property - prop:flat-contract - (build-flat-contract-property - #:name base->-name - #:first-order - (λ (ctc) - (define arity (arity-check-only->-arity ctc)) - (λ (val) - (arrow:procedure-arity-includes?/no-kwds val arity))) - #:late-neg-projection - (λ (ctc) - (define arity (arity-check-only->-arity ctc)) - (λ (blame) - (λ (val neg-party) - (if (arrow:procedure-arity-includes?/no-kwds val arity) - val - (raise-blame-error - blame #:missing-party neg-party val - '(expected: "a procedure that accepts ~a non-keyword argument~a" - given: "~e") - arity - (if (= arity 1) "" "s") - val))))) - #:stronger ->-stronger - #:generate ->-generate - #:exercise ->-exercise)) (define-struct (-> base->) () #:property diff --git a/racket/collects/racket/contract/private/arrow.rkt b/racket/collects/racket/contract/private/arrow.rkt index c7c510a193..72b596f12f 100644 --- a/racket/collects/racket/contract/private/arrow.rkt +++ b/racket/collects/racket/contract/private/arrow.rkt @@ -41,8 +41,7 @@ blame-add-range-context blame-add-nth-arg-context raise-no-keywords-arg - raise-wrong-number-of-args-error - procedure-arity-includes?/no-kwds) + raise-wrong-number-of-args-error) (define-syntax-parameter making-a-method #f) (define-syntax-parameter method-contract? #f) @@ -1908,25 +1907,7 @@ (define-syntax (-> stx) - (syntax-case stx (any any/c boolean?) - [(_ any/c ... any) - (not (syntax-parameter-value #'making-a-method)) - ;; special case the (-> any/c ... any) contracts to be first-order checks only - ;; this is now implemented by ->2 so we should get here only when we're - ;; building an ->m contract - (let ([dom-len (- (length (syntax->list stx)) 2)]) - #`(flat-named-contract - '(-> #,@(build-list dom-len (λ (x) 'any/c)) any) - (λ (x) - (procedure-arity-includes?/no-kwds x #,dom-len))))] - [_ - #`(syntax-parameterize ((making-a-method #f)) #,(->/proc/main stx))])) - -(define (procedure-arity-includes?/no-kwds val dom-len) - (and (procedure? val) - (procedure-arity-includes? val dom-len) - (let-values ([(man opt) (procedure-keywords val)]) - (null? man)))) + #`(syntax-parameterize ((making-a-method #f)) #,(->/proc/main stx))) ;; this is to make the expanded versions a little easier to read (define-syntax (values/drop stx) From 0796350a8886fc17565b2941f14c89a87e38a208 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sat, 2 Jan 2016 12:53:18 -0600 Subject: [PATCH 294/369] Extend `random` to work with ranges and sequences. Requested by Matthias. --- .../scribblings/reference/numbers.scrbl | 21 +++++- .../racket-test-core/tests/racket/number.rktl | 20 +++++- racket/collects/racket/private/for.rkt | 28 ++++++++ racket/collects/racket/private/pre-base.rkt | 67 ++++++++++++++++++- racket/collects/racket/private/sequence.rkt | 4 +- racket/collects/racket/sequence.rkt | 23 ------- 6 files changed, 133 insertions(+), 30 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/numbers.scrbl b/pkgs/racket-doc/scribblings/reference/numbers.scrbl index 1ce1061240..0817ec2de8 100644 --- a/pkgs/racket-doc/scribblings/reference/numbers.scrbl +++ b/pkgs/racket-doc/scribblings/reference/numbers.scrbl @@ -842,13 +842,30 @@ both in binary and as integers. [rand-gen pseudo-random-generator? (current-pseudo-random-generator)]) exact-nonnegative-integer?] + [(random [min (integer-in 1 4294967087)] + [max (integer-in 1 4294967087)] + [rand-gen pseudo-random-generator? + (current-pseudo-random-generator)]) + exact-nonnegative-integer?] + [(random [seq sequence?] + [rand-gen pseudo-random-generator? + (current-pseudo-random-generator)]) + any/c] [(random [rand-gen pseudo-random-generator? (current-pseudo-random-generator)]) (and/c real? inexact? (>/c 0) (pseudo-random-generator + #(3620087466 1904163406 3177592043 1406334318 257151704 3090455638))]) + (test 3 random '(1 2 3 4 5)) + (test 10 random '#(7 6 8 9 10)) + (test #\e random "abcde")) (test #t = 0 0) (test #f = 0 (expt 2 32)) diff --git a/racket/collects/racket/private/for.rkt b/racket/collects/racket/private/for.rkt index c95664af1a..12851138ec 100644 --- a/racket/collects/racket/private/for.rkt +++ b/racket/collects/racket/private/for.rkt @@ -78,6 +78,9 @@ sequence-generate sequence-generate* prop:sequence + sequence-length + + -sequence-ref define-sequence-syntax make-do-sequence @@ -2029,4 +2032,29 @@ #true [(next-body l d init-dir use-dir?)])]]))) + (define-values (sequence-length) + (λ (s) + (unless (sequence? s) (raise-argument-error 'sequence-length "sequence?" s)) + (for/fold ([c 0]) ([i (in-values*-sequence s)]) + (add1 c)))) + + (define-values (-sequence-ref) + (λ (s i) + (unless (sequence? s) (raise-argument-error 'sequence-ref "sequence?" s)) + (unless (exact-nonnegative-integer? i) + (raise-argument-error 'sequence-ref "exact-nonnegative-integer?" i)) + (let-values ([(v) (for/fold ([c #f]) ([v (in-values*-sequence s)] + [j (in-range (add1 i))] + #:unless (j . < . i)) + (or v '(#f)))]) + (cond + [(not v) + (raise-arguments-error + 'sequence-ref + "sequence ended before index" + "index" i + "sequence" s)] + [(list? v) (apply values v)] + [else v])))) + ) diff --git a/racket/collects/racket/private/pre-base.rkt b/racket/collects/racket/private/pre-base.rkt index e695d4bf08..15986c49bc 100644 --- a/racket/collects/racket/private/pre-base.rkt +++ b/racket/collects/racket/private/pre-base.rkt @@ -97,6 +97,67 @@ (define-values (double-flonum?) ; for symmetry with single-flonum? (lambda (x) (flonum? x))) + (define-values (enforce-random-int-range) + (lambda (x) + (unless (and (exact-positive-integer? x) + (<= x 4294967087)) + (raise-argument-error 'random "(integer-in 1 4294967087)" x)))) + (define-values (enforce-greater) + (lambda (x y) + (unless (> y x) + (raise-argument-error + 'random + (string-append "integer greater than " (number->string x)) + y)))) + (define-values (-random) ; more featureful than #%kernel's `random` + (case-lambda + [() (random)] ; no args, random float + [(x) + ;; one arg, either random float with prng, or random integer, or random + ;; sequence element + (cond [(exact-positive-integer? x) + (enforce-random-int-range x) + (random x)] + [(pseudo-random-generator? x) + (random x)] + [(sequence? x) + (-sequence-ref x (random (sequence-length x)))] + [else + (raise-argument-error + 'random + "(or/c (integer-in 1 4294967087) sequence? pseudo-random-generator?)" + x)])] + [(x y) + ;; two args, either min and prng, or min and max, or sequence and prng + (cond [(exact-positive-integer? y) ; min and max case + (enforce-random-int-range x) + (enforce-random-int-range y) + (enforce-greater x y) + (+ x (random (- y x)))] + [(pseudo-random-generator? y) + (cond [(exact-positive-integer? x) ; int and prng case + (enforce-random-int-range x) + (random x y)] + [(sequence? x) ; sequence and prng case + (-sequence-ref x (random (sequence-length x) y))] + [else + (raise-argument-error + 'random + "(or/c (integer-in 1 4294967087) sequence?)" + x)])] + [else + (raise-argument-error + 'random + "(or/c (integer-in 1 4294967087) pseudo-random-generator?)" + y)])] + [(min max prng) ; three args: min, max, and prng + (enforce-random-int-range min) + (enforce-random-int-range max) + (enforce-greater min max) + (unless (pseudo-random-generator? prng) + (raise-argument-error 'random "pseudo-random-generator?" prng)) + (+ min (random (- max min) prng))])) + (define-values (new:collection-path) (let ([collection-path (new-lambda (collection #:fail [fail (lambda (s) @@ -184,7 +245,8 @@ chaperone-procedure impersonate-procedure chaperone-procedure* impersonate-procedure* assq assv assoc - prop:incomplete-arity prop:method-arity-error) + prop:incomplete-arity prop:method-arity-error + random) (all-from "reqprov.rkt") (all-from-except "for.rkt" define-in-vector-like @@ -207,4 +269,5 @@ define-struct/derived struct-field-index struct-copy - double-flonum?)) + double-flonum? + (rename -random random))) diff --git a/racket/collects/racket/private/sequence.rkt b/racket/collects/racket/private/sequence.rkt index 3c25917e3a..4c199d9251 100644 --- a/racket/collects/racket/private/sequence.rkt +++ b/racket/collects/racket/private/sequence.rkt @@ -9,7 +9,9 @@ sequence-ormap sequence-for-each sequence-fold - sequence-count) + sequence-count + sequence-length + (rename-out [-sequence-ref sequence-ref])) (define (sequence-andmap f s) (unless (procedure? f) (raise-argument-error 'sequence-andmap "procedure?" f)) diff --git a/racket/collects/racket/sequence.rkt b/racket/collects/racket/sequence.rkt index cd68cd305c..51d98f1996 100644 --- a/racket/collects/racket/sequence.rkt +++ b/racket/collects/racket/sequence.rkt @@ -39,29 +39,6 @@ (define (sequence->list s) (for/list ([v s]) v)) -(define (sequence-length s) - (unless (sequence? s) (raise-argument-error 'sequence-length "sequence?" s)) - (for/fold ([c 0]) ([i (in-values*-sequence s)]) - (add1 c))) - -(define (sequence-ref s i) - (unless (sequence? s) (raise-argument-error 'sequence-ref "sequence?" s)) - (unless (exact-nonnegative-integer? i) - (raise-argument-error 'sequence-ref "exact-nonnegative-integer?" i)) - (let ([v (for/fold ([c #f]) ([v (in-values*-sequence s)] - [j (in-range (add1 i))] - #:unless (j . < . i)) - (or v '(#f)))]) - (cond - [(not v) - (raise-arguments-error - 'sequence-ref - "sequence ended before index" - "index" i - "sequence" s)] - [(list? v) (apply values v)] - [else v]))) - (define (sequence-tail seq i) (unless (sequence? seq) (raise-argument-error 'sequence-tail "sequence?" seq)) (unless (exact-nonnegative-integer? i) From 6af2f711b7c9dae7804d5d18e21593f26d180c28 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sat, 2 Jan 2016 12:59:15 -0600 Subject: [PATCH 295/369] Fix optimization tests. --- pkgs/racket-test-core/tests/racket/optimize.rktl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index 1aa59ed2a5..01ab2b1f16 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -9,7 +9,10 @@ racket/unsafe/undefined racket/unsafe/ops compiler/zo-parse - compiler/zo-marshal) + compiler/zo-marshal + ;; `random` from `racket/base is a Racket function, which makes + ;; compilation less predictable than a primitive + (only-in '#%kernel random)) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; From 707f9bffa683ece27d0cb971b9140b06602a4154 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sat, 2 Jan 2016 15:49:28 -0600 Subject: [PATCH 296/369] random: move sequence support to `random-ref`, in `racket/random`. And add `random-sample`. --- .../scribblings/reference/numbers.scrbl | 52 ++++++++++++++----- .../racket-test-core/tests/racket/number.rktl | 23 +++++--- racket/collects/racket/private/for.rkt | 28 ---------- racket/collects/racket/private/pre-base.rkt | 23 +++----- racket/collects/racket/private/sequence.rkt | 4 +- racket/collects/racket/random.rkt | 32 +++++++++++- racket/collects/racket/sequence.rkt | 23 ++++++++ 7 files changed, 113 insertions(+), 72 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/numbers.scrbl b/pkgs/racket-doc/scribblings/reference/numbers.scrbl index 0817ec2de8..28e2c7121c 100644 --- a/pkgs/racket-doc/scribblings/reference/numbers.scrbl +++ b/pkgs/racket-doc/scribblings/reference/numbers.scrbl @@ -847,10 +847,6 @@ both in binary and as integers. [rand-gen pseudo-random-generator? (current-pseudo-random-generator)]) exact-nonnegative-integer?] - [(random [seq sequence?] - [rand-gen pseudo-random-generator? - (current-pseudo-random-generator)]) - any/c] [(random [rand-gen pseudo-random-generator? (current-pseudo-random-generator)]) (and/c real? inexact? (>/c 0) (pseudo-random-generator #(3620087466 1904163406 3177592043 1406334318 257151704 3090455638))]) - (test 3 random '(1 2 3 4 5)) - (test 10 random '#(7 6 8 9 10)) - (test #\e random "abcde")) + (test 3 random-ref '(1 2 3 4 5)) + (test 10 random-ref '#(7 6 8 9 10)) + (test #\e random-ref "abcde")) +(parameterize ([current-pseudo-random-generator + (vector->pseudo-random-generator + #(3620087466 1904163406 3177592043 1406334318 257151704 3090455638))]) + (test '(3) random-sample '(1 2 3 4 5) 1) + (test '(5 5 5) random-sample '(1 2 3 4 5) 3) + (test '(2 4 5) random-sample '(1 2 3 4 5) 3 #:replacement? #f)) + (test #t = 0 0) (test #f = 0 (expt 2 32)) diff --git a/racket/collects/racket/private/for.rkt b/racket/collects/racket/private/for.rkt index 12851138ec..c95664af1a 100644 --- a/racket/collects/racket/private/for.rkt +++ b/racket/collects/racket/private/for.rkt @@ -78,9 +78,6 @@ sequence-generate sequence-generate* prop:sequence - sequence-length - - -sequence-ref define-sequence-syntax make-do-sequence @@ -2032,29 +2029,4 @@ #true [(next-body l d init-dir use-dir?)])]]))) - (define-values (sequence-length) - (λ (s) - (unless (sequence? s) (raise-argument-error 'sequence-length "sequence?" s)) - (for/fold ([c 0]) ([i (in-values*-sequence s)]) - (add1 c)))) - - (define-values (-sequence-ref) - (λ (s i) - (unless (sequence? s) (raise-argument-error 'sequence-ref "sequence?" s)) - (unless (exact-nonnegative-integer? i) - (raise-argument-error 'sequence-ref "exact-nonnegative-integer?" i)) - (let-values ([(v) (for/fold ([c #f]) ([v (in-values*-sequence s)] - [j (in-range (add1 i))] - #:unless (j . < . i)) - (or v '(#f)))]) - (cond - [(not v) - (raise-arguments-error - 'sequence-ref - "sequence ended before index" - "index" i - "sequence" s)] - [(list? v) (apply values v)] - [else v])))) - ) diff --git a/racket/collects/racket/private/pre-base.rkt b/racket/collects/racket/private/pre-base.rkt index 15986c49bc..b0e4575df4 100644 --- a/racket/collects/racket/private/pre-base.rkt +++ b/racket/collects/racket/private/pre-base.rkt @@ -113,38 +113,27 @@ (case-lambda [() (random)] ; no args, random float [(x) - ;; one arg, either random float with prng, or random integer, or random - ;; sequence element + ;; one arg, either random float with prng, or random integer (cond [(exact-positive-integer? x) (enforce-random-int-range x) (random x)] [(pseudo-random-generator? x) (random x)] - [(sequence? x) - (-sequence-ref x (random (sequence-length x)))] [else (raise-argument-error 'random - "(or/c (integer-in 1 4294967087) sequence? pseudo-random-generator?)" + "(or/c (integer-in 1 4294967087) pseudo-random-generator?)" x)])] [(x y) - ;; two args, either min and prng, or min and max, or sequence and prng + ;; two args, either min and prng, or min and max (cond [(exact-positive-integer? y) ; min and max case (enforce-random-int-range x) (enforce-random-int-range y) (enforce-greater x y) (+ x (random (- y x)))] - [(pseudo-random-generator? y) - (cond [(exact-positive-integer? x) ; int and prng case - (enforce-random-int-range x) - (random x y)] - [(sequence? x) ; sequence and prng case - (-sequence-ref x (random (sequence-length x) y))] - [else - (raise-argument-error - 'random - "(or/c (integer-in 1 4294967087) sequence?)" - x)])] + [(pseudo-random-generator? y) ; int and prng case + (enforce-random-int-range x) + (random x y)] [else (raise-argument-error 'random diff --git a/racket/collects/racket/private/sequence.rkt b/racket/collects/racket/private/sequence.rkt index 4c199d9251..3c25917e3a 100644 --- a/racket/collects/racket/private/sequence.rkt +++ b/racket/collects/racket/private/sequence.rkt @@ -9,9 +9,7 @@ sequence-ormap sequence-for-each sequence-fold - sequence-count - sequence-length - (rename-out [-sequence-ref sequence-ref])) + sequence-count) (define (sequence-andmap f s) (unless (procedure? f) (raise-argument-error 'sequence-andmap "procedure?" f)) diff --git a/racket/collects/racket/random.rkt b/racket/collects/racket/random.rkt index 2978444c9b..83955dbc2b 100644 --- a/racket/collects/racket/random.rkt +++ b/racket/collects/racket/random.rkt @@ -1,7 +1,13 @@ #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?)])) +(require "private/unix-rand.rkt" "private/windows-rand.rkt" + racket/contract/base racket/sequence racket/set) +(provide (contract-out [crypto-random-bytes (-> exact-nonnegative-integer? bytes?)] + [random-ref (->* (sequence?) (pseudo-random-generator?) any/c)] + [random-sample (->* (sequence? exact-nonnegative-integer?) + (pseudo-random-generator? + #:replacement? any/c) + (listof any/c))])) ; (: crypto-random-bytes (-> Positive-Integer Bytes)) ; returns n random bytes from the os. @@ -12,3 +18,25 @@ [else (raise (make-exn:fail:unsupported "not supported on the current platform" (current-continuation-marks)))])) + +(define (random-ref seq [prng (current-pseudo-random-generator)]) + (sequence-ref seq (random (sequence-length seq)))) + +(define (random-sample seq n [prng (current-pseudo-random-generator)] + #:replacement? [replacement? #t]) + (cond [replacement? + (for/list ([i (in-range n)]) + (random-ref seq prng))] + [else + (unless (>= (sequence-length seq) n) + (raise-argument-error 'random-sample + "integer less than sequence length" + n)) + (define l (sequence-length seq)) + ;; sequences don't necessarily support removal, so instead sample + ;; indices without replacement, then index into the sequence + (let loop ([res-idx (set)]) + (cond [(= (set-count res-idx) n) ; we have all we need, we're done + (for/list ([i (in-set res-idx)]) (sequence-ref seq i))] + [else + (loop (set-add res-idx (random l)))]))])) diff --git a/racket/collects/racket/sequence.rkt b/racket/collects/racket/sequence.rkt index 51d98f1996..cd68cd305c 100644 --- a/racket/collects/racket/sequence.rkt +++ b/racket/collects/racket/sequence.rkt @@ -39,6 +39,29 @@ (define (sequence->list s) (for/list ([v s]) v)) +(define (sequence-length s) + (unless (sequence? s) (raise-argument-error 'sequence-length "sequence?" s)) + (for/fold ([c 0]) ([i (in-values*-sequence s)]) + (add1 c))) + +(define (sequence-ref s i) + (unless (sequence? s) (raise-argument-error 'sequence-ref "sequence?" s)) + (unless (exact-nonnegative-integer? i) + (raise-argument-error 'sequence-ref "exact-nonnegative-integer?" i)) + (let ([v (for/fold ([c #f]) ([v (in-values*-sequence s)] + [j (in-range (add1 i))] + #:unless (j . < . i)) + (or v '(#f)))]) + (cond + [(not v) + (raise-arguments-error + 'sequence-ref + "sequence ended before index" + "index" i + "sequence" s)] + [(list? v) (apply values v)] + [else v]))) + (define (sequence-tail seq i) (unless (sequence? seq) (raise-argument-error 'sequence-tail "sequence?" seq)) (unless (exact-nonnegative-integer? i) From acb7d999ba45c7f06968ea9fb83667d3327ad0c2 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sat, 2 Jan 2016 16:05:16 -0600 Subject: [PATCH 297/369] Comment typo. Pointed out by Gustavo. --- racket/collects/racket/private/pre-base.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/racket/private/pre-base.rkt b/racket/collects/racket/private/pre-base.rkt index b0e4575df4..468edddd23 100644 --- a/racket/collects/racket/private/pre-base.rkt +++ b/racket/collects/racket/private/pre-base.rkt @@ -125,7 +125,7 @@ "(or/c (integer-in 1 4294967087) pseudo-random-generator?)" x)])] [(x y) - ;; two args, either min and prng, or min and max + ;; two args, either max and prng, or min and max (cond [(exact-positive-integer? y) ; min and max case (enforce-random-int-range x) (enforce-random-int-range y) From 740b6dc19881f07a505c60362c211b48db85095c Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sat, 2 Jan 2016 16:10:53 -0600 Subject: [PATCH 298/369] random: Remove redundant checking. --- racket/collects/racket/private/pre-base.rkt | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/racket/collects/racket/private/pre-base.rkt b/racket/collects/racket/private/pre-base.rkt index 468edddd23..4fe514062d 100644 --- a/racket/collects/racket/private/pre-base.rkt +++ b/racket/collects/racket/private/pre-base.rkt @@ -112,18 +112,10 @@ (define-values (-random) ; more featureful than #%kernel's `random` (case-lambda [() (random)] ; no args, random float - [(x) - ;; one arg, either random float with prng, or random integer - (cond [(exact-positive-integer? x) - (enforce-random-int-range x) - (random x)] - [(pseudo-random-generator? x) - (random x)] - [else - (raise-argument-error - 'random - "(or/c (integer-in 1 4294967087) pseudo-random-generator?)" - x)])] + [(x) ; one arg, either random float with prng, or random integer + ;; can just pass through to #%kernel's `random`, which will do the + ;; necessary checking + (random x)] [(x y) ;; two args, either max and prng, or min and max (cond [(exact-positive-integer? y) ; min and max case From 47f06f11e15aeb1adacfc8f74a4cd3d64511ce4c Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sat, 2 Jan 2016 19:14:16 -0600 Subject: [PATCH 299/369] random: encourage inlining. Reduces overhead to 6% over #%kernel's for the integer case. --- racket/collects/racket/private/pre-base.rkt | 60 +++++++++++---------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/racket/collects/racket/private/pre-base.rkt b/racket/collects/racket/private/pre-base.rkt index 4fe514062d..ee0f14c89e 100644 --- a/racket/collects/racket/private/pre-base.rkt +++ b/racket/collects/racket/private/pre-base.rkt @@ -17,6 +17,7 @@ "member.rkt" "kernstruct.rkt" "norm-arity.rkt" + "performance-hint.rkt" "top-int.rkt" '#%builtin ; so it's attached (for-syntax "kw.rkt" @@ -109,35 +110,36 @@ 'random (string-append "integer greater than " (number->string x)) y)))) - (define-values (-random) ; more featureful than #%kernel's `random` - (case-lambda - [() (random)] ; no args, random float - [(x) ; one arg, either random float with prng, or random integer - ;; can just pass through to #%kernel's `random`, which will do the - ;; necessary checking - (random x)] - [(x y) - ;; two args, either max and prng, or min and max - (cond [(exact-positive-integer? y) ; min and max case - (enforce-random-int-range x) - (enforce-random-int-range y) - (enforce-greater x y) - (+ x (random (- y x)))] - [(pseudo-random-generator? y) ; int and prng case - (enforce-random-int-range x) - (random x y)] - [else - (raise-argument-error - 'random - "(or/c (integer-in 1 4294967087) pseudo-random-generator?)" - y)])] - [(min max prng) ; three args: min, max, and prng - (enforce-random-int-range min) - (enforce-random-int-range max) - (enforce-greater min max) - (unless (pseudo-random-generator? prng) - (raise-argument-error 'random "pseudo-random-generator?" prng)) - (+ min (random (- max min) prng))])) + (begin-encourage-inline + (define-values (-random) ; more featureful than #%kernel's `random` + (case-lambda + [() (random)] ; no args, random float + [(x) ; one arg, either random float with prng, or random integer + ;; can just pass through to #%kernel's `random`, which will do the + ;; necessary checking + (random x)] + [(x y) + ;; two args, either max and prng, or min and max + (cond [(exact-positive-integer? y) ; min and max case + (enforce-random-int-range x) + (enforce-random-int-range y) + (enforce-greater x y) + (+ x (random (- y x)))] + [(pseudo-random-generator? y) ; int and prng case + (enforce-random-int-range x) + (random x y)] + [else + (raise-argument-error + 'random + "(or/c (integer-in 1 4294967087) pseudo-random-generator?)" + y)])] + [(min max prng) ; three args: min, max, and prng + (enforce-random-int-range min) + (enforce-random-int-range max) + (enforce-greater min max) + (unless (pseudo-random-generator? prng) + (raise-argument-error 'random "pseudo-random-generator?" prng)) + (+ min (random (- max min) prng))]))) (define-values (new:collection-path) (let ([collection-path (new-lambda (collection From c47c0ebfca088e9b5c3079c133931244906c0edd Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sat, 2 Jan 2016 20:05:04 -0600 Subject: [PATCH 300/369] sequence-length: special case O(1) cases. --- racket/collects/racket/sequence.rkt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/racket/collects/racket/sequence.rkt b/racket/collects/racket/sequence.rkt index cd68cd305c..128d71cd17 100644 --- a/racket/collects/racket/sequence.rkt +++ b/racket/collects/racket/sequence.rkt @@ -41,8 +41,11 @@ (define (sequence-length s) (unless (sequence? s) (raise-argument-error 'sequence-length "sequence?" s)) - (for/fold ([c 0]) ([i (in-values*-sequence s)]) - (add1 c))) + (cond [(vector? s) (vector-length s)] + [(hash? s) (hash-count s)] + [else + (for/fold ([c 0]) ([i (in-values*-sequence s)]) + (add1 c))])) (define (sequence-ref s i) (unless (sequence? s) (raise-argument-error 'sequence-ref "sequence?" s)) From 2aa9d8cca3763b48e1b8bb53e75a21b7939b50e2 Mon Sep 17 00:00:00 2001 From: Leif Andersen Date: Sat, 2 Jan 2016 23:07:31 -0700 Subject: [PATCH 301/369] Fixed typo in zo docs. --- 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 5de07392c4..d0f86d547f 100644 --- a/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl +++ b/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl @@ -274,7 +274,7 @@ binding, constructor, etc.} The @racket[lang-info] value specifies an optional module path that provides information about the module's implementation language. - The @racket[internal-module-context] value describes the lexical + The @racket[internal-context] value describes the lexical context of the body of the module. This value is used by @racket[module->namespace]. A @racket[#f] value means that the context is unavailable or empty. A @racket[#t] value means that the From 1e18a7e2b4299005a81454325535df40d25b1b2b Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sun, 3 Jan 2016 12:57:21 -0600 Subject: [PATCH 302/369] sequence-length: special-case lists too. --- racket/collects/racket/sequence.rkt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/racket/collects/racket/sequence.rkt b/racket/collects/racket/sequence.rkt index 128d71cd17..2cc60ed388 100644 --- a/racket/collects/racket/sequence.rkt +++ b/racket/collects/racket/sequence.rkt @@ -41,7 +41,8 @@ (define (sequence-length s) (unless (sequence? s) (raise-argument-error 'sequence-length "sequence?" s)) - (cond [(vector? s) (vector-length s)] + (cond [(list? s) (length s)] + [(vector? s) (vector-length s)] [(hash? s) (hash-count s)] [else (for/fold ([c 0]) ([i (in-values*-sequence s)]) From 4509430063e6f60ff23838da44d5d5db391f24f7 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sun, 3 Jan 2016 12:58:50 -0600 Subject: [PATCH 303/369] Fix object name for new `random` function. --- racket/collects/racket/private/pre-base.rkt | 58 +++++++++++---------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/racket/collects/racket/private/pre-base.rkt b/racket/collects/racket/private/pre-base.rkt index ee0f14c89e..405e5bda9f 100644 --- a/racket/collects/racket/private/pre-base.rkt +++ b/racket/collects/racket/private/pre-base.rkt @@ -112,34 +112,36 @@ y)))) (begin-encourage-inline (define-values (-random) ; more featureful than #%kernel's `random` - (case-lambda - [() (random)] ; no args, random float - [(x) ; one arg, either random float with prng, or random integer - ;; can just pass through to #%kernel's `random`, which will do the - ;; necessary checking - (random x)] - [(x y) - ;; two args, either max and prng, or min and max - (cond [(exact-positive-integer? y) ; min and max case - (enforce-random-int-range x) - (enforce-random-int-range y) - (enforce-greater x y) - (+ x (random (- y x)))] - [(pseudo-random-generator? y) ; int and prng case - (enforce-random-int-range x) - (random x y)] - [else - (raise-argument-error - 'random - "(or/c (integer-in 1 4294967087) pseudo-random-generator?)" - y)])] - [(min max prng) ; three args: min, max, and prng - (enforce-random-int-range min) - (enforce-random-int-range max) - (enforce-greater min max) - (unless (pseudo-random-generator? prng) - (raise-argument-error 'random "pseudo-random-generator?" prng)) - (+ min (random (- max min) prng))]))) + (procedure-rename + (case-lambda + [() (random)] ; no args, random float + [(x) ; one arg, either random float with prng, or random integer + ;; can just pass through to #%kernel's `random`, which will do the + ;; necessary checking + (random x)] + [(x y) + ;; two args, either max and prng, or min and max + (cond [(exact-positive-integer? y) ; min and max case + (enforce-random-int-range x) + (enforce-random-int-range y) + (enforce-greater x y) + (+ x (random (- y x)))] + [(pseudo-random-generator? y) ; int and prng case + (enforce-random-int-range x) + (random x y)] + [else + (raise-argument-error + 'random + "(or/c (integer-in 1 4294967087) pseudo-random-generator?)" + y)])] + [(min max prng) ; three args: min, max, and prng + (enforce-random-int-range min) + (enforce-random-int-range max) + (enforce-greater min max) + (unless (pseudo-random-generator? prng) + (raise-argument-error 'random "pseudo-random-generator?" prng)) + (+ min (random (- max min) prng))]) + 'random))) (define-values (new:collection-path) (let ([collection-path (new-lambda (collection From cc79e2241cedd55727b480a13b6c85df2eeefb5d Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sun, 3 Jan 2016 13:53:31 -0600 Subject: [PATCH 304/369] random: Get the right name without run-time overhead. --- racket/collects/racket/private/pre-base.rkt | 60 ++++++++++----------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/racket/collects/racket/private/pre-base.rkt b/racket/collects/racket/private/pre-base.rkt index 405e5bda9f..f8a5474981 100644 --- a/racket/collects/racket/private/pre-base.rkt +++ b/racket/collects/racket/private/pre-base.rkt @@ -112,36 +112,36 @@ y)))) (begin-encourage-inline (define-values (-random) ; more featureful than #%kernel's `random` - (procedure-rename - (case-lambda - [() (random)] ; no args, random float - [(x) ; one arg, either random float with prng, or random integer - ;; can just pass through to #%kernel's `random`, which will do the - ;; necessary checking - (random x)] - [(x y) - ;; two args, either max and prng, or min and max - (cond [(exact-positive-integer? y) ; min and max case - (enforce-random-int-range x) - (enforce-random-int-range y) - (enforce-greater x y) - (+ x (random (- y x)))] - [(pseudo-random-generator? y) ; int and prng case - (enforce-random-int-range x) - (random x y)] - [else - (raise-argument-error - 'random - "(or/c (integer-in 1 4294967087) pseudo-random-generator?)" - y)])] - [(min max prng) ; three args: min, max, and prng - (enforce-random-int-range min) - (enforce-random-int-range max) - (enforce-greater min max) - (unless (pseudo-random-generator? prng) - (raise-argument-error 'random "pseudo-random-generator?" prng)) - (+ min (random (- max min) prng))]) - 'random))) + (let ([random ; to get the right name + (case-lambda + [() (random)] ; no args, random float + [(x) ; one arg, either random float with prng, or random integer + ;; can just pass through to #%kernel's `random`, which will do the + ;; necessary checking + (random x)] + [(x y) + ;; two args, either max and prng, or min and max + (cond [(exact-positive-integer? y) ; min and max case + (enforce-random-int-range x) + (enforce-random-int-range y) + (enforce-greater x y) + (+ x (random (- y x)))] + [(pseudo-random-generator? y) ; int and prng case + (enforce-random-int-range x) + (random x y)] + [else + (raise-argument-error + 'random + "(or/c (integer-in 1 4294967087) pseudo-random-generator?)" + y)])] + [(min max prng) ; three args: min, max, and prng + (enforce-random-int-range min) + (enforce-random-int-range max) + (enforce-greater min max) + (unless (pseudo-random-generator? prng) + (raise-argument-error 'random "pseudo-random-generator?" prng)) + (+ min (random (- max min) prng))])]) + random))) (define-values (new:collection-path) (let ([collection-path (new-lambda (collection From 77a76a795304cfb5910bf2c10fb24729b45c4a20 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 2 Jan 2016 20:49:06 -0600 Subject: [PATCH 305/369] fix opt/c for the new way (-> any/c ... any) works should have been a part of 36b3493e --- .../tests/racket/contract/arrow.rkt | 13 ++++++ .../contract/private/arrow-higher-order.rkt | 1 + .../racket/contract/private/opters.rkt | 46 ++++++++----------- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/pkgs/racket-test/tests/racket/contract/arrow.rkt b/pkgs/racket-test/tests/racket/contract/arrow.rkt index 567b9233a4..c5ecff1614 100644 --- a/pkgs/racket-test/tests/racket/contract/arrow.rkt +++ b/pkgs/racket-test/tests/racket/contract/arrow.rkt @@ -323,6 +323,19 @@ 'contract-any/c-arrow5 '((contract (-> any/c any) (λ (x [y 1]) x) 'pos 'neg) 1 2)) + (test/spec-passed/result + 'contract-any/c-arrow6 + '(let ([f (λ (x) x)]) + (eq? f (contract (-> any/c any) f 'pos 'neg))) + #t) + + (test/spec-passed/result + 'contract-any/c-arrow7 + '(let ([f (λ (x [y 1]) x)]) + (eq? f (contract (-> any/c any) f 'pos 'neg))) + #f) + + (test/spec-passed 'contract-arrow-all-kwds2 '((contract (-> #:a string? void?) diff --git a/racket/collects/racket/contract/private/arrow-higher-order.rkt b/racket/collects/racket/contract/private/arrow-higher-order.rkt index b5590cd93a..01e0469037 100644 --- a/racket/collects/racket/contract/private/arrow-higher-order.rkt +++ b/racket/collects/racket/contract/private/arrow-higher-order.rkt @@ -11,6 +11,7 @@ (prefix-in arrow: "arrow.rkt")) (provide (for-syntax build-chaperone-constructor/real) + procedure-arity-exactly/no-kwds ->-proj check-pre-cond check-post-cond diff --git a/racket/collects/racket/contract/private/opters.rkt b/racket/collects/racket/contract/private/opters.rkt index 64c4e97b25..7eaa59ea07 100644 --- a/racket/collects/racket/contract/private/opters.rkt +++ b/racket/collects/racket/contract/private/opters.rkt @@ -6,6 +6,7 @@ "blame.rkt" "arrow.rkt" "arrow-val-first.rkt" + "arrow-higher-order.rkt" "orc.rkt" (for-syntax racket/base syntax/stx @@ -619,6 +620,10 @@ #`(list 'values #,@rng-names)))))) (define (opt/arrow-any-ctc doms) + (define all-anys? (for/and ([d (in-list doms)]) + (syntax-case d (any/c) + [any/c #t] + [anything-else #f]))) (let*-values ([(dom-vars) (generate-temporaries doms)] [(next-doms lifts-doms superlifts-doms partials-doms stronger-ribs-dom dom-chaperone? names) (let loop ([vars dom-vars] @@ -662,14 +667,20 @@ ((dom-arg ...) dom-vars) ((next-dom ...) next-doms) (dom-len (length dom-vars))) - (syntax (begin - (check-procedure val #f dom-len 0 '() '() #|keywords|# blame #f) - (chaperone-procedure - val - (case-lambda - [(dom-arg ...) (values next-dom ...)] - [args - (bad-number-of-arguments blame val args dom-len)]))))) + (define do-chap-stx + #'(begin + (check-procedure val #f dom-len 0 '() '() #|keywords|# blame #f) + (chaperone-procedure + val + (case-lambda + [(dom-arg ...) (values next-dom ...)] + [args + (bad-number-of-arguments blame val args dom-len)])))) + (if all-anys? + #`(if (procedure-arity-exactly/no-kwds val #,(length doms)) + val + #,do-chap-stx) + do-chap-stx)) lifts-doms superlifts-doms partials-doms @@ -682,25 +693,6 @@ 'any)))) (syntax-case* stx (-> values any any/c boolean?) module-or-top-identifier=? - [(_ any/c ... any) - (with-syntax ([n (- (length (syntax->list stx)) 2)]) - (build-optres - #:exp - (with-syntax ((val (opt/info-val opt/info)) - (ctc (opt/info-contract opt/info)) - (blame (opt/info-blame opt/info))) - (syntax (if (and (procedure? val) - (procedure-arity-includes? val n)) - val - (raise-flat-arrow-err blame val n)))) - #:lifts null - #:superlifts null - #:partials null - #:flat #'(and (procedure? val) (procedure-arity-includes? val n)) - #:opt #f - #:stronger-ribs null - #:chaperone #t - #:name #`'(-> #,@(build-list (syntax-e #'n) (λ (x) 'any/c)) any)))] [(_ any/c boolean?) (predicate/c-optres opt/info #f)] [(_ dom ... (values rng ...)) From 1c431e6f4d79e3b54265f5d1c1ca5a7ceae880fa Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 3 Jan 2016 15:15:11 -0600 Subject: [PATCH 306/369] Clean up chaperone-hash-set and impersonate-hash-set and adjust set/c to match Made the hash-set chaperones essentially forward the hash chaperone operations, but now explain them all in terms of set-based operations in the docs. Also adjusted value-blame and has-blame? to support late-neg projections --- .../scribblings/reference/contracts.scrbl | 13 +- .../scribblings/reference/sets.scrbl | 93 +++--- pkgs/racket-test-core/tests/racket/set.rktl | 310 +++++++++++------- .../racket-test/tests/racket/contract/set.rkt | 75 ++++- .../tests/racket/contract/test-util.rkt | 4 +- .../tests/racket/contract/value-contract.rkt | 47 ++- .../collects/racket/contract/private/guts.rkt | 14 +- racket/collects/racket/private/set-types.rkt | 257 +++++++-------- racket/collects/racket/set.rkt | 72 ++-- 9 files changed, 551 insertions(+), 334 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index ca946bb3e9..b21ab2794c 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -2384,10 +2384,17 @@ is expected to be the contract on the value). @defthing[impersonator-prop:blame impersonator-property?] )]{ These properties attach a blame information to the protected structure, -chaperone, or impersonator value. The function @racket[blame-contract?] +chaperone, or impersonator value. The function @racket[has-blame?] returns @racket[#t] for values that have one of these properties, and -@racket[blame-contract] extracts the value from the property (which -is expected to be the blame record for the contract on the value). +@racket[value-blame] extracts the value from the property. + +The value is expected to be the blame record for the contract on the value or +a @racket[cons]-pair of a blame record with a missing party and the missing +party. The @racket[value-blame] function reassembles the arguments of the pair +into a complete blame record using @racket[blame-add-missing-party]. If +the value has one of the properties, but the value is not a blame object +or a pair whose @racket[car] position is a blame object, then @racket[has-blame?] +returns @racket[#f] but @racket[value-blame] returns @racket[#f]. } @deftogether[( diff --git a/pkgs/racket-doc/scribblings/reference/sets.scrbl b/pkgs/racket-doc/scribblings/reference/sets.scrbl index ff5523751f..63d0b1aff3 100644 --- a/pkgs/racket-doc/scribblings/reference/sets.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sets.scrbl @@ -206,7 +206,8 @@ named by the @racket[sym]s. 'immutable] [#:lazy? lazy? any/c (not (and (equal? kind 'immutable) - (flat-contract? elem/c)))]) + (flat-contract? elem/c)))] + [#:equal-key/c equal-key/c contract? any/c]) contract?]{ Constructs a contract that recognizes sets whose elements match @@ -243,9 +244,13 @@ named by the @racket[sym]s. @racket['mutable], @racket['weak], or @racket['mutable-or-weak]) and @racket[lazy?] is @racket[#f], then the elements are checked both immediately and when they are accessed from the set. + + The @racket[equal-key/c] contract is used when values are passed to the comparison + and hashing functions used internally. - The result contract will be a @tech{flat contract} when @racket[elem/c] is a @tech{flat - contract}, @racket[lazy?] is @racket[#f], and @racket[kind] is @racket['immutable]. + The result contract will be a @tech{flat contract} when @racket[elem/c] + and @racket[equal-key/c] are both @tech{flat contracts}, + @racket[lazy?] is @racket[#f], and @racket[kind] is @racket['immutable]. The result will be a @tech{chaperone contract} when @racket[elem/c] is a @tech{chaperone contract}. } @@ -716,59 +721,73 @@ Supported for any @racket[st] that @supp{supports} @racket[set->stream]. } -@defproc[(impersonate-hash-set [st mutable-set?] - [ref-proc (or/c #f (-> set? any/c any/c))] +@defproc[(impersonate-hash-set [st (or/c mutable-set? weak-set?)] + [inject-proc (or/c #f (-> set? any/c any/c))] [add-proc (or/c #f (-> set? any/c any/c))] - [remove-proc (or/c #f (-> set? any/c any/c))] + [shrink-proc (or/c #f (-> set? any/c any/c))] + [extract-proc (or/c #f (-> set? any/c any/c))] [clear-proc (or/c #f (-> set? any)) #f] + [equal-key-proc (or/c #f (-> set? any/c any/c)) #f] [prop impersonator-property?] [prop-val any/c] ... ...) - (and/c set? impersonator?)]{ - Impersonates @racket[st], redirecting via the given procedures. + (and/c (or/c mutable-set? weak-set?) impersonator?)]{ + Impersonates @racket[st], redirecting various set operations via the given procedures. - The @racket[ref-proc] procedure - is called whenever an element is extracted from @racket[st]. Its first argument - is the set and its second argument is the element being extracted. The - result of @racket[ref-proc] is used in place of the extracted argument. + The @racket[inject-proc] procedure + is called whenever an element is temporarily put into the set for the purposes + of comparing it with other elements that may already be in the set. For example, + when evaluating @racket[(set-member? s e)], @racket[e] will be passed to the + @racket[inject-proc] before comparing it with other elements of @racket[s]. - The @racket[add-proc] procedure is called whenever an element is added to @racket[st]. - Its first argument is the set and its second argument is the element being - added. The result of the procedure is the one actually added to the set. + The @racket[add-proc] procedure is called when adding an element to a set, e.g., + via @racket[set-add] or @racket[set-add!]. The result of the @racket[add-proc] is + stored in the set. - The @racket[remove-proc] procedure is called whenever an element is removed - from @racket[st]. Its first argument is the set and its second argument is the - element being removed. The result of the procedure is the element that actually - gets removed from the set. - - If any of the @racket[ref-proc], @racket[add-proc], or @racket[remove-proc] arguments - is @racket[#f], then all three must be and there must be at least one property supplied. - In that case, a more efficient chaperone wrapper is created. + The @racket[shrink-proc] procedure is called when building a new set with + one fewer element. For example, when evaluating @racket[(set-remove s e)] + or @racket[(set-remove! s e)], + an element is removed from a set, e.g., + via @racket[set-remove] or @racket[set-remove!]. The result of the @racket[shrink-proc] + is the element actually removed from the set. - If @racket[clear-proc] is not @racket[#f], it must accept @racket[set] as - an argument and is result is ignored. The fact that @racket[clear-proc] - returns (as opposed to raising an exception or otherwise escaping) grants the - capability to remove all elements from @racket[st]. - If @racket[clear-proc] is @racket[#f], then - @racket[set-clear] or @racket[set-clear!] on the impersonated set - is implemented using @racket[custom-set-first], @racket[custom-set-rest] - and @racket[set-remove] or @racket[set-remove!]. + The @racket[extract-proc] procedure is called when an element is pulled out of + a set, e.g., by @racket[set-first]. The result of the @racket[extract-proc] is + the element actually produced by from the set. + The @racket[clear-proc] is called by @racket[set-clear] and @racket[set-clear!] + and if it returns (as opposed to escaping, perhaps via raising an exception), + the clearing operation is permitted. Its result is ignored. If @racket[clear-proc] + is @racket[#f], then clearing is done element by element (via calls into the other + supplied procedures). + + The @racket[equal-key-proc] is called when an element's hash code is needed of when an + element is supplied to the underlying equality in the set. The result of + @racket[equal-key-proc] is used when computing the hash or comparing for equality. + + If any of the @racket[inject-proc], @racket[add-proc], @racket[shrink-proc], or + @racket[extract-proc] arguments are @racket[#f], then they all must be @racket[#f], + the @racket[clear-proc] and @racket[equal-key-proc] must also be @racket[#f], + and there must be at least one property supplied. + Pairs of @racket[prop] and @racket[prop-val] (the number of arguments to @racket[impersonate-hash-set] must be odd) add @tech{impersonator properties} or override impersonator property values of @racket[st]. } -@defproc[(chaperone-hash-set [st (or/c set? mutable-set?)] - [ref-proc (or/c #f (-> set? any/c any/c))] +@defproc[(chaperone-hash-set [st (or/c set? mutable-set? weak-set?)] + [inject-proc (or/c #f (-> set? any/c any/c))] [add-proc (or/c #f (-> set? any/c any/c))] - [remove-proc (or/c #f (-> set? any/c any/c))] + [shrink-proc (or/c #f (-> set? any/c any/c))] + [extract-proc (or/c #f (-> set? any/c any/c))] [clear-proc (or/c #f (-> set? any)) #f] + [equal-key-proc (or/c #f (-> set? any/c any/c)) #f] [prop impersonator-property?] [prop-val any/c] ... ...) - (and/c set? chaperone?)]{ + (and/c (or/c set? mutable-set? weak-set?) chaperone?)]{ Chaperones @racket[st]. Like @racket[impersonate-hash-set] but with - the constraints that the results of the @racket[ref-proc], - @racket[add-proc], and @racket[remove-proc] must be + the constraints that the results of the @racket[inject-proc], + @racket[add-proc], @racket[shrink-proc], @racket[extract-proc], and + @racket[equal-key-proc] must be @racket[chaperone-of?] their second arguments. Also, the input may be an @racket[immutable?] set. } diff --git a/pkgs/racket-test-core/tests/racket/set.rktl b/pkgs/racket-test-core/tests/racket/set.rktl index 084d8fd574..935818eab3 100644 --- a/pkgs/racket-test-core/tests/racket/set.rktl +++ b/pkgs/racket-test-core/tests/racket/set.rktl @@ -561,153 +561,223 @@ (add1 i))) ;; ---------------------------------------- -;; set/c tests +;; chaperone-hash-set tests -(err/rt-test (set/c '(not a contract))) -(err/rt-test (set/c any/c #:cmp 'not-a-comparison)) -(err/rt-test (set/c any/c #:kind 'not-a-kind-of-set)) -(err/rt-test (set/c (-> integer? string?) #:cmp 'eq)) -(err/rt-test (set/c (-> integer? string?) #:cmp 'eqv)) +(let () + + ;; adds a tracing chaperone to 's', runs 'go' on it, and returns the trace + (define (counting-chaperone s go equal-key?) + (define trace '()) + (define (add-to-trace ele) (set! trace (cons ele trace))) + (define (count name) + (procedure-rename + (λ (s ele) (add-to-trace (list name ele)) ele) + name)) + (go + (chaperone-hash-set + s + (count 'inject) + (count 'add) + (count 'shrink) + (count 'extract) + (λ (s) (add-to-trace 'clear)) + (if equal-key? (count 'equal-key) (λ (s ele) ele)))) + (reverse trace)) + + (test '((extract 1)) + counting-chaperone + (set 1) + (λ (s) (set-first s)) + #f) + (test '((add 1)) + counting-chaperone + (set) + (λ (s) (set-add s 1)) + #f) + (test '((extract 1)) + counting-chaperone + (mutable-set 1) + (λ (s) (set-first s)) + #f) + (test '((extract 1)) + counting-chaperone + (weak-set 1) + (λ (s) (set-first s)) + #f) + (test '((add 2)) + counting-chaperone + (mutable-set 1) + (λ (s) (set-add! s 2)) + #f) + (test '((inject 2)) + counting-chaperone + (mutable-set 1) + (λ (s) (set-member? s 2)) + #f) + (test '((inject 1)) + counting-chaperone + (mutable-set 1) + (λ (s) (set-member? s 1)) + #f) + (test '((shrink 1)) + counting-chaperone + (set 1) + (λ (s) (set-remove s 1)) + #f) + (test '((shrink 1)) + counting-chaperone + (mutable-set 1) + (λ (s) (set-remove! s 1)) + #f) + (test '((inject 2) (equal-key 2) (equal-key 2)) + counting-chaperone + (set 2) + (λ (s) (set-member? s 2)) + #t) + (test '((extract 0)) + counting-chaperone + (let () + (define-custom-set-types set2 equal? equal-hash-code) + (define ele #f) + (set-add (make-immutable-set2) 0)) + (λ (s) (set-first s)) + #f) + (test '((extract 0)) + counting-chaperone + (let () + (define-custom-set-types set2 equal? equal-hash-code) + (define s (make-weak-set2)) + (set-add! s 0) + s) + (λ (s) (set-first s)) + #f) + (test '((add 0) (remove 0)) + counting-chaperone + (let () + (define-custom-set-types set2 equal? equal-hash-code) + (make-immutable-set2)) + (λ (s) + (set-first (set-add s 0))) + #f) + (test '((extract 1)) + counting-chaperone + (let () + (define-custom-set-types set2 equal? equal-hash-code) + (define ele #f) + (set-add (make-immutable-set2) 1)) + (λ (s) (set-first s)) + #f) + (test '((add 1)) + counting-chaperone + (let () + (define-custom-set-types set2 equal? equal-hash-code) + (define ele #f) + (make-immutable-set2)) + (λ (s) (set-add s 1)) + #f) + (test '((remove 1)) + counting-chaperone + (let () + (define-custom-set-types set2 equal? equal-hash-code) + (define s (make-mutable-set2)) + (set-add! s 1) + s) + (λ (s) (set-first s)) + #f) + (test '((remove 1)) + counting-chaperone + (let () + (define-custom-set-types set2 equal? equal-hash-code) + (define s (make-weak-set2)) + (set-add! s 1) + s) + (λ (s) (set-first s)) + #f) + (test '((add 2)) + counting-chaperone + (let () + (define-custom-set-types set2 equal? equal-hash-code) + (define s (make-mutable-set2)) + (set-add! s 1) + s) + (λ (s) (set-add! s 2)) + #f) + (test '((inject 2)) + counting-chaperone + (let () + (define-custom-set-types set2 equal? equal-hash-code) + (define s (make-mutable-set2)) + (set-add! s 1) + s) + (λ (s) (set-member? s 2)) + #f) + (test '((inject 1)) + counting-chaperone + (let () + (define-custom-set-types set2 equal? equal-hash-code) + (define s (make-mutable-set2)) + (set-add! s 1) + s) + (λ (s) (set-member? s 1)) + #f) + (test '((shrink 1)) + counting-chaperone + (let () + (define-custom-set-types set2 equal? equal-hash-code) + (define ele #f) + (set-add (make-immutable-set2) 1)) + (λ (s) (set-remove s 1)) + #f) + (test '((inject 2) (equal-key 2) (equal-key 2)) + counting-chaperone + (let () + (define-custom-set-types set2 equal? equal-hash-code) + (define ele #f) + (set-add (make-immutable-set2) 2)) + (λ (s) (set-member? s 2)) + #t)) -(define (app-ctc ctc value) - (contract ctc value 'positive 'negative)) - -(define (positive-error? exn) - (and exn:fail:contract? - (regexp-match? "blaming: positive" (exn-message exn)))) -(define (negative-error? exn) - (and exn:fail:contract? - (regexp-match? "blaming: negative" (exn-message exn)))) - -(define-syntax-rule (test/blame-pos e) - (thunk-error-test (lambda () e) #'e positive-error?)) -(define-syntax-rule (test/blame-neg e) - (thunk-error-test (lambda () e) #'e negative-error?)) - -;; check dont-care defaults -(test #t set? (app-ctc (set/c any/c) (set))) -(test #t set? (app-ctc (set/c any/c) (seteq))) - -(test/blame-pos (app-ctc (set/c any/c) (mutable-set))) ; check immutable default -(test/blame-pos (app-ctc (set/c any/c #:cmp 'eq) (set))) -(test/blame-pos (app-ctc (set/c any/c #:kind 'mutable) (set))) -(test/blame-pos (app-ctc (set/c string? #:kind 'immutable) (set 1))) -(test/blame-pos (app-ctc (set/c string?) (set 1))) -(test/blame-pos (set-first (app-ctc (set/c string?) (set 1)))) -(test/blame-neg (set-add! (app-ctc (set/c string? #:kind 'mutable) (mutable-set)) 1)) - -(let ([s (set (list 1 2))]) - (test #f eq? - (set-first (chaperone-hash-set s - (λ (s l) (apply list l)) - (λ (s l) l) - (λ (s l) l))) - (set-first s))) -(let ([s (set (list 1 2))]) - (test #t eq? - (set-first (chaperone-hash-set s - (λ (s l) l) - (λ (s l) l) - (λ (s l) l))) - (set-first s))) -(let ([l (list 1 2)]) - (test #f eq? - (set-first (set-add (chaperone-hash-set (set) - (λ (s l) l) - (λ (s l) (apply list l)) - (λ (s l) l)) - l)) - l)) -(let ([l (list 1 2)]) - (test #t eq? - (set-first (set-add (chaperone-hash-set (set) - (λ (s l) l) - (λ (s l) l) - (λ (s l) l)) - l)) - l)) -(test #t even? - (set-first (impersonate-hash-set (mutable-set 1 3 5) - (λ (s e) (+ e 1)) - (λ (s l) l) - (λ (s l) l)))) -(test #t even? - (set-first (impersonate-hash-set (weak-set 1 3 5) - (λ (s e) (+ e 1)) - (λ (s l) l) - (λ (s l) l)))) - -(test #t zero? - (let ([ele #f]) - (set-first (impersonate-hash-set (weak-set 0) - (λ (s e) (set! ele e)) - (λ (s l) l) - (λ (s l) l))) - ele)) -(test #t zero? - (let ([ele #f]) - (define-custom-set-types set2 equal? equal-hash-code) - (define ele #f) - (set-first - (chaperone-hash-set (set-add (make-immutable-set2) 0) - (λ (s e) (set! ele e) e) - (λ (s l) l) - (λ (s l) l))) - ele)) -(test #t zero? - (let ([ele #f]) - (define-custom-set-types set2 equal? equal-hash-code) - (define ele #f) - (define s (make-weak-set2)) - (set-add! s 0) - (set-first - (impersonate-hash-set s - (λ (s e) (set! ele e) e) - (λ (s l) l) - (λ (s l) l))) - ele)) - -(test #t zero? - (let () - (define-custom-set-types set2 equal? equal-hash-code) - (set-first - (set-add (chaperone-hash-set - (make-immutable-set2) - (λ (a b) b) - (λ (a b) b) - (λ (a b) b)) - 0)))) +(let ([s (set 1 2 3)]) + (test #t equal? + (chaperone-hash-set s (λ (x y) y) (λ (x y) y) (λ (x y) y) (λ (x y) y)) + s)) +(let ([s (set 1 2 3)]) + (test #t equal? + s + (chaperone-hash-set s (λ (x y) y) (λ (x y) y) (λ (x y) y) (λ (x y) y)))) (let-values ([(impersonator-prop:p has-impersonator-prop:p? get-impersonator-prop:p) (make-impersonator-property 'p)]) - (let ([s (chaperone-hash-set (set) (λ (s l) l) (λ (s l) l) (λ (s l) l) impersonator-prop:p 11)]) + (let ([s (chaperone-hash-set (set) (λ (s l) l) (λ (s l) l) (λ (s l) l) (λ (s l) l) + impersonator-prop:p 11)]) (test #t has-impersonator-prop:p? s))) (let-values ([(impersonator-prop:p has-impersonator-prop:p? get-impersonator-prop:p) (make-impersonator-property 'p)]) - (let ([s (chaperone-hash-set (set) (λ (s l) l) (λ (s l) l) (λ (s l) l) impersonator-prop:p 11)]) + (let ([s (chaperone-hash-set (set) (λ (s l) l) (λ (s l) l) (λ (s l) l) (λ (s l) l) + impersonator-prop:p 11)]) (test 11 get-impersonator-prop:p s))) (let-values ([(impersonator-prop:p has-impersonator-prop:p? get-impersonator-prop:p) (make-impersonator-property 'p)]) - (let ([s (impersonate-hash-set (weak-set) (λ (s l) l) (λ (s l) l) (λ (s l) l) + (let ([s (impersonate-hash-set (weak-set) (λ (s l) l) (λ (s l) l) (λ (s l) l) (λ (s l) l) impersonator-prop:p 11)]) (test #t has-impersonator-prop:p? s))) (let-values ([(impersonator-prop:p has-impersonator-prop:p? get-impersonator-prop:p) (make-impersonator-property 'p)]) - (let ([s (impersonate-hash-set (mutable-set) (λ (s l) l) (λ (s l) l) (λ (s l) l) + (let ([s (impersonate-hash-set (mutable-set) (λ (s l) l) (λ (s l) l) (λ (s l) l) (λ (s l) l) impersonator-prop:p 11)]) (test 11 get-impersonator-prop:p s))) (let-values ([(impersonator-prop:p has-impersonator-prop:p? get-impersonator-prop:p) (make-impersonator-property 'p)]) - (let ([s (chaperone-hash-set (set) #f #f #f impersonator-prop:p 11)]) + (let ([s (chaperone-hash-set (set) #f #f #f #f impersonator-prop:p 11)]) (test #t has-impersonator-prop:p? s))) (let-values ([(impersonator-prop:p has-impersonator-prop:p? get-impersonator-prop:p) (make-impersonator-property 'p)]) - (let ([s (impersonate-hash-set (mutable-set) #f #f #f impersonator-prop:p 11)]) + (let ([s (impersonate-hash-set (mutable-set) #f #f #f #f impersonator-prop:p 11)]) (test 11 get-impersonator-prop:p s))) (report-errs) diff --git a/pkgs/racket-test/tests/racket/contract/set.rkt b/pkgs/racket-test/tests/racket/contract/set.rkt index 1678137129..31aed187b9 100644 --- a/pkgs/racket-test/tests/racket/contract/set.rkt +++ b/pkgs/racket-test/tests/racket/contract/set.rkt @@ -3,6 +3,59 @@ (parameterize ([current-contract-namespace (make-basic-contract-namespace 'racket/set)]) + + (test/spec-passed/result + 'set/c.0.1 + '(with-handlers ([exn:fail? (λ (x) (regexp-match? #rx"^set/c:" (exn-message x)))]) + (set/c '(not a contract))) + #t) + (test/spec-passed/result + 'set/c.0.2 + '(with-handlers ([exn:fail? (λ (x) (regexp-match? #rx"^set/c:" (exn-message x)))]) + (set/c any/c #:cmp 'not-a-comparison)) + #t) + (test/spec-passed/result + 'set/c.0.3 + '(with-handlers ([exn:fail? (λ (x) (regexp-match? #rx"^set/c:" (exn-message x)))]) + (set/c any/c #:kind 'not-a-kind-of-set)) + #t) + (test/spec-passed/result + 'set/c.0.4 + '(with-handlers ([exn:fail? (λ (x) (regexp-match? #rx"^set/c:" (exn-message x)))]) + (set/c (-> integer? string?) #:cmp 'eq)) + #t) + (test/spec-passed/result + 'set/c.0.5 + '(with-handlers ([exn:fail? (λ (x) (regexp-match? #rx"^set/c:" (exn-message x)))]) + (set/c (-> integer? string?) #:cmp 'eqv)) + #t) + + ;; check dont-care defaults + (test/spec-passed/result + 'set/c.0.6 + '(set? (contract (set/c any/c) (set) 'pos 'neg)) + #t) + (test/spec-passed/result + 'set/c.0.7 + '(set? (contract (set/c any/c) (seteq) 'pos 'neg)) + #t) + + (test/pos-blame 'set/c.0.8 + '(contract (set/c any/c) (mutable-set) 'pos 'neg)) ; check immutable default + (test/pos-blame 'set/c.0.9 + '(contract (set/c any/c #:cmp 'eq) (set) 'pos 'neg)) + (test/pos-blame 'set/c.0.10 + '(contract (set/c any/c #:kind 'mutable) (set) 'pos 'neg)) + (test/pos-blame 'set/c.0.11 + '(contract (set/c string? #:kind 'immutable) (set 1) 'pos 'neg)) + (test/pos-blame 'set/c.0.12 + '(contract (set/c string?) (set 1) 'pos 'neg)) + (test/pos-blame 'set/c.0.13 + '(set-first (contract (set/c string?) (set 1) 'pos 'neg))) + (test/neg-blame 'set/c.0.14 + '(set-add! (contract (set/c string? #:kind 'mutable) (mutable-set) 'pos 'neg) + 1)) + (test/spec-passed/result 'set/c1 @@ -236,7 +289,7 @@ add1))) (test/spec-passed - 'set/c30 + 'set/c31 '(let () (define-custom-set-types set2 equal?) (set-add @@ -244,5 +297,25 @@ (make-immutable-set2) 'pos 'neg) add1))) + + (test/pos-blame + 'set/c32 + '(let () + (define-custom-set-types set2 equal? (λ (p) (p #f) 0)) + (set-add (contract (set/c (-> integer? boolean?) + #:equal-key/c (-> integer? boolean?)) + (make-immutable-set2) + 'pos 'neg) + (λ (x) (zero? (+ x 1)))))) + + (test/spec-passed + 'set/c33 + '(let () + (define-custom-set-types set2 equal? (λ (p) (p 0) 0)) + (set-add (contract (set/c (-> integer? boolean?) + #:equal-key/c (-> integer? boolean?)) + (make-immutable-set2) + 'pos 'neg) + (λ (x) (zero? (+ x 1)))))) ) diff --git a/pkgs/racket-test/tests/racket/contract/test-util.rkt b/pkgs/racket-test/tests/racket/contract/test-util.rkt index 0d789dfa63..12acc74b66 100644 --- a/pkgs/racket-test/tests/racket/contract/test-util.rkt +++ b/pkgs/racket-test/tests/racket/contract/test-util.rkt @@ -163,7 +163,7 @@ name (contract-eval #:test-case-name name `(with-handlers ((exn:fail:syntax? - (lambda (x) (and (regexp-match ,reg (exn-message x)) #t)))) + (lambda (x) (regexp-match? ,reg (exn-message x))))) (eval ',exp))))) ;; test/spec-passed : symbol sexp -> void @@ -281,7 +281,7 @@ (define (good-thing? l) (for/or ([x (in-list l)]) (and (symbol? x) - (regexp-match #rx"contract" (symbol->string x))))) + (regexp-match? #rx"contract" (symbol->string x))))) (cond [(and (pair? body) (eq? (car body) 'require) diff --git a/pkgs/racket-test/tests/racket/contract/value-contract.rkt b/pkgs/racket-test/tests/racket/contract/value-contract.rkt index e69625b28c..12bbec4637 100644 --- a/pkgs/racket-test/tests/racket/contract/value-contract.rkt +++ b/pkgs/racket-test/tests/racket/contract/value-contract.rkt @@ -2,7 +2,8 @@ (require "test-util.rkt") (parameterize ([current-contract-namespace - (make-basic-contract-namespace 'racket/unit 'racket/class 'racket/contract)]) + (make-basic-contract-namespace 'racket/unit 'racket/class + 'racket/contract 'racket/set)]) (ctest #f value-contract #f) (ctest #f value-contract (λ (x) x)) @@ -50,7 +51,7 @@ '(let () (define c (-> integer? integer?)) (define f (contract c (λ (x) x) 'pos 'neg)) - ;; opt/c version doesn't yet have blame, so + ;; opt/c version doesn't yet have blame, so ;; we require only that when there is blame, that the blame is right. (or (and (has-contract? f) (equal? c (value-contract f))) @@ -58,13 +59,49 @@ #t) (test/spec-passed/result - 'value-blame + 'value-blame.1 '(let () (define f (contract (-> integer? integer?) (λ (x) x) 'pos 'neg)) - ;; opt/c version doesn't yet have blame, so + ;; opt/c version doesn't yet have blame, so ;; we require only that when there is blame, that the blame is right. (or (and (has-blame? f) (blame-positive (value-blame f))) 'pos)) - 'pos)) \ No newline at end of file + 'pos) + + (test/spec-passed/result + 'value-blame.2 + '(let () + (define f + (contract (-> integer? integer?) (λ (x) x) 'pos 'neg)) + ;; opt/c version doesn't yet have blame, so + ;; we require only that when there is blame, that the blame is right. + (or (and (has-blame? f) + (blame-negative (value-blame f))) + 'neg)) + 'neg) + + (test/spec-passed/result + 'value-blame.3 + '(let () + (define f + (contract (set/c (-> integer? integer?) #:kind 'mutable) (mutable-set) 'pos 'neg)) + ;; opt/c version doesn't yet have blame, so + ;; we require only that when there is blame, that the blame is right. + (or (and (has-blame? f) + (blame-positive (value-blame f))) + 'pos)) + 'pos) + + (test/spec-passed/result + 'value-blame.4 + '(let () + (define f + (contract (set/c (-> integer? integer?) #:kind 'mutable) (mutable-set) 'pos 'neg)) + ;; opt/c version doesn't yet have blame, so + ;; we require only that when there is blame, that the blame is right. + (or (and (has-blame? f) + (blame-negative (value-blame f))) + 'neg)) + 'neg)) diff --git a/racket/collects/racket/contract/private/guts.rkt b/racket/collects/racket/contract/private/guts.rkt index a73ca22453..d166a9d838 100644 --- a/racket/collects/racket/contract/private/guts.rkt +++ b/racket/collects/racket/contract/private/guts.rkt @@ -139,11 +139,17 @@ (has-impersonator-prop:blame? v))) (define (value-blame v) + (define bv + (cond + [(has-prop:blame? v) + (get-prop:blame v)] + [(has-impersonator-prop:blame? v) + (get-impersonator-prop:blame v)] + [else #f])) (cond - [(has-prop:blame? v) - (get-prop:blame v)] - [(has-impersonator-prop:blame? v) - (get-impersonator-prop:blame v)] + [(and (pair? bv) (blame? (car bv))) + (blame-add-missing-party (car bv) (cdr bv))] + [(blame? bv) bv] [else #f])) (define-values (prop:contracted has-prop:contracted? get-prop:contracted) diff --git a/racket/collects/racket/private/set-types.rkt b/racket/collects/racket/private/set-types.rkt index 942c877440..cce77ae187 100644 --- a/racket/collects/racket/private/set-types.rkt +++ b/racket/collects/racket/private/set-types.rkt @@ -338,19 +338,9 @@ [(hash-weak? table) (weak-custom-set (custom-set-spec s) table)] [else (mutable-custom-set (custom-set-spec s) table)])) -(define (chaperone-hash-set s - ref-proc - add-proc - remove-proc - . - clear-proc+props) - (define-values (clear-proc prop-args) - (check-chap/imp-args #f - s - ref-proc - add-proc - remove-proc - clear-proc+props)) +(define (chaperone-hash-set s inject-proc add-proc shrink-proc extract-proc . clear-proc+props) + (define-values (clear-proc equal-key-proc prop-args) + (check-chap/imp-args #f s inject-proc add-proc shrink-proc extract-proc clear-proc+props)) (define (check-it who original new) (unless (chaperone-of? new original) (error 'chaperone-hash-set @@ -358,105 +348,62 @@ who original new)) new) - (define (chaperone-hash-set-hash-ref-proc hash key) - (values (check-it 'ref-proc key (ref-proc (update-custom-set-table s hash) key)) - (λ (hash key val) val))) - (define (chaperone-hash-set-hash-set-proc hash key val) - (values (check-it 'add-proc key (add-proc (update-custom-set-table s hash) key)) - val)) - (define (chaperone-hash-set-hash-remove-proc hash key) - (check-it 'remove-proc key (remove-proc (update-custom-set-table s hash) key))) - (define (chaperone-hash-set-hash-key-proc hash key) - (check-it 'ref-proc key (ref-proc (update-custom-set-table s hash) key))) - (define chaperone-hash-set-hash-clear-proc - (and clear-proc (λ (hash) (clear-proc (update-custom-set-table s hash))))) (add-impersonator-properties - (if ref-proc + (if inject-proc (chap-or-imp-hash-set s chaperone-hash - chaperone-hash-set-hash-ref-proc - chaperone-hash-set-hash-set-proc - chaperone-hash-set-hash-remove-proc - chaperone-hash-set-hash-key-proc - chaperone-hash-set-hash-clear-proc) + (λ (ele) (check-it 'in-proc ele (inject-proc s ele))) + (λ (ele) (check-it 'add-proc ele (add-proc s ele))) + (λ (ele) (check-it 'shrink-proc ele (shrink-proc s ele))) + (λ (ele) (check-it 'extract-proc ele (extract-proc s ele))) + (and clear-proc (λ () (clear-proc s))) + (λ (ele) (equal-key-proc s ele))) s) prop-args)) -(define (chap-or-imp-hash-set s - chaperone-or-impersonate-hash - c/i-hash-set-hash-ref-proc - c/i-hash-set-hash-set-proc - c/i-hash-set-hash-remove-proc - c/i-hash-set-hash-key-proc - c/i-hash-set-hash-clear-proc) - (define rewrap - (and (custom-set-spec s) - (custom-spec-wrap (custom-set-spec s)))) - (update-custom-set-table - s - (if (custom-set-spec s) - (chaperone-or-impersonate-hash - (custom-set-table s) - (λ (hash key) - (define-values (a b) - (c/i-hash-set-hash-ref-proc hash (custom-elem-contents key))) - (values (rewrap a) b)) - (λ (hash key val) - (define-values (a b) - (c/i-hash-set-hash-set-proc hash (custom-elem-contents key) val)) - (values (rewrap a) b)) - (λ (hash key) - (rewrap (c/i-hash-set-hash-remove-proc hash (custom-elem-contents key)))) - (λ (hash key) - (rewrap (c/i-hash-set-hash-key-proc hash (custom-elem-contents key)))) - c/i-hash-set-hash-clear-proc) - (chaperone-or-impersonate-hash - (custom-set-table s) - c/i-hash-set-hash-ref-proc - c/i-hash-set-hash-set-proc - c/i-hash-set-hash-remove-proc - c/i-hash-set-hash-key-proc - c/i-hash-set-hash-clear-proc)))) - -(define (impersonate-hash-set s - ref-proc - add-proc - remove-proc - . - clear-proc+props) - (define-values (clear-proc prop-args) - (check-chap/imp-args #t - s - ref-proc - add-proc - remove-proc - clear-proc+props)) - (define impersonate-hash-set-hash-ref-proc - (λ (hash key) (values (ref-proc (update-custom-set-table s hash) key) - (λ (hash key val) val)))) - (define impersonate-hash-set-hash-set-proc - (λ (hash key val) (values (add-proc (update-custom-set-table s hash) key) val))) - (define impersonate-hash-set-hash-remove-proc - (λ (hash key) (remove-proc (update-custom-set-table s hash) key))) - (define impersonate-hash-set-hash-key-proc - (λ (hash key) (ref-proc (update-custom-set-table s hash) key))) - (define impersonate-hash-set-hash-clear-proc - (and clear-proc (λ (hash) (clear-proc (update-custom-set-table s hash))))) - (define rewrap - (and (custom-set-spec s) - (custom-spec-wrap (custom-set-spec s)))) +(define (impersonate-hash-set s inject-proc add-proc shrink-proc extract-proc . clear-proc+props) + (define-values (clear-proc equal-key-proc prop-args) + (check-chap/imp-args #t s inject-proc add-proc shrink-proc extract-proc clear-proc+props)) (add-impersonator-properties - (if ref-proc + (if inject-proc (chap-or-imp-hash-set s impersonate-hash - impersonate-hash-set-hash-ref-proc - impersonate-hash-set-hash-set-proc - impersonate-hash-set-hash-remove-proc - impersonate-hash-set-hash-key-proc - impersonate-hash-set-hash-clear-proc) + (λ (ele) (inject-proc s ele)) + (λ (ele) (add-proc s ele)) + (λ (ele) (shrink-proc s ele)) + (λ (ele) (extract-proc s ele)) + (and clear-proc (λ () (clear-proc s))) + (λ (ele) (equal-key-proc s ele))) s) prop-args)) +(define (chap-or-imp-hash-set s c-or-i-hash + inject-proc add-proc shrink-proc extract-proc + clear-proc equal-key-proc) + (update-custom-set-table + s + (cond + [(custom-set-spec s) + (define rewrap (custom-spec-wrap (custom-set-spec s))) + (c-or-i-hash + (custom-set-table s) + (λ (hash key) (values (rewrap (inject-proc (custom-elem-contents key))) + (λ (hash key val) val))) + (λ (hash key val) (values (rewrap (add-proc (custom-elem-contents key))) val)) + (λ (hash key) (rewrap (shrink-proc (custom-elem-contents key)))) + (λ (hash key) (rewrap (extract-proc (custom-elem-contents key)))) + (λ (hash) (clear-proc)) + (λ (hash key) (rewrap (equal-key-proc (custom-elem-contents key)))))] + [else + (c-or-i-hash + (custom-set-table s) + (λ (hash key) (values (inject-proc key) (λ (hash key val) val))) + (λ (hash key val) (values (add-proc key) val)) + (λ (hash key) (shrink-proc key)) + (λ (hash key) (extract-proc key)) + (λ (hash) (clear-proc)) + (λ (hash key) (equal-key-proc key)))]))) + (define (add-impersonator-properties without-props prop-args) (cond [(null? prop-args) without-props] @@ -467,12 +414,9 @@ [else (apply chaperone-struct without-props struct:mutable-custom-set prop-args)])) -(define (check-chap/imp-args impersonate? - s - ref-proc - add-proc - remove-proc - clear-proc+props) +(define (check-chap/imp-args impersonate? s + inject-proc add-proc shrink-proc extract-proc + clear-proc+equal-key-proc+props) (define who (if impersonate? 'impersonate-hash-set 'chaperone-hash-set)) (unless (if impersonate? (or (set-mutable? s) (set-weak? s)) @@ -483,55 +427,69 @@ (if impersonate? '(or/c set-mutable? set-weak?) '(or/c set? set-mutable? set-weak?))) - 0 s ref-proc add-proc clear-proc+props)) - (unless (or (not ref-proc) - (and (procedure? ref-proc) - (procedure-arity-includes? ref-proc 2))) + 0 s inject-proc add-proc shrink-proc extract-proc clear-proc+equal-key-proc+props)) + (unless (or (not inject-proc) + (and (procedure? inject-proc) + (procedure-arity-includes? inject-proc 2))) (apply raise-argument-error who "(or/c #f (procedure-arity-includes/c 2))" - 1 s ref-proc add-proc clear-proc+props)) + 1 s inject-proc add-proc shrink-proc extract-proc clear-proc+equal-key-proc+props)) (unless (or (not add-proc) (and (procedure? add-proc) (procedure-arity-includes? add-proc 2))) (apply raise-argument-error who "(or/c #f (procedure-arity-includes/c 2))" - 2 s ref-proc add-proc clear-proc+props)) - (unless (or (not remove-proc) - (and (procedure? remove-proc) - (procedure-arity-includes? remove-proc 2))) + 2 s inject-proc add-proc shrink-proc extract-proc clear-proc+equal-key-proc+props)) + (unless (or (not shrink-proc) + (and (procedure? shrink-proc) + (procedure-arity-includes? shrink-proc 2))) (apply raise-argument-error who "(or/c #f (procedure-arity-includes/c 2))" - 3 s ref-proc add-proc clear-proc+props)) - (when (or (not ref-proc) (not add-proc) (not remove-proc)) - (unless (and (not ref-proc) (not add-proc) (not remove-proc)) - (raise-arguments-error who - "if one of ref-proc, add-proc, or remove-proc is #f, they must all be" - "ref-proc" ref-proc - "add-proc" add-proc - "remove-proc" remove-proc))) - (unless (null? clear-proc+props) - (unless (or (not (car clear-proc+props)) - (and (procedure? (car clear-proc+props)) - (procedure-arity-includes? (car clear-proc+props) 1)) - (impersonator-property? (car clear-proc+props))) + 3 s inject-proc add-proc shrink-proc extract-proc clear-proc+equal-key-proc+props)) + (unless (or (not extract-proc) + (and (procedure? extract-proc) + (procedure-arity-includes? extract-proc 2))) + (apply raise-argument-error + who + "(or/c #f (procedure-arity-includes/c 2))" + 4 s inject-proc add-proc shrink-proc extract-proc clear-proc+equal-key-proc+props)) + (unless (null? clear-proc+equal-key-proc+props) + (unless (or (not (car clear-proc+equal-key-proc+props)) + (and (procedure? (car clear-proc+equal-key-proc+props)) + (procedure-arity-includes? (car clear-proc+equal-key-proc+props) 1)) + (impersonator-property? (car clear-proc+equal-key-proc+props))) (apply raise-argument-error who (format "~s" `(or/c #f (procedure-arity-includes/c 1) impersonator-property?)) - 4 - s ref-proc add-proc clear-proc+props))) - (define-values (supplied-clear-proc? clear-proc args) + 5 + s inject-proc add-proc shrink-proc extract-proc clear-proc+equal-key-proc+props))) + (define-values (num-supplied-procs clear-proc equal-key-proc args) (cond - [(null? clear-proc+props) (values #f #f '())] - [(impersonator-property? (car clear-proc+props)) (values #f #f clear-proc+props)] + [(null? clear-proc+equal-key-proc+props) (values 0 #f #f '())] + [(impersonator-property? (car clear-proc+equal-key-proc+props)) + (values 0 #f #f clear-proc+equal-key-proc+props)] [else - (values #t - (car clear-proc+props) - (cdr clear-proc+props))])) + (define clear-proc (car clear-proc+equal-key-proc+props)) + (define equal-key-proc+props (cdr clear-proc+equal-key-proc+props)) + (cond + [(null? equal-key-proc+props) (values 1 clear-proc #f '())] + [(impersonator-property? (car equal-key-proc+props)) + (values 1 clear-proc #f equal-key-proc+props)] + [else + (values 2 clear-proc (car equal-key-proc+props) (cdr equal-key-proc+props))])])) + (unless (or (not equal-key-proc) + (and (procedure? equal-key-proc) + (procedure-arity-includes? equal-key-proc 2))) + (apply raise-argument-error + who + "(or/c #f (procedure-arity-includes/c 1))" + (+ 4 num-supplied-procs) + s inject-proc add-proc shrink-proc extract-proc clear-proc+equal-key-proc+props)) (for ([ele (in-list args)] [i (in-naturals)] #:when (even? i)) @@ -539,14 +497,31 @@ (apply raise-argument-error who "impersonator-property?" - (+ i (if supplied-clear-proc? 1 0) 4) - s ref-proc add-proc clear-proc+props))) - (unless ref-proc + (+ i num-supplied-procs 4) + s inject-proc add-proc shrink-proc extract-proc clear-proc+equal-key-proc+props))) + (when (or (not inject-proc) (not add-proc) (not shrink-proc) (not extract-proc)) + (unless (and (not inject-proc) (not add-proc) (not shrink-proc) (not extract-proc) + (not equal-key-proc) (not clear-proc)) + (raise-arguments-error who + (string-append + "if one of inject-proc, add-proc, shrink-proc" + " or extract-proc is #f, they must all be and the" + " equal-key-proc and clear-proc must also be") + "inject-proc" inject-proc + "add-proc" add-proc + "shrink-proc" shrink-proc + "extract-proc" extract-proc + "equal-key-proc" equal-key-proc + "clear-proc" clear-proc))) + (unless inject-proc (when (null? args) (raise-arguments-error who - "when ref-proc, add-proc, and remove-proc are #f, at least one property must be supplied"))) - (values clear-proc args)) + "when inject-proc, add-proc, shrink-proc, and extract-proc are #f," + " at least one property must be supplied"))) + (values clear-proc + (or equal-key-proc (λ (s e) e)) + args)) (define (set-check-compatible name s1 s2) (define spec (custom-set-spec s1)) diff --git a/racket/collects/racket/set.rkt b/racket/collects/racket/set.rkt index 301cfe134c..d58ab523a1 100644 --- a/racket/collects/racket/set.rkt +++ b/racket/collects/racket/set.rkt @@ -50,10 +50,13 @@ set/c) (define/subexpression-pos-prop/name - real-set/c-name (set/c elem/c + real-set/c-name (set/c _elem/c + #:equal-key/c [_equal-key/c any/c] #:cmp [cmp 'dont-care] #:kind [kind 'immutable] - #:lazy? [_lazy? (lazy-default kind elem/c)]) + #:lazy? [_lazy? (lazy-default kind _elem/c)]) + (define elem/c (coerce-contract 'set/c _elem/c)) + (define equal-key/c (coerce-contract 'set/c _equal-key/c)) (define lazy? (and _lazy? #t)) (define cmp/c (case cmp @@ -80,7 +83,7 @@ (raise-arguments-error 'set/c "element contract must be a flat contract for eqv? and eq?-based sets" - "element contract" (contract-name elem/c) + "element contract" elem/c "#:cmp option" cmp))] [else (unless (chaperone-contract? elem/c) @@ -88,14 +91,15 @@ (cond [(and (eq? kind 'immutable) (not lazy?) - (flat-contract? elem/c)) - (flat-set-contract elem/c cmp kind lazy?)] + (flat-contract? elem/c) + (flat-contract? equal-key/c)) + (flat-set-contract elem/c equal-key/c cmp kind lazy?)] [(chaperone-contract? elem/c) - (chaperone-set-contract elem/c cmp kind lazy?)] + (chaperone-set-contract elem/c equal-key/c cmp kind lazy?)] [else - (impersonator-set-contract elem/c cmp kind lazy?)])) + (impersonator-set-contract elem/c equal-key/c cmp kind lazy?)])) -(struct set-contract [elem/c cmp kind lazy?]) +(struct set-contract [elem/c equal-key/c cmp kind lazy?]) (define (lazy-default kind elem/c) (not (and (equal? kind 'immutable) @@ -177,25 +181,45 @@ (define (hash-set-late-neg-projection ctc chaperone-ctc?) (define elem/c (set-contract-elem/c ctc)) + (define equal-key/c (set-contract-equal-key/c ctc)) (define cmp (set-contract-cmp ctc)) (define kind (set-contract-kind ctc)) (define late-neg-ele-proj (contract-late-neg-projection elem/c)) + (define late-neg-equal-key-proj (contract-late-neg-projection equal-key/c)) (define lazy? (set-contract-lazy? ctc)) (λ (blame) + (define ele-neg-blame (blame-add-element-context blame #t)) (define late-neg-pos-proj (late-neg-ele-proj (blame-add-element-context blame #f))) - (define late-neg-neg-proj (late-neg-ele-proj (blame-add-element-context blame #t))) + (define late-neg-neg-proj (late-neg-ele-proj ele-neg-blame)) + (define late-neg-equal-key-pos-proj (late-neg-equal-key-proj ele-neg-blame)) (cond [lazy? (λ (val neg-party) - (set-contract-check cmp kind blame neg-party val) - (define (pos-interpose val ele) (late-neg-pos-proj ele neg-party)) - (chaperone-hash-set - val - pos-interpose - (λ (val ele) (late-neg-neg-proj ele neg-party)) - pos-interpose - impersonator-prop:contracted ctc - impersonator-prop:blame (cons blame neg-party)))] + (set-contract-check cmp kind blame neg-party val) + (define (pos-interpose val ele) (late-neg-pos-proj ele neg-party)) + (cond + [(set? val) + (chaperone-hash-set + val + (λ (val ele) ele) + (λ (val ele) ele) + (λ (val ele) ele) + (λ (val ele) (late-neg-pos-proj ele neg-party)) + (λ (val) (void)) + (λ (val ele) (late-neg-equal-key-pos-proj ele neg-party)) + impersonator-prop:contracted ctc + impersonator-prop:blame (cons blame neg-party))] + [else + (chaperone-hash-set + val + (λ (val ele) ele) + (λ (val ele) (late-neg-neg-proj ele neg-party)) + (λ (val ele) ele) + (λ (val ele) (late-neg-pos-proj ele neg-party)) + (λ (val) (void)) + (λ (val ele) (late-neg-equal-key-pos-proj ele neg-party)) + impersonator-prop:contracted ctc + impersonator-prop:blame (cons blame neg-party))]))] [else (λ (val neg-party) (set-contract-check cmp kind blame neg-party val) @@ -209,15 +233,17 @@ impersonator-prop:contracted ctc impersonator-prop:blame (cons blame neg-party))] [else - (define (pos-interpose val ele) (late-neg-pos-proj ele neg-party)) (for ([ele (in-list (set->list val))]) (set-remove! val ele) (set-add! val (late-neg-pos-proj ele neg-party))) (chaperone-hash-set val - pos-interpose + (λ (val ele) ele) (λ (val ele) (late-neg-neg-proj ele neg-party)) - pos-interpose + (λ (val ele) ele) + (λ (val ele) (late-neg-pos-proj ele neg-party)) + (λ (val) (void)) + (λ (val ele) (late-neg-equal-key-pos-proj ele neg-party)) impersonator-prop:contracted ctc impersonator-prop:blame (cons blame neg-party))]))]))) @@ -313,6 +339,10 @@ (for/and ([e (in-set x)]) (elem-passes? e))))) +;; since the equal-key/c must be a flat contract +;; in order for the entire set/c to be a flat contract, +;; then we know that it doesn't have any negative blame +;; and thus can never fail; so this projection ignores it. (define (flat-set-contract-late-neg-projection ctc) (define elem/c (set-contract-elem/c ctc)) (define cmp (set-contract-cmp ctc)) From 5cf748d734607c3820949daa071c5108ae6d5ee4 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Mon, 4 Jan 2016 11:08:02 -0500 Subject: [PATCH 307/369] Fix set chaperone tests. `set-first` just does an extract, not a remove. --- pkgs/racket-test-core/tests/racket/set.rktl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/set.rktl b/pkgs/racket-test-core/tests/racket/set.rktl index 935818eab3..99013eeaeb 100644 --- a/pkgs/racket-test-core/tests/racket/set.rktl +++ b/pkgs/racket-test-core/tests/racket/set.rktl @@ -651,7 +651,7 @@ s) (λ (s) (set-first s)) #f) - (test '((add 0) (remove 0)) + (test '((add 0) (extract 0)) counting-chaperone (let () (define-custom-set-types set2 equal? equal-hash-code) @@ -675,7 +675,7 @@ (make-immutable-set2)) (λ (s) (set-add s 1)) #f) - (test '((remove 1)) + (test '((extract 1)) counting-chaperone (let () (define-custom-set-types set2 equal? equal-hash-code) @@ -684,7 +684,7 @@ s) (λ (s) (set-first s)) #f) - (test '((remove 1)) + (test '((extract 1)) counting-chaperone (let () (define-custom-set-types set2 equal? equal-hash-code) From d37ee8c5b12c11b7a8e7a8a3951b92918d93f7ad Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 4 Jan 2016 10:59:32 -0700 Subject: [PATCH 308/369] fix `place` and `raco exe` The repair involves making `raco exe` detect a sub-submodule whose name is `declare-preserve-for-embedding` as an indication that a submodule should be carried along with its enclosing module. Normally, `define-runtime-module-path-index` would do that, but the submodule for `place` is created with `syntax-local-lift-module`, and the point of `syntax-local-lift-module` is to work in a nested experssion context where definitions cannot be lifted to the enclosing module. --- pkgs/racket-doc/scribblings/raco/exe.scrbl | 8 ++++- racket/collects/compiler/embed.rkt | 42 ++++++++++++++++------ racket/collects/racket/place.rkt | 19 ++++++---- 3 files changed, 51 insertions(+), 18 deletions(-) diff --git a/pkgs/racket-doc/scribblings/raco/exe.scrbl b/pkgs/racket-doc/scribblings/raco/exe.scrbl index 3e957c98b4..2a276cd540 100644 --- a/pkgs/racket-doc/scribblings/raco/exe.scrbl +++ b/pkgs/racket-doc/scribblings/raco/exe.scrbl @@ -49,7 +49,10 @@ created executable. Such modules can be explicitly included using the @racket[define-runtime-path] to embed references to the run-time files in the executable; the files are then copied and packaged together with the executable when creating a distribution (as described in -@secref["exe-dist"]). +@secref["exe-dist"]). Finally, a submodule is included if its +enclosing module is included and the submodule contains a +sub-submodule named @racketidfont{declare-preserve-for-embedding} +(where the implementation of the sub-submodule is ignored). Modules that are implemented directly by extensions---i.e., extensions that are automatically loaded from @racket[(build-path "compiled" @@ -172,6 +175,9 @@ The @exec{raco exe} command accepts the following command-line flags: ] +@history[#:changed "6.3.0.11" @elem{Added support for + @racketidfont{declare-preserve-for-embedding}.}] + @; ---------------------------------------------------------------------- @include-section["exe-api.scrbl"] diff --git a/racket/collects/compiler/embed.rkt b/racket/collects/compiler/embed.rkt index f95d115feb..00c783b475 100644 --- a/racket/collects/compiler/embed.rkt +++ b/racket/collects/compiler/embed.rkt @@ -571,8 +571,9 @@ (if (or (null? use-submods) use-source?) null - (for/list ([m l] - #:when (member (cadr (module-compiled-name m)) use-submods)) + (for/list ([m (in-list l)] + #:when (or (member (last (module-compiled-name m)) use-submods) + (declares-always-preserved? m))) m)))] [pre-submods (extract-submods (module-compiled-submodules renamed-code #t))] [post-submods (extract-submods (module-compiled-submodules renamed-code #f))] @@ -756,6 +757,12 @@ (apply append (map accum-from-mod (module-compiled-submodules mod #f)))))) +(define (declares-always-preserved? m) + (for/or ([s (in-list + (append (module-compiled-submodules m #t) + (module-compiled-submodules m #f)))]) + (eq? (last (module-compiled-name s)) 'declare-preserve-for-embedding))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define (compile-using-kernel e) @@ -825,7 +832,7 @@ (namespace-module-registry (current-namespace)) (vector mapping-table library-table)) (letrec-values ([(lookup) - (lambda (name rel-to stx load? orig) + (lambda (name rel-to stx load? for-submod? orig) (if (not (module-path? name)) ;; Bad input (orig name rel-to stx load?) @@ -1018,8 +1025,17 @@ (if a3 ;; Have it: (make-resolved-module-path (cdr a3)) - ;; Let default handler try: - (orig name rel-to stx load?)))))))))))] + (if (if for-submod? + (if (pair? name) + (if (eq? (car name) 'quote) + (assq (cadr name) mapping-table) + #f) + #f) + #f) + ;; Report that we have mappings relative to `name`: + (make-resolved-module-path (cadr name)) + ;; Let default handler try: + (orig name rel-to stx load?))))))))))))] [(embedded-resolver) (case-lambda [(name from-namespace) @@ -1055,20 +1071,26 @@ (void)) (orig name from-namespace)] [(name rel-to stx load?) - (lookup name rel-to stx load? + (lookup name rel-to stx load? #f (lambda (name rel-to stx load?) ;; For a submodule, if we have a mapping for the base name, ;; then don't try the original handler. (let-values ([(base) (if (pair? name) (if (eq? (car name) 'submod) - (lookup (cadr name) rel-to stx load? (lambda (n r s l?) #f)) + ;; Pass #t for `for-submod?`, which causes a + ;; resolved module name to be returned for a quoted + ;; module name if we have any relative mappings for it: + (lookup (cadr name) rel-to stx load? #t (lambda (n r s l?) #f)) #f) #f)]) (if base - ;; don't chain to `orig': - (make-resolved-module-path - (list* 'submod (resolved-module-path-name base) (cddr name))) + ;; don't chain to `orig'; try `lookup` again with `(submod "." ...)`, + ;; and if that still fails, just construct a submodule path: + (lookup (cons 'submod (cons "." (cddr name))) base stx load? #f + (lambda (name rel-to stx load?) + (make-resolved-module-path + (cons (resolved-module-path-name base) (cddr name))))) ;; chain to `orig': (orig name rel-to stx load?)))))])]) (current-module-name-resolver embedded-resolver)))))) diff --git a/racket/collects/racket/place.rkt b/racket/collects/racket/place.rkt index 237e71f194..b5886c63b6 100644 --- a/racket/collects/racket/place.rkt +++ b/racket/collects/racket/place.rkt @@ -11,6 +11,7 @@ racket/place/private/prop racket/private/streams racket/match + racket/runtime-path (for-syntax racket/base @@ -186,7 +187,7 @@ (syntax-case stx () [(who ch body1 body ...) (if (eq? (syntax-local-context) 'module-begin) - ;; when a `place' form is the only thing in a module mody: + ;; when a `place' form is the only thing in a module body: #`(begin #,stx) ;; normal case: (let () @@ -200,10 +201,14 @@ (string->symbol (format "place-body-~a" place-body-counter)))) (with-syntax ([internal-def-name - (syntax-local-lift-module #`(module* #,module-name-stx #f - (provide main) - (define (main ch) - body1 body ...)))] + (syntax-local-lift-module + #`(module* #,module-name-stx #f + (provide main) + (define (main ch) + body1 body ...) + ;; The existence of this submodule makes the + ;; enclosing submodule preserved by `raco exe`: + (module declare-preserve-for-embedding '#%kernel)))] [in _in] [out _out] [err _err] @@ -236,9 +241,9 @@ (error who "the enclosing module's resolved name is not a path or predefined")) (define submod-ref (match name - [(? symbol?) `(quote 'name)] + [(? symbol?) `(submod (quote ,name) ,submod-name)] [(? path?) `(submod ,name ,submod-name)] - [`(,p ,s ...) `(submod ,p ,@s ,submod-name)])) + [`(,p ,s ...) `(submod ,(if (symbol? p) `(quote ,p) p) ,@s ,submod-name)])) (start-place-func who submod-ref 'main in out err)) (define-syntax (place/context stx) From 14b951cf446f4b5b3eb2558ba8d4085701929309 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 4 Jan 2016 17:16:58 -0600 Subject: [PATCH 309/369] improve the performance of the way contract-stronger? recurs and fix evt/c's contract-stronger --- .../tests/racket/contract/stronger.rkt | 3 + .../contract/private/arrow-val-first.rkt | 8 +- .../racket/contract/private/arrow.rkt | 8 +- .../collects/racket/contract/private/box.rkt | 6 +- .../racket/contract/private/case-arrow.rkt | 4 +- .../collects/racket/contract/private/ds.rkt | 6 +- .../collects/racket/contract/private/hash.rkt | 12 +-- .../collects/racket/contract/private/misc.rkt | 77 +++++++++---------- .../collects/racket/contract/private/orc.rkt | 30 +++----- .../racket/contract/private/parametric.rkt | 4 +- .../racket/contract/private/struct-dc.rkt | 6 +- .../racket/contract/private/vector.rkt | 18 ++--- 12 files changed, 85 insertions(+), 97 deletions(-) diff --git a/pkgs/racket-test/tests/racket/contract/stronger.rkt b/pkgs/racket-test/tests/racket/contract/stronger.rkt index dc30bfc608..53069f2bbb 100644 --- a/pkgs/racket-test/tests/racket/contract/stronger.rkt +++ b/pkgs/racket-test/tests/racket/contract/stronger.rkt @@ -444,6 +444,9 @@ (ctest #f contract-stronger? (implementation?/c one-interface<%>) (implementation?/c another-interface<%>)) + + (ctest #t contract-stronger? (evt/c integer?) (evt/c integer?)) + (ctest #f contract-stronger? (evt/c integer?) (evt/c boolean?)) ;; chances are, this predicate will accept "x", but ;; we don't want to consider it stronger, since it diff --git a/racket/collects/racket/contract/private/arrow-val-first.rkt b/racket/collects/racket/contract/private/arrow-val-first.rkt index eeb1adffc5..32497e22c2 100644 --- a/racket/collects/racket/contract/private/arrow-val-first.rkt +++ b/racket/collects/racket/contract/private/arrow-val-first.rkt @@ -1208,18 +1208,18 @@ (= (length (base->-doms that)) (length (base->-doms this))) (= (base->-min-arity this) (base->-min-arity that)) - (andmap contract-stronger? (base->-doms that) (base->-doms this)) + (andmap contract-struct-stronger? (base->-doms that) (base->-doms this)) (= (length (base->-kwd-infos this)) (length (base->-kwd-infos that))) (for/and ([this-kwd-info (base->-kwd-infos this)] [that-kwd-info (base->-kwd-infos that)]) (and (equal? (kwd-info-kwd this-kwd-info) (kwd-info-kwd that-kwd-info)) - (contract-stronger? (kwd-info-ctc that-kwd-info) - (kwd-info-ctc this-kwd-info)))) + (contract-struct-stronger? (kwd-info-ctc that-kwd-info) + (kwd-info-ctc this-kwd-info)))) (if (base->-rngs this) (and (base->-rngs that) - (andmap contract-stronger? (base->-rngs this) (base->-rngs that))) + (andmap contract-struct-stronger? (base->-rngs this) (base->-rngs that))) (not (base->-rngs that))) (not (base->-pre? this)) (not (base->-pre? that)) diff --git a/racket/collects/racket/contract/private/arrow.rkt b/racket/collects/racket/contract/private/arrow.rkt index 72b596f12f..384784b4a1 100644 --- a/racket/collects/racket/contract/private/arrow.rkt +++ b/racket/collects/racket/contract/private/arrow.rkt @@ -662,16 +662,16 @@ (define (->-stronger? this that) (and (base->? that) (= (length (base->-doms/c that)) (length (base->-doms/c this))) - (andmap contract-stronger? (base->-doms/c that) (base->-doms/c this)) + (andmap contract-struct-stronger? (base->-doms/c that) (base->-doms/c this)) (equal? (base->-mandatory-kwds this) (base->-mandatory-kwds that)) - (andmap contract-stronger? (base->-mandatory-kwds/c that) (base->-mandatory-kwds/c this)) + (andmap contract-struct-stronger? (base->-mandatory-kwds/c that) (base->-mandatory-kwds/c this)) (equal? (base->-optional-kwds this) (base->-optional-kwds that)) - (andmap contract-stronger? (base->-optional-kwds/c that) (base->-optional-kwds/c this)) + (andmap contract-struct-stronger? (base->-optional-kwds/c that) (base->-optional-kwds/c this)) (= (length (base->-rngs/c that)) (length (base->-rngs/c this))) - (andmap contract-stronger? (base->-rngs/c this) (base->-rngs/c that)) + (andmap contract-struct-stronger? (base->-rngs/c this) (base->-rngs/c that)) ;; these procs might be based on state; only ;; allow stronger to be true when #:pre and diff --git a/racket/collects/racket/contract/private/box.rkt b/racket/collects/racket/contract/private/box.rkt index 0abccd0365..e88d576cd1 100644 --- a/racket/collects/racket/contract/private/box.rkt +++ b/racket/collects/racket/contract/private/box.rkt @@ -99,11 +99,11 @@ (cond [(and (equal? this-immutable #t) (equal? that-immutable #t)) - (contract-stronger? this-content-r that-content-r)] + (contract-struct-stronger? this-content-r that-content-r)] [(or (equal? that-immutable 'dont-care) (equal? this-immutable that-immutable)) - (and (contract-stronger? this-content-r that-content-r) - (contract-stronger? that-content-w this-content-w))] + (and (contract-struct-stronger? this-content-r that-content-r) + (contract-struct-stronger? that-content-w this-content-w))] [else #f])] [else #f])) diff --git a/racket/collects/racket/contract/private/case-arrow.rkt b/racket/collects/racket/contract/private/case-arrow.rkt index f51e1862ef..b644cf10a9 100644 --- a/racket/collects/racket/contract/private/case-arrow.rkt +++ b/racket/collects/racket/contract/private/case-arrow.rkt @@ -333,6 +333,6 @@ (= (length fst) (length ps)) (for/and ([c (in-list ps)] [fst-c (in-list fst)]) - (and (contract-stronger? c fst-c) - (contract-stronger? fst-c c))))) + (and (contract-struct-stronger? c fst-c) + (contract-struct-stronger? fst-c c))))) fst)])) diff --git a/racket/collects/racket/contract/private/ds.rkt b/racket/collects/racket/contract/private/ds.rkt index 4341ec8bb6..8dc55bf60b 100644 --- a/racket/collects/racket/contract/private/ds.rkt +++ b/racket/collects/racket/contract/private/ds.rkt @@ -235,7 +235,7 @@ it around flattened out. [b-sel (contract-get b selector-indices)]) (if (contract-struct? a-sel) (if (contract-struct? b-sel) - (contract-stronger? a-sel b-sel) + (contract-struct-stronger? a-sel b-sel) #f) (if (contract-struct? b-sel) #f @@ -275,8 +275,8 @@ it around flattened out. (let ([old-contract/info (wrap-get val 1)]) (if (and (equal? (contract/info-blame new-contract/info) (contract/info-blame old-contract/info)) - (contract-stronger? (contract/info-contract old-contract/info) - (contract/info-contract new-contract/info))) + (contract-struct-stronger? (contract/info-contract old-contract/info) + (contract/info-contract new-contract/info))) #t (already-there? new-contract/info (wrap-get val 0) (- depth 1)))))] [else diff --git a/racket/collects/racket/contract/private/hash.rkt b/racket/collects/racket/contract/private/hash.rkt index deaeb3578d..712d735975 100644 --- a/racket/collects/racket/contract/private/hash.rkt +++ b/racket/collects/racket/contract/private/hash.rkt @@ -168,14 +168,14 @@ (cond [(and (equal? this-immutable #t) (equal? that-immutable #t)) - (and (contract-stronger? this-dom that-dom) - (contract-stronger? this-rng that-rng))] + (and (contract-struct-stronger? this-dom that-dom) + (contract-struct-stronger? this-rng that-rng))] [(or (equal? that-immutable 'dont-care) (equal? this-immutable that-immutable)) - (and (contract-stronger? this-dom that-dom) - (contract-stronger? that-dom this-dom) - (contract-stronger? this-rng that-rng) - (contract-stronger? that-rng this-rng))] + (and (contract-struct-stronger? this-dom that-dom) + (contract-struct-stronger? that-dom this-dom) + (contract-struct-stronger? this-rng that-rng) + (contract-struct-stronger? that-rng this-rng))] [else #f])] [else #f])) diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index 7a2dbe399e..ad5d3f2c6c 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -56,7 +56,9 @@ random-any/c rename-contract - if/c) + if/c + + pairwise-stronger-contracts?) (define-syntax (flat-murec-contract stx) (syntax-case stx () @@ -132,12 +134,8 @@ (define (and-stronger? this that) (and (base-and/c? that) - (let ([this-ctcs (base-and/c-ctcs this)] - [that-ctcs (base-and/c-ctcs that)]) - (and (= (length this-ctcs) (length that-ctcs)) - (andmap contract-stronger? - this-ctcs - that-ctcs))))) + (pairwise-stronger-contracts? (base-and/c-ctcs this) + (base-and/c-ctcs that)))) (define (and/c-generate? ctc) (cond @@ -206,21 +204,21 @@ (define (and/c-check-nonneg ctc pred) (define sub-contracts (base-and/c-ctcs ctc)) (cond - [(are-stronger-contracts? (list pred (not/c negative?)) - sub-contracts) + [(pairwise-stronger-contracts? (list pred (not/c negative?)) + sub-contracts) (define go (hash-ref predicate-generator-table pred)) (λ (fuel) (λ () (abs (go fuel))))] [else #f])) -(define (are-stronger-contracts? c1s c2s) +(define (pairwise-stronger-contracts? c1s c2s) (let loop ([c1s c1s] [c2s c2s]) (cond [(and (null? c1s) (null? c2s)) #t] [(and (pair? c1s) (pair? c2s)) - (and (contract-stronger? (car c1s) (car c2s)) + (and (contract-struct-stronger? (car c1s) (car c2s)) (loop (cdr c1s) (cdr c2s)))] [else #f]))) @@ -576,13 +574,13 @@ [(pe-listof-ctc? this) (pe-listof-ctc? that)] [(im-listof-ctc? this) (im-listof-ctc? that)] [else #t]) - (contract-stronger? this-elem that-elem))] + (contract-struct-stronger? this-elem that-elem))] [(the-cons/c? that) (define hd-ctc (the-cons/c-hd-ctc that)) (define tl-ctc (the-cons/c-tl-ctc that)) (and (ne-listof-ctc? this) - (contract-stronger? this-elem hd-ctc) - (contract-stronger? (ne->pe-ctc this) tl-ctc))] + (contract-struct-stronger? this-elem hd-ctc) + (contract-struct-stronger? (ne->pe-ctc this) tl-ctc))] [else #f])) (define (raise-listof-blame-error blame val empty-ok? neg-party) @@ -828,16 +826,16 @@ [(the-cons/c? that) (define that-hd (the-cons/c-hd-ctc that)) (define that-tl (the-cons/c-tl-ctc that)) - (and (contract-stronger? this-hd that-hd) - (contract-stronger? this-tl that-tl))] + (and (contract-struct-stronger? this-hd that-hd) + (contract-struct-stronger? this-tl that-tl))] [(ne-listof-ctc? that) (define elem-ctc (listof-ctc-elem-c that)) - (and (contract-stronger? this-hd elem-ctc) - (contract-stronger? this-tl (ne->pe-ctc that)))] + (and (contract-struct-stronger? this-hd elem-ctc) + (contract-struct-stronger? this-tl (ne->pe-ctc that)))] [(pe-listof-ctc? that) (define elem-ctc (listof-ctc-elem-c that)) - (and (contract-stronger? this-hd elem-ctc) - (contract-stronger? this-tl that))] + (and (contract-struct-stronger? this-hd elem-ctc) + (contract-struct-stronger? this-tl that))] [else #f])) @@ -1109,18 +1107,15 @@ (define (list/c-stronger this that) (cond [(generic-list/c? that) - (and (= (length (generic-list/c-args this)) - (length (generic-list/c-args that))) - (for/and ([this-s (in-list (generic-list/c-args this))] - [that-s (in-list (generic-list/c-args this))]) - (contract-stronger? this-s that-s)))] + (pairwise-stronger-contracts? (generic-list/c-args this) + (generic-list/c-args that))] [(listof-ctc? that) (define that-elem-ctc (listof-ctc-elem-c that)) (define this-elem-ctcs (generic-list/c-args this)) (and (or (pair? this-elem-ctcs) (pe-listof-ctc? that)) (for/and ([this-s (in-list this-elem-ctcs)]) - (contract-stronger? this-s that-elem-ctc)))] + (contract-struct-stronger? this-s that-elem-ctc)))] [else #f])) (struct generic-list/c (args)) @@ -1250,8 +1245,8 @@ #:name (λ (ctc) (build-compound-type-name 'syntax/c (syntax-ctc-ctc ctc))) #:stronger (λ (this that) (and (syntax-ctc? that) - (contract-stronger? (syntax-ctc-ctc this) - (syntax-ctc-ctc that)))) + (contract-struct-stronger? (syntax-ctc-ctc this) + (syntax-ctc-ctc that)))) #:first-order (λ (ctc) (define ? (flat-contract-predicate (syntax-ctc-ctc ctc))) (λ (v) @@ -1299,8 +1294,8 @@ (define (promise-ctc-stronger? this that) (and (promise-base-ctc? that) - (contract-stronger? (promise-base-ctc-ctc this) - (promise-base-ctc-ctc that)))) + (contract-struct-stronger? (promise-base-ctc-ctc this) + (promise-base-ctc-ctc that)))) (struct promise-base-ctc (ctc)) (struct chaperone-promise-ctc promise-base-ctc () @@ -1380,10 +1375,10 @@ #:stronger (λ (this that) (and (parameter/c? that) - (and (contract-stronger? (parameter/c-out this) - (parameter/c-out that)) - (contract-stronger? (parameter/c-in that) - (parameter/c-in this))))))) + (and (contract-struct-stronger? (parameter/c-out this) + (parameter/c-out that)) + (contract-struct-stronger? (parameter/c-in that) + (parameter/c-in this))))))) (define-struct procedure-arity-includes/c (n) #:property prop:custom-write custom-write-property-proc @@ -1558,10 +1553,10 @@ (define (prompt-tag/c-stronger? this that) (and (base-prompt-tag/c? that) - (andmap (λ (this that) (contract-stronger? this that)) + (andmap (λ (this that) (contract-struct-stronger? this that)) (base-prompt-tag/c-ctcs this) (base-prompt-tag/c-ctcs that)) - (andmap (λ (this that) (contract-stronger? this that)) + (andmap (λ (this that) (contract-struct-stronger? this that)) (base-prompt-tag/c-call/ccs this) (base-prompt-tag/c-call/ccs that)))) @@ -1626,7 +1621,7 @@ (define (continuation-mark-key/c-stronger? this that) (and (base-continuation-mark-key/c? that) - (contract-stronger? + (contract-struct-stronger? (base-continuation-mark-key/c-ctc this) (base-continuation-mark-key/c-ctc that)))) @@ -1707,9 +1702,7 @@ (define (evt/c-stronger? this that) (define this-ctcs (chaperone-evt/c-ctcs this)) (define that-ctcs (chaperone-evt/c-ctcs that)) - (and (= (length this-ctcs) (that-ctcs)) - (for/and ([this this-ctcs] [that that-ctcs]) - (contract-stronger? this that)))) + (pairwise-stronger-contracts? this-ctcs that-ctcs)) ;; ctcs - Listof (define-struct chaperone-evt/c (ctcs) @@ -1760,7 +1753,7 @@ (define (channel/c-stronger? this that) (and (base-channel/c? that) - (contract-stronger? + (contract-struct-stronger? (base-channel/c-ctc this) (base-channel/c-ctc that)))) @@ -1869,7 +1862,7 @@ (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)) + (contract-struct-stronger? ctc other)) (make-contract #:name name #:late-neg-projection (get/build-late-neg-projection ctc) #:first-order (contract-first-order ctc) diff --git a/racket/collects/racket/contract/private/orc.rkt b/racket/collects/racket/contract/private/orc.rkt index dcb8bfc566..4077120e65 100644 --- a/racket/collects/racket/contract/private/orc.rkt +++ b/racket/collects/racket/contract/private/orc.rkt @@ -94,14 +94,10 @@ (define (single-or/c-stronger? this that) (or (and (single-or/c? that) - (contract-stronger? (single-or/c-ho-ctc this) - (single-or/c-ho-ctc that)) - (let ([this-ctcs (single-or/c-flat-ctcs this)] - [that-ctcs (single-or/c-flat-ctcs that)]) - (and (= (length this-ctcs) (length that-ctcs)) - (andmap contract-stronger? - this-ctcs - that-ctcs)))) + (contract-struct-stronger? (single-or/c-ho-ctc this) + (single-or/c-ho-ctc that)) + (pairwise-stronger-contracts? (single-or/c-flat-ctcs this) + (single-or/c-flat-ctcs that))) (generic-or/c-stronger? this that))) (define (generic-or/c-stronger? this that) @@ -111,7 +107,7 @@ that-sub-ctcs (for/and ([this-sub-ctc (in-list this-sub-ctcs)]) (for/or ([that-sub-ctc (in-list that-sub-ctcs)]) - (contract-stronger? this-sub-ctc that-sub-ctc))))) + (contract-struct-stronger? this-sub-ctc that-sub-ctc))))) (define (or/c-sub-contracts ctc) (cond @@ -304,14 +300,10 @@ (define (multi-or/c-stronger? this that) (or (and (multi-or/c? that) - (let ([this-ctcs (multi-or/c-ho-ctcs this)] - [that-ctcs (multi-or/c-ho-ctcs that)]) - (and (= (length this-ctcs) (length that-ctcs)) - (andmap contract-stronger? this-ctcs that-ctcs))) - (let ([this-ctcs (multi-or/c-flat-ctcs this)] - [that-ctcs (multi-or/c-flat-ctcs that)]) - (and (= (length this-ctcs) (length that-ctcs)) - (andmap contract-stronger? this-ctcs that-ctcs)))) + (pairwise-stronger-contracts? (multi-or/c-ho-ctcs this) + (multi-or/c-ho-ctcs that)) + (pairwise-stronger-contracts? (multi-or/c-flat-ctcs this) + (multi-or/c-flat-ctcs that))) (generic-or/c-stronger? this that))) (define (mult-or/c-list-contract? c) @@ -373,7 +365,7 @@ [(and (<= (length this-ctcs) (length that-ctcs)) (for/and ([this-ctc (in-list this-ctcs)] [that-ctc (in-list that-ctcs)]) - (contract-stronger? this-ctc that-ctc))) + (contract-struct-stronger? this-ctc that-ctc))) #t] [(and (andmap (λ (x) (or (eq-contract? x) (equal-contract? x))) this-ctcs) (andmap (λ (x) (or (eq-contract? x) (equal-contract? x))) that-ctcs)) @@ -522,7 +514,7 @@ [(equal? this that) #t] [(recur?) (parameterize ([recur? #f]) - (contract-stronger? (get-flat-rec-me this) that))] + (contract-struct-stronger? (get-flat-rec-me this) that))] [else #f]))) #:first-order (λ (ctc) diff --git a/racket/collects/racket/contract/private/parametric.rkt b/racket/collects/racket/contract/private/parametric.rkt index 34ac6bea4f..a0b072a104 100644 --- a/racket/collects/racket/contract/private/parametric.rkt +++ b/racket/collects/racket/contract/private/parametric.rkt @@ -49,8 +49,8 @@ (define instances (for/list ([var (in-list this-vars)]) (this-barrier/c #t var))) - (contract-stronger? (apply (polymorphic-contract-body this) instances) - (apply (polymorphic-contract-body that) instances))] + (contract-struct-stronger? (apply (polymorphic-contract-body this) instances) + (apply (polymorphic-contract-body that) instances))] [else #f])] [else #f])) #:late-neg-projection diff --git a/racket/collects/racket/contract/private/struct-dc.rkt b/racket/collects/racket/contract/private/struct-dc.rkt index 624ba27869..b422a1e69f 100644 --- a/racket/collects/racket/contract/private/struct-dc.rkt +++ b/racket/collects/racket/contract/private/struct-dc.rkt @@ -289,7 +289,7 @@ (λ (v neg-party) (cond [(and (struct/c-imp-prop-pred? v) - (contract-stronger? (struct/c-imp-prop-get v) ctc)) + (contract-struct-stronger? (struct/c-imp-prop-get v) ctc)) v] [else (unless (pred? v) @@ -653,8 +653,8 @@ (immutable? that-subcontract)) (and (lazy-immutable? this-subcontract) (lazy-immutable? that-subcontract))) - (contract-stronger? (indep-ctc this-subcontract) - (indep-ctc that-subcontract)))] + (contract-struct-stronger? (indep-ctc this-subcontract) + (indep-ctc that-subcontract)))] [(and (dep? this-subcontract) (dep? that-subcontract)) (and (or (dep-mutable? this-subcontract) diff --git a/racket/collects/racket/contract/private/vector.rkt b/racket/collects/racket/contract/private/vector.rkt index 648bc3c12e..9cc5eb8442 100644 --- a/racket/collects/racket/contract/private/vector.rkt +++ b/racket/collects/racket/contract/private/vector.rkt @@ -114,12 +114,12 @@ (cond [(and (equal? this-immutable #t) (equal? that-immutable #t)) - (contract-stronger? this-elem that-elem)] + (contract-struct-stronger? this-elem that-elem)] [else (and (or (equal? that-immutable 'dont-care) (equal? this-immutable that-immutable)) - (contract-stronger? this-elem that-elem) - (contract-stronger? that-elem this-elem))])] + (contract-struct-stronger? this-elem that-elem) + (contract-struct-stronger? that-elem this-elem))])] [else #f])) (define-struct (flat-vectorof base-vectorof) () @@ -325,14 +325,14 @@ (and (= (length this-elems) (length that-elems)) (for/and ([this-elem (in-list this-elems)] [that-elem (in-list that-elems)]) - (contract-stronger? this-elem that-elem)))] + (contract-struct-stronger? this-elem that-elem)))] [(or (equal? that-immutable 'dont-care) (equal? this-immutable that-immutable)) (and (= (length this-elems) (length that-elems)) (for/and ([this-elem (in-list this-elems)] [that-elem (in-list that-elems)]) - (and (contract-stronger? this-elem that-elem) - (contract-stronger? that-elem this-elem))))] + (and (contract-struct-stronger? this-elem that-elem) + (contract-struct-stronger? that-elem this-elem))))] [else #f])] [(base-vectorof? that) (define that-elem (base-vectorof-elem that)) @@ -341,12 +341,12 @@ [(and (equal? this-immutable #t) (equal? that-immutable #t)) (for/and ([this-elem (in-list this-elems)]) - (contract-stronger? this-elem that-elem))] + (contract-struct-stronger? this-elem that-elem))] [(or (equal? that-immutable 'dont-care) (equal? this-immutable that-immutable)) (for/and ([this-elem (in-list this-elems)]) - (and (contract-stronger? this-elem that-elem) - (contract-stronger? that-elem this-elem)))] + (and (contract-struct-stronger? this-elem that-elem) + (contract-struct-stronger? that-elem this-elem)))] [else #f])] [else #f])) From 3ed7dfd62bd61a44888e02550899ae8f4bd86b91 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 4 Jan 2016 19:20:25 -0600 Subject: [PATCH 310/369] add the contract printer to set contracts --- racket/collects/racket/set.rkt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/racket/collects/racket/set.rkt b/racket/collects/racket/set.rkt index d58ab523a1..8df5a90110 100644 --- a/racket/collects/racket/set.rkt +++ b/racket/collects/racket/set.rkt @@ -99,7 +99,8 @@ [else (impersonator-set-contract elem/c equal-key/c cmp kind lazy?)])) -(struct set-contract [elem/c equal-key/c cmp kind lazy?]) +(struct set-contract [elem/c equal-key/c cmp kind lazy?] + #:property prop:custom-write contract-custom-write-property-proc) (define (lazy-default kind elem/c) (not (and (equal? kind 'immutable) From 94ac77d30edf53cac29c6a1bbcf610cd93efffca Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 4 Jan 2016 19:22:49 -0600 Subject: [PATCH 311/369] port sequence/c to late-neg projections --- racket/collects/racket/sequence.rkt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/racket/collects/racket/sequence.rkt b/racket/collects/racket/sequence.rkt index 2cc60ed388..65c5ec8d92 100644 --- a/racket/collects/racket/sequence.rkt +++ b/racket/collects/racket/sequence.rkt @@ -182,7 +182,7 @@ (coerce-contract 'sequence/c elem/c))) (define elem/mk-projs (for/list ([ctc (in-list ctcs)]) - (contract-projection ctc))) + (contract-late-neg-projection ctc))) (define n-cs (length elem/cs)) (make-contract #:name (apply build-compound-type-name 'sequence/c @@ -197,15 +197,15 @@ (if (vector? val) (= n-cs 1) #t) (if (list? val) (= n-cs 1) #t) (if (hash? val) (= n-cs 2) #t))) - #:projection + #:late-neg-projection (λ (orig-blame) (define blame (blame-add-context orig-blame "an element of")) (define ps (for/list ([mk-proj (in-list elem/mk-projs)]) (mk-proj blame))) - (λ (seq) + (λ (seq neg-party) (unless (sequence? seq) (raise-blame-error - orig-blame seq + orig-blame #:missing-party neg-party seq '(expected: "a sequence" given: "~e") seq)) (define result-seq @@ -220,14 +220,14 @@ (define n-elems (length elems)) (unless (= n-elems n-cs) (raise-blame-error - blame seq + blame #:missing-party neg-party seq '(expected: "a sequence of ~a values" given: "~a values\n values: ~e") n-cs n-elems elems)) (apply values (for/list ([elem (in-list elems)] [p (in-list ps)]) - (p elem)))))) + (p elem neg-party)))))) add1 0 (lambda (idx) @@ -235,7 +235,7 @@ (when (and min-count (idx . < . min-count)) (unless ans (raise-blame-error - orig-blame + orig-blame #:missing-party neg-party seq '(expected: "a sequence that contains at least ~a values" given: "~e") min-count From 3df12dca585ce10a84c2fe07578fd80c73cfd5dc Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 4 Jan 2016 19:55:01 -0600 Subject: [PATCH 312/369] specialize sequence/c for one-element sequences MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this yields only a modest speed up and only when iterating over long sequences, e.g. like in this program: #lang racket/base (require racket/sequence racket/contract/base) (define s (make-string 10000 #\a)) (define str (contract (any/c . -> . (sequence/c char?)) (λ (x) (in-string s)) 'pos 'neg)) (time (for ([x (in-range 100)]) (for ([x (str 0)]) (void)))) --- racket/collects/racket/sequence.rkt | 126 ++++++++++++++++++---------- 1 file changed, 81 insertions(+), 45 deletions(-) diff --git a/racket/collects/racket/sequence.rkt b/racket/collects/racket/sequence.rkt index 65c5ec8d92..494ade427c 100644 --- a/racket/collects/racket/sequence.rkt +++ b/racket/collects/racket/sequence.rkt @@ -202,51 +202,87 @@ (define blame (blame-add-context orig-blame "an element of")) (define ps (for/list ([mk-proj (in-list elem/mk-projs)]) (mk-proj blame))) - (λ (seq neg-party) - (unless (sequence? seq) - (raise-blame-error - orig-blame #:missing-party neg-party seq - '(expected: "a sequence" given: "~e") - seq)) - (define result-seq - (make-do-sequence - (lambda () - (let*-values ([(more? next) (sequence-generate seq)]) - (values - (lambda (idx) - (call-with-values - next - (lambda elems - (define n-elems (length elems)) - (unless (= n-elems n-cs) - (raise-blame-error - blame #:missing-party neg-party seq - '(expected: "a sequence of ~a values" given: "~a values\n values: ~e") - n-cs n-elems elems)) - (apply - values - (for/list ([elem (in-list elems)] - [p (in-list ps)]) - (p elem neg-party)))))) - add1 - 0 - (lambda (idx) - (define ans (more?)) - (when (and min-count (idx . < . min-count)) - (unless ans - (raise-blame-error - orig-blame #:missing-party neg-party - seq - '(expected: "a sequence that contains at least ~a values" given: "~e") - min-count - seq))) - ans) - (lambda elems #t) - (lambda (idx . elems) #t)))))) - (cond - [(list? seq) (sequence->list result-seq)] - [(stream? seq) (sequence->stream result-seq)] - [else result-seq]))))) + (cond + [(and (= n-cs 1) (not min-count)) + (define p (car ps)) + (λ (seq neg-party) + (unless (sequence? seq) + (raise-blame-error + orig-blame #:missing-party neg-party seq + '(expected: "a sequence" given: "~e") + seq)) + (define result-seq + (make-do-sequence + (lambda () + (let*-values ([(more? next) (sequence-generate seq)]) + (values + (lambda (idx) + (call-with-values + next + (case-lambda + [(elem) + (p elem neg-party)] + [elems + (define n-elems (length elems)) + (raise-blame-error + blame #:missing-party neg-party seq + '(expected: "a sequence of ~a values" given: "~a values\n values: ~e") + n-cs n-elems elems)]))) + add1 + 0 + (lambda (idx) (more?)) + (lambda elems #t) + (lambda (idx . elems) #t)))))) + (cond + [(list? seq) (sequence->list result-seq)] + [(stream? seq) (sequence->stream result-seq)] + [else result-seq]))] + [else + (λ (seq neg-party) + (unless (sequence? seq) + (raise-blame-error + orig-blame #:missing-party neg-party seq + '(expected: "a sequence" given: "~e") + seq)) + (define result-seq + (make-do-sequence + (lambda () + (let*-values ([(more? next) (sequence-generate seq)]) + (values + (lambda (idx) + (call-with-values + next + (lambda elems + (define n-elems (length elems)) + (unless (= n-elems n-cs) + (raise-blame-error + blame #:missing-party neg-party seq + '(expected: "a sequence of ~a values" given: "~a values\n values: ~e") + n-cs n-elems elems)) + (apply + values + (for/list ([elem (in-list elems)] + [p (in-list ps)]) + (p elem neg-party)))))) + add1 + 0 + (lambda (idx) + (define ans (more?)) + (when (and min-count (idx . < . min-count)) + (unless ans + (raise-blame-error + orig-blame #:missing-party neg-party + seq + '(expected: "a sequence that contains at least ~a values" given: "~e") + min-count + seq))) + ans) + (lambda elems #t) + (lambda (idx . elems) #t)))))) + (cond + [(list? seq) (sequence->list result-seq)] + [(stream? seq) (sequence->stream result-seq)] + [else result-seq]))])))) ;; additional sequence constructors From 3f4dcb8e871615a59fbce2c42f418c45645a6b10 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 5 Jan 2016 09:09:52 -0600 Subject: [PATCH 313/369] more accurate error message when content-length is missing --- racket/collects/planet/private/resolver.rkt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/racket/collects/planet/private/resolver.rkt b/racket/collects/planet/private/resolver.rkt index 6ba17bfb28..32a096e1ac 100644 --- a/racket/collects/planet/private/resolver.rkt +++ b/racket/collects/planet/private/resolver.rkt @@ -782,11 +782,13 @@ See the scribble documentation on the planet/resolver module. (let ([maj/str (extract-field "Package-Major-Version" head)] [min/str (extract-field "Package-Minor-Version" head)] [content-length/str (extract-field "Content-Length" head)]) - (unless (and maj/str min/str content-length/str + (unless (and maj/str min/str (nat? (string->number maj/str)) - (nat? (string->number min/str)) - (nat? (string->number content-length/str))) + (nat? (string->number min/str))) (abort "Server did not include valid major and minor version information")) + (unless (and content-length/str + (nat? (string->number content-length/str))) + (abort "Server did not include content-length")) (let* ([filename (make-temporary-file "planettmp~a.plt")] [maj (string->number maj/str)] [min (string->number min/str)] From c7726e23ec354e12399a846940408aee000fe979 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 5 Jan 2016 09:14:15 -0600 Subject: [PATCH 314/369] fix random-generation for and/c --- racket/collects/racket/contract/private/misc.rkt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index ad5d3f2c6c..75cc3c9265 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -204,8 +204,9 @@ (define (and/c-check-nonneg ctc pred) (define sub-contracts (base-and/c-ctcs ctc)) (cond - [(pairwise-stronger-contracts? (list pred (not/c negative?)) - sub-contracts) + [(pairwise-stronger-contracts? + (list (coerce-contract 'and/c-check-nonneg pred) (not/c negative?)) + sub-contracts) (define go (hash-ref predicate-generator-table pred)) (λ (fuel) (λ () From 31a94149839cd212ca3d75280948704ef63625ec Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 5 Jan 2016 09:41:47 -0600 Subject: [PATCH 315/369] move contract tests into contract subdirectory and fix up the code that orders the tests when running them all --- .../tests/racket/contract-opt-tests.rkt | 282 ------------------ .../racket-test/tests/racket/contract/all.rkt | 32 +- .../helpers.rkt} | 0 .../tests/racket/contract/opt-c.rkt | 129 +++++++- .../random-generate.rkt} | 0 .../tests/racket/contract/test-util.rkt | 9 +- 6 files changed, 153 insertions(+), 299 deletions(-) delete mode 100644 pkgs/racket-test/tests/racket/contract-opt-tests.rkt rename pkgs/racket-test/tests/racket/{contract-helpers.rkt => contract/helpers.rkt} (100%) rename pkgs/racket-test/tests/racket/{contract-rand-test.rkt => contract/random-generate.rkt} (100%) diff --git a/pkgs/racket-test/tests/racket/contract-opt-tests.rkt b/pkgs/racket-test/tests/racket/contract-opt-tests.rkt deleted file mode 100644 index 8c5cd17f6b..0000000000 --- a/pkgs/racket-test/tests/racket/contract-opt-tests.rkt +++ /dev/null @@ -1,282 +0,0 @@ -#lang racket/base -(require racket/contract - rackunit - rackunit/text-ui) - -(define ((blame-to whom) exn) - (and (exn:fail:contract:blame? exn) - (regexp-match? (regexp-quote (format "blaming: ~a" whom)) - (exn-message exn)))) - -(define ((match-msg . msgs) exn) - (and (exn:fail? exn) - (for/and ([msg (in-list msgs)]) - (regexp-match (regexp-quote msg) (exn-message exn))))) - -(define-simple-check (check-pred2 func thunk) - (let-values ([(a b) (thunk)]) - (func a b))) - -(define-simple-check (check-name expected ctc) - (let ((got (contract-name ctc))) - (equal? expected got))) - -(define opt-tests - (test-suite - "Tests for opt/c" - - (test-case - "or 1" - (check-pred (λ (x) (= x 1)) - (contract (opt/c (or/c number? boolean?)) 1 'pos 'neg))) - - (test-case - "or 2" - (check-pred (λ (x) (eq? x #t)) - (contract (opt/c (or/c number? boolean?)) #t 'pos 'neg))) - - (test-exn - "or 3" - (blame-to 'pos) - (λ () - (contract (opt/c (or/c number? boolean?)) "string" 'pos 'neg))) - - (test-case - "or 4" - (check-pred (λ (x) (= x 1)) - ((contract (opt/c (or/c number? (-> boolean? number?))) - (λ (x) 1) 'pos 'neg) #t))) - - (test-case - "or 5" - (check-pred (λ (x) (= x 1)) - ((contract (opt/c (or/c (-> boolean? boolean? number?) (-> boolean? number?))) - (λ (x y) 1) 'pos 'neg) #t #f))) - - (test-case - "lifting 1" - (check-pred (λ (x) (= x 1)) - (let ((volatile 0)) - (contract (opt/c (between/c (begin (set! volatile 1) 3) 5)) 4 'pos 'neg) - volatile))) - - (test-case - "arrow 1" - (check-pred (λ (x) (= x 1)) - ((contract (opt/c (-> boolean? number?)) (λ (x) 1) 'pos 'neg) #t))) - - (test-case - "arrow 2" - (check-pred2 (λ (x y) (and (= x 1) (= y 2))) - (λ () - ((contract (opt/c (-> boolean? (values number? number?))) - (λ (x) (values 1 2)) 'pos 'neg) #t)))) - - (test-case - "arrow 3" - (check-pred2 (λ (x y) (and (= x 1) (= y 2))) - (λ () - ((contract (opt/c (-> boolean? any)) (λ (x) (values 1 2)) 'pos 'neg) #t)))) - - (test-case - "arrow 4" - (check-pred (λ (x) (= x 1)) - ((contract (opt/c (-> boolean? any)) (λ (x) 1) 'pos 'neg) #t))) - - (test-exn - "arrow 5" - (blame-to 'neg) - (λ () - ((contract (opt/c (-> boolean? number?)) (λ (x) #t) 'pos 'neg) 1))) - - (test-exn - "arrow 6" - (blame-to 'pos) - (λ () - ((contract (opt/c (-> boolean? number?)) (λ (x) #t) 'pos 'neg) #t))) - - (test-case - "flat-contract 1" - (check-pred (λ (x) (= x 1)) - (contract (opt/c (flat-contract (λ (x) (= x 1)))) 1 'pos 'neg))) - - (test-exn - "flat-contract 2" - (match-msg "expected: flat-contract?") - (λ () - (contract (opt/c (flat-contract (λ (x y) #f))) 1 'pos 'neg))) - - (test-case - "cons/c 1" - (check-pred (λ (x) (and (= (car x) 1) (= (cdr x) 2))) - (contract (opt/c (cons/c number? (flat-contract (λ (x) (= x 2))))) - (cons 1 2) 'pos 'neg))) - - (test-case - "cons/c 1" - (check-pred (λ (x) (and (= (car x) 1) (= (cdr x) 2))) - (contract (opt/c (cons/c number? (flat-contract (λ (x) (= x 2))))) - (cons 1 2) 'pos 'neg))) - - (test-case - "cons/c 2" - (check-pred (λ (x) (and (= (car x) 1) (= ((cdr x) 1) 2))) - (contract (opt/c (cons/c number? (-> number? any))) - (cons 1 (λ (x) 2)) 'pos 'neg))) - - (test-case - "between/c 1" - (check-pred (λ (x) (= x 1)) - (contract (opt/c (between/c 1 2)) 1 'pos 'neg))) - - (test-case - "between/c 2" - (blame-to 'pos) - (λ () - (contract (opt/c (between/c 1 2)) 3 'pos 'neg))) - - (test-exn - "between/c 2" - (match-msg "expected: real?" "argument position: 1st") - (λ () - (contract (opt/c (between/c 'x 'b)) 1 'pos 'neg))) - - (test-exn - "between/c 3" - (match-msg "expected: real?" "argument position: 2nd") - (λ () - (contract (opt/c (between/c 1 'b)) 1 'pos 'neg))) - - ;; - ;; name tests - ;; - - (test-case - "integer? name" - (check-name 'integer? (opt/c (flat-contract integer?)))) - - (test-case - "boolean? name" - (check-name 'boolean? (opt/c (flat-contract boolean?)))) - - (test-case - "char? name" - (check-name 'char? (opt/c (flat-contract char?)))) - - (test-case - "any/c name" - (check-name 'any/c (opt/c any/c))) - - (test-case - "-> name 1" - (check-name '(-> integer? integer?) (opt/c (-> integer? integer?)))) - - (test-case - "-> name 2" - (check-name '(-> integer? any) (opt/c (-> integer? any)))) - - (test-case - "-> name 3" - (check-name '(-> integer? (values boolean? char?)) (opt/c (-> integer? (values boolean? char?))))) - - (test-case - "or/c name 1" - (check-name '(or/c) (opt/c (or/c)))) - - (test-case - "or/c name 2" - (check-name '(or/c integer? gt0?) (opt/c (or/c integer? (let ([gt0? (lambda (x) (> x 0))]) gt0?))))) - - (test-case - "or/c name 3" - (check-name '(or/c integer? boolean?) - (opt/c (or/c (flat-contract integer?) - (flat-contract boolean?))))) - - (test-case - "or/c name 4" - (check-name '(or/c integer? boolean?) - (opt/c (or/c integer? boolean?)))) - - (test-case - "or/c name 5" - (check-name '(or/c (-> (>=/c 5) (>=/c 5)) boolean?) - (opt/c (or/c (-> (>=/c 5) (>=/c 5)) boolean?)))) - - (test-case - "or/c name 6" - (check-name '(or/c boolean? (-> (>=/c 5) (>=/c 5))) - (opt/c (or/c boolean? (-> (>=/c 5) (>=/c 5)))))) - - (test-case - "or/c name 7" - (check-name '(or/c (-> (>=/c 5) (>=/c 5)) - (-> (<=/c 5) (<=/c 5) (<=/c 5))) - (opt/c (or/c (-> (>=/c 5) (>=/c 5)) - (-> (<=/c 5) (<=/c 5) (<=/c 5)))))) - - (test-case - "or/c name 8" - (check-name '(or/c boolean? - (-> (>=/c 5) (>=/c 5)) - (-> (<=/c 5) (<=/c 5) (<=/c 5))) - (opt/c (or/c boolean? - (-> (>=/c 5) (>=/c 5)) - (-> (<=/c 5) (<=/c 5) (<=/c 5)))))) - - (test-case - "=/c name 1" - (check-name '(=/c 5) (opt/c (=/c 5)))) - - (test-case - ">=/c name 1" - (check-name '(>=/c 5) (opt/c (>=/c 5)))) - - (test-case - "<=/c name 1" - (check-name '(<=/c 5) (opt/c (<=/c 5)))) - - (test-case - "/c name 1" - (check-name '(>/c 5) (opt/c (>/c 5)))) - - (test-case - "between/c name 1" - (check-name '(between/c 5 6) (opt/c (between/c 5 6)))) - - (test-case - "cons/c name 1" - (check-name '(cons/c boolean? integer?) - (opt/c (cons/c boolean? (flat-contract integer?))))) - - (test-case - "cons/c name 2" - (check-name '(cons/c boolean? integer?) - (opt/c (cons/c boolean? (flat-contract integer?))))) - - (test-case - "cons/c name 1" - (check-name '(cons/c boolean? integer?) - (opt/c (cons/c boolean? (flat-contract integer?))))) - - (test-case - "cons/c name 2" - (check-name '(cons/c boolean? integer?) - (opt/c (cons/c boolean? (flat-contract integer?))))) - - (test-case - "cons/c name 3" - (check-name '(cons/c boolean? integer?) - (opt/c (cons/c boolean? (flat-contract integer?))))) - - (test-case - "cons/c name 4" - (check-name '(cons/c (-> boolean? boolean?) integer?) - (opt/c (cons/c (-> boolean? boolean?) integer?)))))) - -(unless (zero? (run-tests opt-tests)) - (error 'contract-opt-tests.rkt "tests failed")) diff --git a/pkgs/racket-test/tests/racket/contract/all.rkt b/pkgs/racket-test/tests/racket/contract/all.rkt index c6ec0e8aa5..348f900764 100644 --- a/pkgs/racket-test/tests/racket/contract/all.rkt +++ b/pkgs/racket-test/tests/racket/contract/all.rkt @@ -98,7 +98,7 @@ #:when (and (regexp-match #rx"[.]rkt$" (path->string file)) (not (member (path->string file) - '("test-util.rkt" "all.rkt"))))) + '("info.rkt" "test-util.rkt" "all.rkt"))))) file)) (define (find-deps file) @@ -117,26 +117,34 @@ (cond [(and (list? exp) (pair? exp) - (eq? (car exp) 'make-basic-contract-namespace)) - (when deps + (or (equal? (car exp) 'make-basic-contract-namespace) + (equal? (car exp) 'make-full-contract-namespace))) + (when deps (error 'find-deps "found two calls to make-basic-contract-namespace in ~a" file)) - (set! deps (map remove-quote (cdr exp)))] + (set! deps (append (if (equal? (car exp) 'make-full-contract-namespace) + full-contract-namespace-initial-set + '()) + (map remove-quote (cdr exp))))] [(list? exp) (for-each loop exp)] [else (void)])) + (unless deps (printf "no deps ~a\n" file)) deps) (define (dep boolean? number?))) + (λ (x) 1) 'pos 'neg) #t) + 1) + + (test/spec-passed/result + "or 5" + '((contract (opt/c (or/c (-> boolean? boolean? number?) (-> boolean? number?))) + (λ (x y) 1) 'pos 'neg) #t #f) + 1) + + (test/spec-passed/result + "lifting 1" + '(let ((volatile 0)) + (contract (opt/c (between/c (begin (set! volatile 1) 3) 5)) 4 'pos 'neg) + volatile) + 1) + + (test/spec-passed/result + "arrow 1" + '((contract (opt/c (-> boolean? number?)) (λ (x) 1) 'pos 'neg) #t) + 1) + + (test/spec-passed/result + "arrow 2" + '(call-with-values + (λ () ((contract (opt/c (-> boolean? (values number? number?))) + (λ (x) (values 1 2)) 'pos 'neg) #t)) + list) + '(1 2)) + + (test/spec-passed/result + "arrow 3" + '(call-with-values + (λ () ((contract (opt/c (-> boolean? any)) (λ (x) (values 1 2)) 'pos 'neg) #t)) + list) + '(1 2)) + + (test/spec-passed/result + "arrow 4" + '((contract (opt/c (-> boolean? any)) (λ (x) 1) 'pos 'neg) #t) + 1) + + (test/neg-blame + "arrow 5" + '((contract (opt/c (-> boolean? number?)) (λ (x) #t) 'pos 'neg) 1)) + + (test/pos-blame + "arrow 6" + '((contract (opt/c (-> boolean? number?)) (λ (x) #t) 'pos 'neg) #t)) + + (test/spec-passed/result + "flat-contract 1" + '(contract (opt/c (flat-contract (λ (x) (= x 1)))) 1 'pos 'neg) + 1) + + (test/spec-passed/result + "flat-contract 2" + '(with-handlers ([exn:fail? (λ (x) (regexp-match? #rx"expected: flat-contract[?]" + (exn-message x)))]) + (contract (opt/c (flat-contract (λ (x y) #f))) 1 'pos 'neg) + 'no-exn) + #t) + + (test/spec-passed/result + "cons/c 1" + '(contract (opt/c (cons/c number? (flat-contract (λ (x) (= x 2))))) + (cons 1 2) 'pos 'neg) + '(1 . 2)) + + (test/spec-passed/result + "cons/c 1b" + '(contract (opt/c (cons/c number? (flat-contract (λ (x) (= x 2))))) + (cons 1 2) 'pos 'neg) + '(1 . 2)) + + (test/spec-passed/result + "cons/c 2" + '(let ([x (contract (opt/c (cons/c number? (-> number? any))) + (cons 1 (λ (x) 2)) 'pos 'neg)]) + (and (= (car x) 1) (= ((cdr x) 1) 2))) + #t) + + (test/spec-passed/result + "between/c 1" + '(contract (opt/c (between/c 1 2)) 1 'pos 'neg) + 1) + + (test/pos-blame + "between/c 2" + '(contract (opt/c (between/c 1 2)) 3 'pos 'neg)) + + (test/spec-passed/result + "between/c 2" + '(with-handlers ([exn:fail? (λ (x) + (regexp-match? + #rx"expected: real[?].*argument position: 1st" + (exn-message x)))]) + (contract (opt/c (between/c 'x 'b)) 1 'pos 'neg) + 'no-exn) + #t) + + (test/spec-passed/result + "between/c 3" + '(with-handlers ([exn:fail? (λ (x) + (regexp-match? + #rx"expected: real[?].*argument position: 2nd" + (exn-message x)))]) + (contract (opt/c (between/c 1 'b)) 1 'pos 'neg)) + #t) + + ;; test the predicate (ctest #t couple? (contract (couple/c any/c any/c) (make-couple 1 2) 'pos 'neg)) (ctest #t couple? (make-couple 1 2)) (ctest #t couple? (contract (couple/dc [hd any/c] [tl (hd) any/c]) (make-couple 1 2) 'pos 'neg)) (ctest #f couple? 1) - (ctest #f couple? #f)) \ No newline at end of file + (ctest #f couple? #f)) diff --git a/pkgs/racket-test/tests/racket/contract-rand-test.rkt b/pkgs/racket-test/tests/racket/contract/random-generate.rkt similarity index 100% rename from pkgs/racket-test/tests/racket/contract-rand-test.rkt rename to pkgs/racket-test/tests/racket/contract/random-generate.rkt diff --git a/pkgs/racket-test/tests/racket/contract/test-util.rkt b/pkgs/racket-test/tests/racket/contract/test-util.rkt index 12acc74b66..e8856fd2a5 100644 --- a/pkgs/racket-test/tests/racket/contract/test-util.rkt +++ b/pkgs/racket-test/tests/racket/contract/test-util.rkt @@ -13,6 +13,7 @@ current-contract-namespace make-basic-contract-namespace make-full-contract-namespace + full-contract-namespace-initial-set contract-syntax-error-test contract-error-test @@ -104,10 +105,10 @@ (define (make-full-contract-namespace . addons) (apply make-basic-contract-namespace - 'racket/contract - 'racket/class - 'racket/set - addons)) + (append full-contract-namespace-initial-set addons))) +(define full-contract-namespace-initial-set + '(racket/contract racket/class racket/set)) + (define (contract-eval x #:test-case-name [test-case #f]) (with-handlers ((exn:fail? (λ (x) From 656044b8fc485ff38addcb4749172b4af068fe72 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 5 Jan 2016 14:30:34 -0600 Subject: [PATCH 316/369] random-sample: use reservoir sampling to do a single pass over sequences. Suggested by Eli. --- .../racket-test-core/tests/racket/number.rktl | 18 ++++--- racket/collects/racket/random.rkt | 54 +++++++++++++------ 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/number.rktl b/pkgs/racket-test-core/tests/racket/number.rktl index 9502a901df..99ba500a1d 100644 --- a/pkgs/racket-test-core/tests/racket/number.rktl +++ b/pkgs/racket-test-core/tests/racket/number.rktl @@ -3,7 +3,7 @@ (Section 'numbers) -(require racket/extflonum racket/random) +(require racket/extflonum racket/random racket/list) (test #f number? 'a) (test #f complex? 'a) @@ -2514,15 +2514,21 @@ (parameterize ([current-pseudo-random-generator (vector->pseudo-random-generator #(3620087466 1904163406 3177592043 1406334318 257151704 3090455638))]) - (test 3 random-ref '(1 2 3 4 5)) - (test 10 random-ref '#(7 6 8 9 10)) - (test #\e random-ref "abcde")) + (test 1 random-ref '(1 2 3 4 5)) + (test 6 random-ref '#(7 6 8 9 10)) + (test #\a random-ref "abcde")) (parameterize ([current-pseudo-random-generator (vector->pseudo-random-generator #(3620087466 1904163406 3177592043 1406334318 257151704 3090455638))]) - (test '(3) random-sample '(1 2 3 4 5) 1) + (test '(1) random-sample '(1 2 3 4 5) 1) (test '(5 5 5) random-sample '(1 2 3 4 5) 3) - (test '(2 4 5) random-sample '(1 2 3 4 5) 3 #:replacement? #f)) + (test '(1 4 3) random-sample '(1 2 3 4 5) 3 #:replacement? #f) + ;; distribution is uniform + (test '(100077 100479 100375 99943 99869 100055 100482 99979 99405 99336) + values ; to avoid the whole pre-`length` list being printed if test fails + (map length (group-by values + (apply append (for/list ([i 10000]) + (random-sample (range 10) 100))))))) (test #t = 0 0) diff --git a/racket/collects/racket/random.rkt b/racket/collects/racket/random.rkt index 83955dbc2b..5bfe7beed8 100644 --- a/racket/collects/racket/random.rkt +++ b/racket/collects/racket/random.rkt @@ -20,23 +20,43 @@ (current-continuation-marks)))])) (define (random-ref seq [prng (current-pseudo-random-generator)]) - (sequence-ref seq (random (sequence-length seq)))) + (car (random-sample seq 1 prng))) (define (random-sample seq n [prng (current-pseudo-random-generator)] #:replacement? [replacement? #t]) - (cond [replacement? - (for/list ([i (in-range n)]) - (random-ref seq prng))] - [else - (unless (>= (sequence-length seq) n) - (raise-argument-error 'random-sample - "integer less than sequence length" - n)) - (define l (sequence-length seq)) - ;; sequences don't necessarily support removal, so instead sample - ;; indices without replacement, then index into the sequence - (let loop ([res-idx (set)]) - (cond [(= (set-count res-idx) n) ; we have all we need, we're done - (for/list ([i (in-set res-idx)]) (sequence-ref seq i))] - [else - (loop (set-add res-idx (random l)))]))])) + ;; doing reservoir sampling, to do a single pass over the sequence + ;; (some sequences may not like multiple passes) + (cond + [(not replacement?) + ;; Based on: http://rosettacode.org/wiki/Knuth's_algorithm_S#Racket + (define not-there (gensym)) + (define samples (make-vector n not-there)) + (for ([elt seq] + [i (in-naturals)]) + (cond [(< i n) ; we're not full, sample for sure + (vector-set! samples i elt)] + [(< (random (add1 i)) n) ; we've already seen n items; replace one? + (vector-set! samples (random n) elt)])) + ;; did we get enough? + (unless (for/and ([s (in-vector samples)]) + (not (eq? s not-there))) + (raise-argument-error 'random-sample + "integer less than sequence length" + n)) + (vector->list samples)] + [else + ;; similar to above, except each sample is independent + (define samples #f) + (for ([elt seq] + [i (in-naturals)]) + (cond [(= i 0) ; initialize samples + (set! samples (make-vector n elt))] + [else ; independently, maybe replace + (for ([j (in-range n)]) + (when (zero? (random (add1 i))) + (vector-set! samples j elt)))])) + (unless samples + (raise-argument-error 'random-sample + "non-empty sequence" + seq)) + (vector->list samples)])) From 533c0d16ec5ef4c108426046fd46ebdb85cfb541 Mon Sep 17 00:00:00 2001 From: Leif Andersen Date: Tue, 5 Jan 2016 15:32:47 -0500 Subject: [PATCH 317/369] Fix typo in raco documentation for scribblings. --- pkgs/racket-doc/scribblings/raco/setup.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/raco/setup.scrbl b/pkgs/racket-doc/scribblings/raco/setup.scrbl index c1f2f14a89..b351eeb35a 100644 --- a/pkgs/racket-doc/scribblings/raco/setup.scrbl +++ b/pkgs/racket-doc/scribblings/raco/setup.scrbl @@ -456,7 +456,7 @@ Optional @filepath{info.rkt} fields trigger additional actions by which determines where the manual appears in the root documentation page. A category is either a string or a symbol. If it is a string, then the string is the category label on the root - page. If it is a symbol, then it a default category label is + page. If it is a symbol, then a default category label is used. The available symbols and the order of categories on the root documentation page is as below: From 1ce6a49f94effe930f251407f3d76d3c19311224 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 5 Jan 2016 20:28:49 -0600 Subject: [PATCH 318/369] random-sample: actually use the passed-in prng. Found by Eli. --- racket/collects/racket/random.rkt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/racket/collects/racket/random.rkt b/racket/collects/racket/random.rkt index 5bfe7beed8..9dcf77c2c5 100644 --- a/racket/collects/racket/random.rkt +++ b/racket/collects/racket/random.rkt @@ -35,8 +35,8 @@ [i (in-naturals)]) (cond [(< i n) ; we're not full, sample for sure (vector-set! samples i elt)] - [(< (random (add1 i)) n) ; we've already seen n items; replace one? - (vector-set! samples (random n) elt)])) + [(< (random (add1 i) prng) n) ; we've already seen n items; replace one? + (vector-set! samples (random n prng) elt)])) ;; did we get enough? (unless (for/and ([s (in-vector samples)]) (not (eq? s not-there))) @@ -53,7 +53,7 @@ (set! samples (make-vector n elt))] [else ; independently, maybe replace (for ([j (in-range n)]) - (when (zero? (random (add1 i))) + (when (zero? (random (add1 i) prng)) (vector-set! samples j elt)))])) (unless samples (raise-argument-error 'random-sample From 4b266f1ff2680fbaa9b5ef9808a1f40f205bbe44 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 5 Jan 2016 20:33:08 -0600 Subject: [PATCH 319/369] sequence-sample: various comments from Eli. --- pkgs/racket-doc/scribblings/reference/numbers.scrbl | 8 ++++---- racket/collects/racket/random.rkt | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/numbers.scrbl b/pkgs/racket-doc/scribblings/reference/numbers.scrbl index 28e2c7121c..664c1c3fdd 100644 --- a/pkgs/racket-doc/scribblings/reference/numbers.scrbl +++ b/pkgs/racket-doc/scribblings/reference/numbers.scrbl @@ -966,8 +966,7 @@ the @tt{RtlGenRand} system function. any/c]{ Returns a random element of the sequence. Like @racket[sequence-length], does -not terminate on infinite sequences, and extracts elements up to the returned -element. +not terminate on infinite sequences, and evaluates the entire sequence. @history[#:added "6.4"]} @@ -978,12 +977,13 @@ element. [#:replacement? replacement? any/c #t]) (listof any/c)]{ -Returns a list of @racket[n] elements of @racket[seq], picked at random. +Returns a list of @racket[n] elements of @racket[seq], picked at random, listed +in any order. If @racket[replacement?] is non-false, elements are drawn with replacement, which allows for duplicates. Like @racket[sequence-length], does not terminate on infinite sequences, and -extracts elements up to the returned element. +evaluates the entire sequence. @history[#:added "6.4"]} diff --git a/racket/collects/racket/random.rkt b/racket/collects/racket/random.rkt index 9dcf77c2c5..5d1c431e1f 100644 --- a/racket/collects/racket/random.rkt +++ b/racket/collects/racket/random.rkt @@ -25,8 +25,9 @@ (define (random-sample seq n [prng (current-pseudo-random-generator)] #:replacement? [replacement? #t]) ;; doing reservoir sampling, to do a single pass over the sequence - ;; (some sequences may not like multiple passes) + ;; (some sequences may not like multiple passes, e.g., ports) (cond + [(zero? n) '()] [(not replacement?) ;; Based on: http://rosettacode.org/wiki/Knuth's_algorithm_S#Racket (define not-there (gensym)) @@ -41,7 +42,7 @@ (unless (for/and ([s (in-vector samples)]) (not (eq? s not-there))) (raise-argument-error 'random-sample - "integer less than sequence length" + "integer less than or equal to sequence length" n)) (vector->list samples)] [else @@ -57,6 +58,6 @@ (vector-set! samples j elt)))])) (unless samples (raise-argument-error 'random-sample - "non-empty sequence" + "non-empty sequence for n>0" seq)) (vector->list samples)])) From 25f8a5d0d991bc0a8f3653782d76d28dacdf8e1f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 4 Jan 2016 17:37:54 -0700 Subject: [PATCH 320/369] Revert "adjust "racket-playsound.exe" return code" This reverts commit 26560240f15085d2a884cbc973043dc2235b076d. New implementation of `play-sound` doesn't need it. --- racket/src/native-libs/playsound.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/src/native-libs/playsound.c b/racket/src/native-libs/playsound.c index 8b3cce47b8..329fb3b50f 100644 --- a/racket/src/native-libs/playsound.c +++ b/racket/src/native-libs/playsound.c @@ -6,5 +6,5 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR ignored, int nCmdShow) { - return !PlaySoundW(GetCommandLineW(), NULL, SND_SYNC | SND_NODEFAULT); + return PlaySoundW(GetCommandLineW(), NULL, SND_SYNC); } From 8068c1e2a5abdf77e5fda9cef49dbf178235b91f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 4 Jan 2016 17:38:22 -0700 Subject: [PATCH 321/369] Revert "add source for "racket-playsound.exe"" This reverts commit e08188aeda8c419b741313ef34ef0e49ac6eb6a4. New implementation of `play-sound` doesn't need it. --- racket/src/native-libs/README.txt | 3 --- racket/src/native-libs/playsound.c | 10 ---------- 2 files changed, 13 deletions(-) delete mode 100644 racket/src/native-libs/playsound.c diff --git a/racket/src/native-libs/README.txt b/racket/src/native-libs/README.txt index 5ce71afdc7..8d174f7e68 100644 --- a/racket/src/native-libs/README.txt +++ b/racket/src/native-libs/README.txt @@ -155,9 +155,6 @@ More details for Windows: uses `-static-libgcc' and `-static-libstdc++' to statically link those libraries. Use "depends.exe" to check DLL dependencies. - * The extra "playsound.c" program is meant to be compiled to - "racket-playsound.exe" for the "gui" library. - More details for Mac OS X: * 32-bit binaries are built for 10.5 and up. 64-bit binaries are diff --git a/racket/src/native-libs/playsound.c b/racket/src/native-libs/playsound.c deleted file mode 100644 index 329fb3b50f..0000000000 --- a/racket/src/native-libs/playsound.c +++ /dev/null @@ -1,10 +0,0 @@ -#include - -/* Doesn't attempt to parse the command line in the usual way. - Instead, the whole command-line is used as a path of a - sound file to play. */ - -int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR ignored, int nCmdShow) -{ - return PlaySoundW(GetCommandLineW(), NULL, SND_SYNC); -} From 1e5da68b88c48af5054b1982de11a95070c20280 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 6 Jan 2016 07:34:18 -0700 Subject: [PATCH 322/369] OS X: avoid getdtablesize() by switching frmo select() to poll() The getdtablesize() result appears not to be constant on OS X. Creating some combination of CFStream objects, threads, and CFRunLoop objects can cause the value to be increased by a factor of 10. Avoid the need for getdtablesize() by switching from select() to poll(). --- racket/src/configure | 5 +++++ racket/src/racket/configure.ac | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/racket/src/configure b/racket/src/configure index 6e6360cb35..86e48fb970 100755 --- a/racket/src/configure +++ b/racket/src/configure @@ -4792,6 +4792,11 @@ fi PREFLAGS="$PREFLAGS -DOS_X -D_DARWIN_UNLIMITED_SELECT" try_kqueue_syscall=yes + # Although select() generally works as well as poll() on OS X, + # getdtablesize() appears not to be constant within a process, + # and that breaks static allocation of fd_sets + try_poll_syscall=yes + # ".a" is typically not useful, since we always build a ".dylib": if test "${enable_libs}" == "" ; then INSTALL_LIBS_ENABLE=no-install diff --git a/racket/src/racket/configure.ac b/racket/src/racket/configure.ac index 579b400c39..e37b39ec5a 100644 --- a/racket/src/racket/configure.ac +++ b/racket/src/racket/configure.ac @@ -873,6 +873,11 @@ case "$host_os" in PREFLAGS="$PREFLAGS -DOS_X -D_DARWIN_UNLIMITED_SELECT" try_kqueue_syscall=yes + # Although select() generally works as well as poll() on OS X, + # getdtablesize() appears not to be constant within a process, + # and that breaks static allocation of fd_sets + try_poll_syscall=yes + # ".a" is typically not useful, since we always build a ".dylib": if test "${enable_libs}" == "" ; then INSTALL_LIBS_ENABLE=no-install From 92f1bfa4d23e0a691778b814a5956c849bb3af83 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 6 Jan 2016 07:45:10 -0700 Subject: [PATCH 323/369] openssl: add 'secure protocol shortcut The 'secure protocol symbol is just a shorthand for `(ssl-secure-client-context)`, but it helps highlight that the default 'auto isn't secure, and having a plain symbol smooths the connection to native Win32 and OS X implementations of SSL. --- pkgs/base/info.rkt | 2 +- pkgs/racket-doc/openssl/openssl.scrbl | 69 ++++++++++++++++++--------- pkgs/racket-lib/info.rkt | 3 ++ racket/collects/net/win32-ssl.rkt | 4 +- racket/collects/openssl/mzssl.rkt | 46 +++++++++++------- racket/src/racket/src/schvers.h | 4 +- 6 files changed, 84 insertions(+), 44 deletions(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index 34e6cdefb2..89e2e8b06f 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.3.0.11") +(define version "6.3.0.12") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/pkgs/racket-doc/openssl/openssl.scrbl b/pkgs/racket-doc/openssl/openssl.scrbl index 2562743e47..03a6c958a0 100644 --- a/pkgs/racket-doc/openssl/openssl.scrbl +++ b/pkgs/racket-doc/openssl/openssl.scrbl @@ -66,7 +66,9 @@ using the functions described in @secref["cert-procs"]. [port-no (integer-in 1 65535)] [client-protocol (or/c ssl-client-context? - 'auto 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12) + 'secure + 'auto + 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12) 'auto]) (values input-port? output-port?)]{ @@ -75,6 +77,10 @@ Connect to the host given by @racket[hostname], on the port given by return values are as for @racket[tcp-connect]: an input port and an output port. +The default @racket['auto] protocol is @bold{insecure}. Use +@racket['secure] for a secure connection. See +@racket[ssl-secure-client-context] for details. + The optional @racket[client-protocol] argument determines which encryption protocol is used, whether the server's certificate is checked, etc. The argument can be either a client context created by @@ -104,14 +110,16 @@ well-defined communication pattern, where theres no question of whether the other end is supposed to be sending or reading data. } -} +@history[#:changed "6.3.0.12" @elem{Added @racket['secure] for + @racket[client-protocol].}]} @defproc[(ssl-connect/enable-break [hostname string?] [port-no (integer-in 1 65535)] [client-protocol (or/c ssl-client-context? - 'auto 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12) + 'secure 'auto + 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12) 'auto]) (values input-port? output-port?)]{ @@ -149,11 +157,13 @@ The context is cached, so different calls to @defproc[(ssl-make-client-context - [protocol (or/c 'auto 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12) 'auto]) + [protocol (or/c 'secure 'auto + 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12) + 'auto]) ssl-client-context?]{ Creates a context to be supplied to @racket[ssl-connect]. The context -is @bold{insecure} unless additional steps are taken; see +is @bold{insecure} unless @racket['secure] is supplied or additional steps are taken; see @racket[ssl-secure-client-context] for details. The client context identifies a communication protocol (as selected by @@ -164,6 +174,7 @@ certificates. The @racket[protocol] should be one of the following: @itemize[ +@item{@racket['secure] : Equivalent to @racket[(ssl-secure-client-context)].} @item{@racket['auto] : Automatically negotiates the protocol version from those that this library considers sufficiently secure---currently TLS versions 1.0 and higher, but subject to change.} @@ -182,27 +193,29 @@ Note that SSL 2.0 support has been removed from many platforms.} ] Not all protocol versions are supported by all servers. The -@racket['auto] option offers broad compatibility at a reasonable level +@racket['secure] and @racket['auto] options offer broad compatibility at a reasonable level of security. Note that the security of connections depends on more than the protocol version; see @racket[ssl-secure-client-context] for -details. - -Not all protocol versions are available on all platforms. See also +details. See also @racket[supported-client-protocols] and @racket[supported-server-protocols]. @history[ #:changed "6.1" @elem{Added @racket['tls11] and @racket['tls12].} #:changed "6.1.1.3" @elem{Default to new @racket['auto] and disabled SSL -2.0 and 3.0 by default.} + 2.0 and 3.0 by default.} +#:changed "6.3.0.12" @elem{Added @racket['secure].} ]} @defproc[(supported-client-protocols) - (listof (or/c 'auto 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12))]{ + (listof (or/c 'secure 'auto + 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12))]{ Returns a list of symbols representing protocols that are supported -for clients on the current platform.} +for clients on the current platform. + +@history[#:changed "6.3.0.12" @elem{Added @racket['secure].}]} @defproc[(ssl-client-context? [v any/c]) boolean?]{ @@ -212,7 +225,7 @@ Returns @racket[#t] if @racket[v] is a value produced by @history[#:added "6.0.1.3"]} -@defproc[(ssl-max-client-protocol) (or/c 'sslv2 sslv3 'tls 'tls11 'tls12 #f)]{ +@defproc[(ssl-max-client-protocol) (or/c 'sslv2 'sslv3 'tls 'tls11 'tls12 #f)]{ Returns the most recent SSL/TLS protocol version supported by the current platform for client connections. @@ -231,13 +244,15 @@ current platform for client connections. [hostname-or-#f (or/c string? #f) #f] [server-protocol (or/c ssl-server-context? - 'auto 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12) + 'secure 'auto + 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12) 'auto]) ssl-listener?]{ Like @racket[tcp-listen], but the result is an SSL listener. The extra optional @racket[server-protocol] is as for @racket[ssl-connect], except that a -context must be a server context instead of a client context. +context must be a server context instead of a client context, and +@racket['secure] is simply an alias for @racket['auto]. Call @racket[ssl-load-certificate-chain!] and @racket[ssl-load-private-key!] to avoid a @emph{no shared cipher} @@ -250,7 +265,9 @@ An SSL listener is a synchronizable value (see @racket[sync]). It is ready---with itself as its value---when the underlying TCP listener is ready. At that point, however, accepting a connection with @racket[ssl-accept] may not complete immediately, because -further communication is needed to establish the connection.} +further communication is needed to establish the connection. + +@history[#:changed "6.3.0.12" @elem{Added @racket['secure].}]} @deftogether[( @@ -298,11 +315,16 @@ Returns @racket[#t] of @racket[v] is an SSL port produced by @defproc[(ssl-make-server-context - [protocol (or/c 'auto 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12) + [protocol (or/c 'secure 'auto + 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12) 'auto]) ssl-server-context?]{ -Like @racket[ssl-make-client-context], but creates a server context.} +Like @racket[ssl-make-client-context], but creates a server context. +For a server context, the @racket['secure] protocol is the same as +@racket['auto]. + +@history[#:changed "6.3.0.12" @elem{Added @racket['secure].}]} @defproc[(ssl-server-context? [v any/c]) boolean?]{ @@ -311,14 +333,16 @@ Returns @racket[#t] if @racket[v] is a value produced by @racket[ssl-make-server-context], @racket[#f] otherwise.} @defproc[(supported-server-protocols) - (listof (or/c 'auto 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12))]{ + (listof (or/c 'secure 'auto + 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12))]{ Returns a list of symbols representing protocols that are supported for servers on the current platform. -@history[#:added "6.0.1.3"]} +@history[#:added "6.0.1.3" + #:changed "6.3.0.12" @elem{Added @racket['secure].}]} -@defproc[(ssl-max-server-protocol) (or/c 'sslv2 sslv3 'tls 'tls11 'tls12 #f)]{ +@defproc[(ssl-max-server-protocol) (or/c 'sslv2 'sslv3 'tls 'tls11 'tls12 #f)]{ Returns the most recent SSL/TLS protocol version supported by the current platform for server connections. @@ -340,7 +364,8 @@ current platform for server connections. ssl-make-server-context ssl-make-client-context) protocol)] - [#:encrypt protocol (or/c 'auto 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12) + [#:encrypt protocol (or/c 'secure 'auto + 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12) 'auto] [#:close-original? close-original? boolean? #f] [#:shutdown-on-close? shutdown-on-close? boolean? #f] diff --git a/pkgs/racket-lib/info.rkt b/pkgs/racket-lib/info.rkt index ededc6b1cd..400af92e46 100644 --- a/pkgs/racket-lib/info.rkt +++ b/pkgs/racket-lib/info.rkt @@ -6,6 +6,9 @@ '(("racket-win32-i386-2" #:platform "win32\\i386") ("racket-win32-x86_64-2" #:platform "win32\\x86_64") ("racket-x86_64-linux-natipkg-2" #:platform "x86_64-linux-natipkg") + ("racket-x86_64-macosx-2" #:platform "x86_64-macosx") + ("racket-i386-macosx-2" #:platform "i386-macosx") + ("racket-ppc-macosx-2" #:platform "ppc-macosx") ("db-ppc-macosx" #:platform "ppc-macosx") ("db-win32-i386" #:platform "win32\\i386") ("db-win32-x86_64" #:platform "win32\\x86_64") diff --git a/racket/collects/net/win32-ssl.rkt b/racket/collects/net/win32-ssl.rkt index 4c0d84aa79..fd0860ce5b 100644 --- a/racket/collects/net/win32-ssl.rkt +++ b/racket/collects/net/win32-ssl.rkt @@ -18,7 +18,7 @@ win32-ssl-port? win32-ssl-available?) -(define (win32-ssl-connect host port [protocol'sslv2-or-v3]) +(define (win32-ssl-connect host port [protocol 'sslv2-or-v3]) (define-values (i o) (tcp-connect host port)) (ports->win32-ssl-ports i o #:encrypt protocol)) @@ -287,7 +287,7 @@ 0 #f ; mappers 0 #f ; algs (case protocol - [(auto sslv2-or-v3) + [(secure auto sslv2-or-v3) (bitwise-ior SP_PROT_TLS1)] [(sslv2) SP_PROT_SSL2] [(sslv3) SP_PROT_SSL3] diff --git a/racket/collects/openssl/mzssl.rkt b/racket/collects/openssl/mzssl.rkt index 852d2cd31b..0adb35afd5 100644 --- a/racket/collects/openssl/mzssl.rkt +++ b/racket/collects/openssl/mzssl.rkt @@ -42,7 +42,7 @@ TO DO: ["private/macosx.rkt" (load-macosx-keychain)]) (define protocol-symbol/c - (or/c 'auto 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12)) + (or/c 'secure 'auto 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12)) (define curve-nid-alist '((sect163k1 . 721) @@ -545,7 +545,7 @@ TO DO: (define (encrypt->method who e client?) (define f (case e - [(auto sslv2-or-v3) + [(secure auto sslv2-or-v3) (if client? SSLv23_client_method SSLv23_server_method)] [(sslv2) (if client? SSLv2_client_method SSLv2_server_method)] @@ -579,7 +579,8 @@ TO DO: ;; Keep symbols in best-last order for ssl-max-{client,server}-protocol. (define (supported-client-protocols) (filter-available - (list 'auto SSLv23_client_method + (list 'secure SSLv23_client_method + 'auto SSLv23_client_method 'sslv2-or-v3 SSLv23_client_method 'sslv2 SSLv2_client_method 'sslv3 SSLv3_client_method @@ -588,7 +589,8 @@ TO DO: 'tls12 TLSv1_2_client_method))) (define (supported-server-protocols) (filter-available - (list 'auto SSLv23_server_method + (list 'secure SSLv23_server_method + 'auto SSLv23_server_method 'sslv2-or-v3 SSLv23_server_method 'sslv2 SSLv2_server_method 'sslv3 SSLv3_server_method @@ -609,17 +611,26 @@ TO DO: ((if client? make-ssl-client-context make-ssl-server-context) ctx #f #f)) (define (make-raw-context who protocol-symbol client?) - (define meth (encrypt->method who protocol-symbol client?)) - (define ctx - (atomically ;; connect SSL_CTX_new to subsequent check-valid (ERR_get_error) - (let ([ctx (SSL_CTX_new meth)]) - (check-valid ctx who "context creation") - ctx))) - (unless (memq protocol-symbol '(sslv2 sslv3)) - (SSL_CTX_set_options ctx (bitwise-ior SSL_OP_NO_SSLv2 SSL_OP_NO_SSLv3))) - (SSL_CTX_set_mode ctx (bitwise-ior SSL_MODE_ENABLE_PARTIAL_WRITE - SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)) - ctx) + (cond + [(and (eq? protocol-symbol 'secure) + client?) + (ssl-context-ctx (ssl-secure-client-context))] + [else + (define meth (encrypt->method who protocol-symbol client?)) + (define ctx + (atomically ;; connect SSL_CTX_new to subsequent check-valid (ERR_get_error) + (let ([ctx (SSL_CTX_new meth)]) + (check-valid ctx who "context creation") + ctx))) + (unless (memq protocol-symbol '(sslv2 sslv3)) + (SSL_CTX_set_options ctx (bitwise-ior SSL_OP_NO_SSLv2 SSL_OP_NO_SSLv3))) + (SSL_CTX_set_mode ctx (bitwise-ior SSL_MODE_ENABLE_PARTIAL_WRITE + SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)) + ctx])) + +(define (need-ctx-free? context-or-encrypt-method) + (and (symbol? context-or-encrypt-method) + (not (eq? context-or-encrypt-method 'secure)))) (define (ssl-make-client-context [protocol-symbol default-encrypt]) (make-context 'ssl-make-client-context protocol-symbol #t)) @@ -1353,7 +1364,8 @@ TO DO: (let ([ctx (get-context who context-or-encrypt-method connect?)]) (check-valid ctx who "context creation") (with-failure - (lambda () (when (and ctx (symbol? context-or-encrypt-method)) + (lambda () (when (and ctx + (need-ctx-free? context-or-encrypt-method)) (SSL_CTX_free ctx))) (let ([r-bio (BIO_new (BIO_s_mem))] [w-bio (BIO_new (BIO_s_mem))] @@ -1365,7 +1377,7 @@ TO DO: (let ([ssl (SSL_new ctx)]) (check-valid ssl who "ssl setup") ;; ssl has a ref count on ctx, so release: - (when (symbol? context-or-encrypt-method) + (when (need-ctx-free? context-or-encrypt-method) (SSL_CTX_free ctx) (set! ctx #f)) (with-failure diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index b7a833417f..3d4011805a 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.11" +#define MZSCHEME_VERSION "6.3.0.12" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 3 #define MZSCHEME_VERSION_Z 0 -#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) From d160cb81a85b9bf887647818789ea24776454384 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 6 Jan 2016 07:49:28 -0700 Subject: [PATCH 324/369] raco pkg: use 'secure for an HTTPS catalog --- racket/collects/net/git-checkout.rkt | 6 ++---- racket/collects/pkg/private/network.rkt | 8 +++++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/racket/collects/net/git-checkout.rkt b/racket/collects/net/git-checkout.rkt index f41bb366f8..6ebc1caa75 100644 --- a/racket/collects/net/git-checkout.rkt +++ b/racket/collects/net/git-checkout.rkt @@ -7,7 +7,6 @@ file/gunzip file/private/check-path openssl/sha1 - openssl net/url net/head net/http-client @@ -282,11 +281,10 @@ (define (ssl-context verify?) (cond [(or (not verify?) - (getenv "GIT_SSL_NO_VERIFY") - (not ssl-available?)) + (getenv "GIT_SSL_NO_VERIFY")) (current-https-protocol)] [else - (ssl-secure-client-context)])) + 'secure])) ;; ---------------------------------------- diff --git a/racket/collects/pkg/private/network.rkt b/racket/collects/pkg/private/network.rkt index 159e1f7283..32baf25aa7 100644 --- a/racket/collects/pkg/private/network.rkt +++ b/racket/collects/pkg/private/network.rkt @@ -1,5 +1,6 @@ #lang racket/base (require net/url + net/url-connect racket/format "print.rkt" "config.rkt") @@ -57,9 +58,10 @@ (lambda (f) (f))) (lambda () (define-values (p hs) - (get-pure-port/headers url headers - #:redirections 25 - #:status? #t)) + (parameterize ([current-https-protocol 'secure]) + (get-pure-port/headers url headers + #:redirections 25 + #:status? #t))) (define status (string->number (substring hs 9 12))) (cond [(memv status success-codes) From 273bc4ea4914cbe73bbb343015cc4fdeb3a1c6a4 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 6 Jan 2016 07:50:39 -0700 Subject: [PATCH 325/369] use OS X native SSL when libssl is too old OS X's libssl is deprecated, and it doesn't work with SSL connections that need SNI. We'll distribute out own libssl builds for OS X via a package, but we need a native implementation that works well enough to get that package. --- pkgs/racket-doc/openssl/openssl.scrbl | 6 +- racket/collects/net/http-client.rkt | 8 +- racket/collects/net/osx-ssl.rkt | 462 ++++++++++++++++++++++++++ racket/collects/net/url-connect.rkt | 16 +- racket/collects/openssl/libcrypto.rkt | 3 + racket/collects/openssl/libssl.rkt | 3 + racket/src/native-libs/build-all.rkt | 4 +- racket/src/native-libs/build.rkt | 40 ++- racket/src/native-libs/install.rkt | 13 +- racket/src/racket/src/port.c | 42 +++ 10 files changed, 569 insertions(+), 28 deletions(-) create mode 100644 racket/collects/net/osx-ssl.rkt diff --git a/pkgs/racket-doc/openssl/openssl.scrbl b/pkgs/racket-doc/openssl/openssl.scrbl index 03a6c958a0..3911dd893a 100644 --- a/pkgs/racket-doc/openssl/openssl.scrbl +++ b/pkgs/racket-doc/openssl/openssl.scrbl @@ -29,8 +29,10 @@ or with the Racket distribution. In particular: included in the Racket distribution for Windows.} @item{For Mac OS X, @racketmodname[openssl] depends on -@filepath{libssl.dylib} and @filepath{libcrypto.dylib}, which are -provided by Mac OS X 10.2 and later.} +@filepath{libssl.dylib} and @filepath{libcrypto.dylib}. Although those +libraries are provided by Mac OS X 10.2 and later, their use is +deprecated, so the Racket distribution for Mac OS X includes newer +versions.} @item{For Unix, @racketmodname[openssl] depends on @filepath{libssl.so} and @filepath{libcrypto.so}, which must be diff --git a/racket/collects/net/http-client.rkt b/racket/collects/net/http-client.rkt index 79d7de5ddf..381e4bb913 100644 --- a/racket/collects/net/http-client.rkt +++ b/racket/collects/net/http-client.rkt @@ -9,6 +9,7 @@ [tcp-abandon-port plain-tcp-abandon-port]) openssl "win32-ssl.rkt" + "osx-ssl.rkt" file/gunzip) (define tolerant? #t) @@ -65,8 +66,13 @@ (cond [ssl? (set-http-conn-port-usual?! hc (= 443 port)) (cond + [(osx-old-openssl?) + ;; OpenSSL is either not available or too old; use + ;; native OS X tools + (set-http-conn-abandon-p! hc osx-ssl-abandon-port) + (osx-ssl-connect host port ssl-version)] [(or ssl-available? (not win32-ssl-available?)) - (set-http-conn-abandon-p! hc ssl-abandon-port) + (set-http-conn-abandon-p! hc ssl-abandon-port) (ssl-connect host port ssl-version)] [else (set-http-conn-abandon-p! hc win32-ssl-abandon-port) diff --git a/racket/collects/net/osx-ssl.rkt b/racket/collects/net/osx-ssl.rkt new file mode 100644 index 0000000000..4311988040 --- /dev/null +++ b/racket/collects/net/osx-ssl.rkt @@ -0,0 +1,462 @@ +#lang racket/base +(require ffi/unsafe + ffi/unsafe/define + ffi/unsafe/nsstring + ffi/unsafe/alloc + ffi/unsafe/atomic + ffi/unsafe/custodian + racket/port + racket/format + openssl) + +(provide osx-ssl-connect + osx-ssl-abandon-port + osx-ssl-output-port? + osx-old-openssl?) + +(define (osx-old-openssl?) + (and (eq? 'macosx (system-type)) + (or (not ssl-available?) + (not (memq 'tls12 (supported-client-protocols)))))) + +(define cf-lib + (and (eq? 'macosx (system-type)) + (ffi-lib "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation"))) +(define net-lib + (and (eq? 'macosx (system-type)) + (ffi-lib "/System/Library/Frameworks/CFNetwork.framework/CFNetwork"))) + +(define-ffi-definer define-cf cf-lib + #:default-make-fail make-not-available) +(define-ffi-definer define-net net-lib + #:default-make-fail make-not-available) +(define-ffi-definer define-racket #f + #:default-make-fail make-not-available) + +(define _CFReadStreamRef (_cpointer/null 'CFReadStreamRef)) +(define _CFWriteStreamRef (_cpointer/null 'CFWriteStreamRef)) + +(define _CFRunLoopRef (_cpointer/null 'CFRunLoopRef)) + +(define _CFDictionaryRef (_cpointer/null 'CFDictionaryRef)) + +(define _Boolean _bool) +(define _CFIndex _long) + +(define-cf CFRelease (_fun _pointer -> _void) + #:wrap (deallocator)) + +(define retain + ((allocator CFRelease) (lambda (p) p))) + +;; Call in atomic mode to ensure `retain` calls: +(define-cf CFStreamCreatePairWithSocketToHost + (_fun (_pointer = #f) + _NSString + _int32 + (in : (_ptr o _CFReadStreamRef)) + (out : (_ptr o _CFWriteStreamRef)) + -> _void + -> (values (and in (retain in)) (and out (retain out))))) + +(define-cf CFReadStreamScheduleWithRunLoop (_fun _CFReadStreamRef _CFRunLoopRef _pointer -> _void)) +(define-cf CFWriteStreamScheduleWithRunLoop (_fun _CFWriteStreamRef _CFRunLoopRef _pointer -> _void)) + +(define-cf CFReadStreamOpen (_fun _CFReadStreamRef -> _Boolean)) +(define-cf CFWriteStreamOpen (_fun _CFWriteStreamRef -> _Boolean)) + +(define-cf CFReadStreamClose (_fun _CFReadStreamRef -> _void)) +(define-cf CFWriteStreamClose (_fun _CFWriteStreamRef -> _void)) + +(define-cf CFReadStreamHasBytesAvailable (_fun _CFReadStreamRef -> _Boolean)) +(define-cf CFReadStreamRead (_fun _CFReadStreamRef _pointer _CFIndex -> _CFIndex)) + +(define-cf CFWriteStreamCanAcceptBytes (_fun _CFWriteStreamRef -> _Boolean)) +(define-cf CFWriteStreamWrite (_fun _CFWriteStreamRef _pointer _CFIndex -> _CFIndex)) + +(define-cf kCFRunLoopDefaultMode _pointer) + +(define-cf CFRunLoopStop (_fun _CFRunLoopRef -> _void)) + +(define-cstruct _CFStreamError ([domain _int] + [error _int32])) + +(define-cf CFReadStreamGetError (_fun _CFReadStreamRef -> _CFStreamError)) +(define-cf CFWriteStreamGetError (_fun _CFWriteStreamRef -> _CFStreamError)) + +(define-cf NSStreamSocketSecurityLevelNegotiatedSSL _pointer) +(define-cf NSStreamSocketSecurityLevelKey _pointer) + +(define-net kCFStreamPropertySSLSettings _pointer) +(define-net kCFStreamSSLValidatesCertificateChain _pointer) +(define-net kCFStreamSSLLevel _pointer) + +(define-cf kCFBooleanFalse _pointer) +(define-cf kCFBooleanTrue _pointer) + +(define-net kCFStreamSocketSecurityLevelSSLv2 _pointer) +(define-net kCFStreamSocketSecurityLevelSSLv3 _pointer) +(define-net kCFStreamSocketSecurityLevelTLSv1 _pointer) +(define-net kCFStreamSocketSecurityLevelNegotiatedSSL _pointer) + +(define-cf CFReadStreamSetProperty (_fun _CFReadStreamRef _pointer _pointer -> _Boolean)) +(define-cf CFWriteStreamSetProperty (_fun _CFWriteStreamRef _pointer _pointer -> _Boolean)) + +(define-cstruct _CFStreamClientContext ([version _CFIndex] + [info _pointer] + [retain _pointer] + [release _pointer] + [copy _pointer])) + +(define-cf CFReadStreamSetClient (_fun _CFReadStreamRef + _int + (_fun #:atomic? #t + #:async-apply (lambda (f) (f)) + _CFReadStreamRef _int _pointer -> _void) + _CFStreamClientContext-pointer + -> _Boolean)) +(define-cf CFWriteStreamSetClient (_fun _CFWriteStreamRef + _int + (_fun #:atomic? #t + #:async-apply (lambda (f) (f)) + _CFWriteStreamRef _int _pointer -> _void) + _CFStreamClientContext-pointer + -> _Boolean)) + +(define kCFStreamEventNone 0) +(define kCFStreamEventOpenCompleted 1) +(define kCFStreamEventHasBytesAvailable 2) +(define kCFStreamEventCanAcceptBytes 4) +(define kCFStreamEventErrorOccurred 8) +(define kCFStreamEventEndEncountered 16) + +(define all-evts (bitwise-ior + kCFStreamEventOpenCompleted + kCFStreamEventHasBytesAvailable + kCFStreamEventCanAcceptBytes + kCFStreamEventErrorOccurred + kCFStreamEventEndEncountered)) + +(define _CFStreamStatus + (_enum '(kCFStreamStatusNotOpen + kCFStreamStatusOpening + kCFStreamStatusOpen + kCFStreamStatusReading + kCFStreamStatusWriting + kCFStreamStatusAtEnd + kCFStreamStatusClosed + kCFStreamStatusError))) + +(define-cf CFReadStreamGetStatus + (_fun _CFReadStreamRef -> _CFStreamStatus)) +(define-cf CFWriteStreamGetStatus + (_fun _CFWriteStreamRef -> _CFStreamStatus)) + + +(define-cf CFDictionaryCreate + (_fun (_pointer = #f) + (keys : (_list i _pointer)) + (vals : (_list i _pointer)) + (_CFIndex = (length keys)) + (_pointer = #f) + (_pointer = #f) + -> _CFDictionaryRef) + #:wrap (allocator CFRelease)) + +;; ---------------------------------------- + +(define-cstruct _Scheme_Proc_Sequence ([num_procs _racket] + [data _pointer] + [proc1 _pointer] + [proc2 (_fun #:atomic? #t #:async-apply (lambda (f) (f)) _pointer -> _pointer)] + [proc3 _pointer] + [proc4 (_fun #:atomic? #t #:async-apply (lambda (f) (f)) -> _pointer)]) + #:malloc-mode 'nonatomic) + +(define-racket scheme_signal_received (_fun -> _void)) + +(define _pthread (_cpointer/null 'pthread)) + +(define-racket pthread_create + (_fun (p : (_ptr o _pthread)) _pointer _pointer _pointer + -> (r : _int) + -> (and (zero? r) + p))) +(define-racket pthread_detach + (_fun _pointer -> _int)) + +(define-racket scheme_call_sequence_of_procedures-ptr _fpointer + #:c-id scheme_call_sequence_of_procedures) + +(define-cf CFRunLoopRun-ptr _fpointer + #:c-id CFRunLoopRun) +(define-cf CFRunLoopGetCurrent-ptr _fpointer + #:c-id CFRunLoopGetCurrent) + +(define stop-and-release + ((deallocator) + (lambda (run-loop) + (CFRunLoopStop run-loop) + (CFReleaseRunLoop run-loop)))) + +(define-cf CFRetainRunLoop (_fun _CFRunLoopRef -> _CFRunLoopRef) + #:c-id CFRetain + #:wrap (allocator stop-and-release)) +(define-cf CFReleaseRunLoop (_fun _pointer -> _void) + #:c-id CFRelease) + +(define (launch-run-loop-in-pthread init-reg more-retain) + (define run-loop #f) + (define done (make-semaphore)) + (define (setup r) + ;; Called in atomic mode in arbitrary Racket thread: + (set! run-loop (CFRetainRunLoop (cast r _pointer _CFRunLoopRef))) + (init-reg run-loop) + (semaphore-post done) + (scheme_signal_received) + #f) + (define (finished) + (free-immobile-cell retainer) + #f) + ;; Retains callbacks until the thread is done: + (define retainer (malloc-immobile-cell + (vector setup finished more-retain))) + (define seq (make-Scheme_Proc_Sequence 4 + #f + CFRunLoopGetCurrent-ptr + ;; `#:aync-apply` moves the following + ;; back to the main thread (in atomic mode): + setup + CFRunLoopRun-ptr + ;; `#:async-apply` here, too: + finished)) + (define pth (pthread_create #f scheme_call_sequence_of_procedures-ptr seq)) + (unless pth (error "could not start run-loop thread")) + (pthread_detach pth) + + (semaphore-wait done) + (set! done seq) ; retains `seq` until here + + run-loop) + +;; ---------------------------------------- + +(define (osx-ssl-connect host port [protocol 'auto]) + (define-syntax-rule (check-ok (op arg ...)) + (unless (op arg ...) + (error 'op "failed"))) + + (define-values (in out) + (call-as-atomic + (lambda () + (CFStreamCreatePairWithSocketToHost host port)))) + + (check-ok (CFReadStreamSetProperty in + NSStreamSocketSecurityLevelKey + NSStreamSocketSecurityLevelNegotiatedSSL)) + (check-ok (CFWriteStreamSetProperty out + NSStreamSocketSecurityLevelKey + NSStreamSocketSecurityLevelNegotiatedSSL)) + + (unless (eq? protocol 'secure) + (define d (CFDictionaryCreate + (list kCFStreamSSLValidatesCertificateChain + kCFStreamSSLLevel) + (list kCFBooleanFalse + (case protocol + [(sslv2) kCFStreamSocketSecurityLevelSSLv2] + [(sslv3) kCFStreamSocketSecurityLevelSSLv3] + [(tls tls11 tls12) kCFStreamSocketSecurityLevelTLSv1] + [else kCFStreamSocketSecurityLevelNegotiatedSSL])))) + (check-ok (CFReadStreamSetProperty in kCFStreamPropertySSLSettings d)) + (check-ok (CFWriteStreamSetProperty out kCFStreamPropertySSLSettings d)) + (CFRelease d)) + + (define in-ready (make-semaphore)) + (define out-ready (make-semaphore 1)) + + ;; These callback must be retained so that they're not GCed + ;; until the run loop is terminated: + (define in-callback (lambda (_in evt _null) + (void (semaphore-try-wait? in-ready)) + (semaphore-post in-ready) + (scheme_signal_received))) + (define out-callback (lambda (_out evt _null) + (void (semaphore-try-wait? out-ready)) + (semaphore-post out-ready) + (scheme_signal_received))) + + (define context (make-CFStreamClientContext 0 #f #f #f #f)) + (check-ok (CFReadStreamSetClient in all-evts in-callback context)) + (check-ok (CFWriteStreamSetClient out all-evts out-callback context)) + + (define run-loop + (launch-run-loop-in-pthread + ;; This function will be called as atomic within the scheduler: + (lambda (run-loop) + (CFReadStreamScheduleWithRunLoop in run-loop kCFRunLoopDefaultMode) + (CFWriteStreamScheduleWithRunLoop out run-loop kCFRunLoopDefaultMode)) + (list in-callback out-callback))) + + (check-ok (CFWriteStreamOpen out)) + (check-ok (CFReadStreamOpen in)) + + (let loop () + (when (or (eq? (CFReadStreamGetStatus in) 'kCFStreamStatusOpening) + (eq? (CFWriteStreamGetStatus out) 'kCFStreamStatusOpening)) + (sync in-ready out-ready) + (loop))) + + (when (or (eq? (CFReadStreamGetStatus in) 'kCFStreamStatusError) + (eq? (CFWriteStreamGetStatus out) 'kCFStreamStatusError)) + (raise + (exn:fail:network + (~a "osx-ssl-connect: connection failed\n" + " address: " host "\n" + " port number: " port) + (current-continuation-marks)))) + + (define open-count 2) + (define skip-close-out? #f) + + (define in-cust-reg (register-custodian-shutdown in (lambda (v) (close!)))) + (define out-cust-reg (register-custodian-shutdown out (lambda (v) (close!)))) + + (define (close!) + (call-as-atomic + (lambda () + (set! open-count (sub1 open-count)) + (when (zero? open-count) + (unregister-custodian-shutdown in in-cust-reg) + (unregister-custodian-shutdown out out-cust-reg) + (stop-and-release run-loop) + (CFRelease in) + (CFRelease out))))) + + (define-values (in-buffer-in in-buffer-out) (make-pipe)) + (define IN-BUFFER-SIZE 4096) + (define in-buffer (make-bytes IN-BUFFER-SIZE)) + + (define lock (make-semaphore 1)) + + ;; Callbacks used below (written here so that they're allocated once): + (define (lock-unavailable/read) (wrap-evt lock (lambda () 0))) + (define (lock-unavailable/write) (wrap-evt lock (lambda () #f))) + + (define (read-in bstr) + (define n (read-bytes-avail!* bstr in-buffer-in)) + (cond + [(positive? n) n] + [(zero? n) + (void (semaphore-try-wait? in-ready)) + (cond + [(CFReadStreamHasBytesAvailable in) + (define use-bstr + (if ((bytes-length bstr) . < . IN-BUFFER-SIZE) + in-buffer + bstr)) + (define n (CFReadStreamRead in use-bstr (bytes-length use-bstr))) + (cond + [(zero? n) eof] + [(negative? n) + (raise-osx-ssl-network-error 'read-bytes + (CFReadStreamGetError in))] + [else + (cond + [(eq? use-bstr in-buffer) + (write-bytes in-buffer in-buffer-out 0 n) + ;; Try again: + 0] + [else n])])] + [(equal? (CFReadStreamGetStatus in) + 'kCFStreamStatusError) + (raise-osx-ssl-network-error 'read-bytes + (CFReadStreamGetError in))] + [else + (wrap-evt (semaphore-peek-evt in-ready) (lambda (v) 0))])])) + + (define (write-out bstr start end buffer? breakable?) + (cond + [(= start end) 0] + [else + (void (semaphore-try-wait? out-ready)) + (cond + [(CFWriteStreamCanAcceptBytes out) + (let ([n (CFWriteStreamWrite out + (if (zero? start) + bstr + (substring bstr start end)) + (- end start))]) + (cond + [(zero? n) + (wrap-evt always-evt (lambda (v) #f))] + [(n . < . -1) + (raise-osx-ssl-network-error 'write-bytes + (CFWriteStreamGetError out))] + [else n]))] + [(equal? (CFWriteStreamGetStatus out) + 'kCFStreamStatusError) + (raise-osx-ssl-network-error 'write-bytes + (CFWriteStreamGetError out))] + [else + (wrap-evt (semaphore-peek-evt out-ready) (lambda (v) #f))])])) + + (values (make-input-port/read-to-peek + 'osx-ssl + ;; read: + (lambda (bstr) + (call-with-semaphore + lock + read-in + lock-unavailable/read + bstr)) + ;; peek: + (lambda (bstr offset slow) + ;; Try fast peek on buffer port: + (define n (peek-bytes-avail!* bstr offset #f in-buffer-in)) + (if (zero? n) + (slow bstr offset) + n)) + (lambda () + (call-with-semaphore + lock + (lambda () + (CFReadStreamClose in) + (close!))))) + + (osx-ssl-output-port + (make-output-port + 'osx-ssl + (semaphore-peek-evt out-ready) + ;; write + (lambda (bstr start end non-block? enable-break?) + (call-with-semaphore + lock + write-out + lock-unavailable/write + bstr start end non-block? enable-break?)) + ;; close + (lambda () + (call-with-semaphore + lock + (lambda () + (unless skip-close-out? + (CFWriteStreamClose out)) + (close!))))) + ;; abandon: + (lambda (self) + (set! skip-close-out? #t) + (close-output-port self))))) + +(struct osx-ssl-output-port (port abandon) + #:property prop:output-port 0) + +(define (osx-ssl-abandon-port p) + (if (osx-ssl-output-port? p) + ((osx-ssl-output-port-abandon p) p) + (close-output-port p))) + +(define (raise-osx-ssl-network-error who err) + (exn:fail:network + (~a who ": failed " (CFStreamError->list err)) + (current-continuation-marks))) diff --git a/racket/collects/net/url-connect.rkt b/racket/collects/net/url-connect.rkt index d644cac826..b722c48363 100644 --- a/racket/collects/net/url-connect.rkt +++ b/racket/collects/net/url-connect.rkt @@ -4,7 +4,8 @@ [tcp-connect plain-tcp-connect] [tcp-abandon-port plain-tcp-abandon-port]) openssl - "win32-ssl.rkt") + "win32-ssl.rkt" + "osx-ssl.rkt") (provide (all-defined-out)) @@ -16,14 +17,19 @@ ;; `current-connect-scheme' (define (tcp-connect host port) (cond [(equal? (current-connect-scheme) "https") - (if (or ssl-available? - (not win32-ssl-available?)) - (ssl-connect host port (current-https-protocol)) - (win32-ssl-connect host port (current-https-protocol)))] + (cond + [(osx-old-openssl?) + (osx-ssl-connect host port (current-https-protocol))] + [(or ssl-available? + (not win32-ssl-available?)) + (ssl-connect host port (current-https-protocol))] + [else + (win32-ssl-connect host port (current-https-protocol))])] [else (plain-tcp-connect host port)])) (define (tcp-abandon-port port) (cond [(ssl-port? port) (ssl-abandon-port port)] [(win32-ssl-port? port) (win32-ssl-abandon-port port)] + [(osx-ssl-output-port? port) (osx-ssl-abandon-port port)] [else (plain-tcp-abandon-port port)])) diff --git a/racket/collects/openssl/libcrypto.rkt b/racket/collects/openssl/libcrypto.rkt index 8eeefd4120..772e9b5d1a 100644 --- a/racket/collects/openssl/libcrypto.rkt +++ b/racket/collects/openssl/libcrypto.rkt @@ -44,6 +44,9 @@ (define-runtime-path libcrypto-so (case (system-type) [(windows) '(so "libeay32")] + [(macosx) + ;; Version "1.0.0" is bundled with Racket + '(so "libcrypto" ("1.0.0" #f))] [else '(so "libcrypto")])) (define libcrypto diff --git a/racket/collects/openssl/libssl.rkt b/racket/collects/openssl/libssl.rkt index 122a346fa1..214b4fe28a 100644 --- a/racket/collects/openssl/libssl.rkt +++ b/racket/collects/openssl/libssl.rkt @@ -14,6 +14,9 @@ (define-runtime-path libssl-so (case (system-type) [(windows) '(so "ssleay32")] + [(macosx) + ;; Version "1.0.0" is bundled with Racket + '(so "libssl" ("1.0.0" #f))] [else '(so "libssl")])) (define libssl diff --git a/racket/src/native-libs/build-all.rkt b/racket/src/native-libs/build-all.rkt index d13ff7ec50..5ba42c0682 100644 --- a/racket/src/native-libs/build-all.rkt +++ b/racket/src/native-libs/build-all.rkt @@ -18,11 +18,11 @@ (cond [(or win? linux?) '("sqlite" - "openssl" "zlib")] [else null]) - '("expat" + '("openssl" + "expat" "gettext") (cond [linux? diff --git a/racket/src/native-libs/build.rkt b/racket/src/native-libs/build.rkt index f955c40eae..29dcc51512 100644 --- a/racket/src/native-libs/build.rkt +++ b/racket/src/native-libs/build.rkt @@ -314,21 +314,33 @@ (~a "cd " (build-path dest "bin") " && mv libsqlite3-0.dll sqlite3.dll")))] [("openssl") - (nonmac-only) + (define make + (if linux? + (~a "make SHARED_LDFLAGS=" "-Wl,-rpath," dest "/lib") + "make")) (config #:configure-exe (find-executable-path "sh") - #:configure (if win? - (list "./Configure" - (~a "--cross-compile-prefix=" win-prefix "-") - #f ; other flags here - (~a "mingw" (if m32? "" "64")) - "shared") - (list "./Configure" - #f - "shared" - "linux-x86_64")) - #:make (if linux? - (~a "make SHARED_LDFLAGS=" "-Wl,-rpath," dest "/lib") - "make"))] + #:configure (cond + [win? + (list "./Configure" + (~a "--cross-compile-prefix=" win-prefix "-") + #f ; other flags here + (~a "mingw" (if m32? "" "64")) + "shared")] + [mac? + (list "./Configure" + #f + "shared" + (cond + [ppc? "darwin-ppc-cc"] + [m32? "darwin-i386-cc"] + [else "darwin64-x86_64-cc"]))] + [else + (list "./Configure" + #f + "shared" + "linux-x86_64")]) + #:make make + #:make-install (~a make " install_sw"))] [("expat") (config)] [("gettext") (config #:depends (if win? '("libiconv") '()) #:configure '("--enable-languages=c") diff --git a/racket/src/native-libs/install.rkt b/racket/src/native-libs/install.rkt index 728d9e72ad..beda881d3b 100644 --- a/racket/src/native-libs/install.rkt +++ b/racket/src/native-libs/install.rkt @@ -39,6 +39,10 @@ "zlib1" "libpangowin32-1.0.0")) +(define nonwin-libs + '("libcrypto.1.0.0" + "libssl.1.0.0")) + (define linux-libs (append '("libXau.6" @@ -49,9 +53,7 @@ "libXext.6" "libXrender.1" "fonts") - '("libcrypto.1.0.0" - "libssl.1.0.0" - "libz.1" + '("libz.1" "libsqlite3.0") '("libgtk-x11-2.0.0" "libgdk-x11-2.0.0" @@ -323,6 +325,8 @@ (define (install-mac) (define (fixup p p-new) (printf "Fixing ~s\n" p-new) + (unless (memq 'write (file-or-directory-permissions p-new)) + (file-or-directory-permissions p-new #o744)) (system (format "install_name_tool -id ~a ~a" (file-name-from-path p-new) p-new)) (for-each (lambda (s) (system (format "install_name_tool -change ~a @loader_path/~a ~a" @@ -337,7 +341,7 @@ "x86_64") "-macosx")) - (install platform platform "dylib" fixup libs)) + (install platform platform "dylib" fixup (append libs nonwin-libs))) (define (install-win) (define exe-prefix (if m32? @@ -398,6 +402,7 @@ (install platform platform add-so fixup (append (remove* linux-remove-libs libs) + nonwin-libs linux-libs))) (cond diff --git a/racket/src/racket/src/port.c b/racket/src/racket/src/port.c index c5202e4205..00ec531b0b 100644 --- a/racket/src/racket/src/port.c +++ b/racket/src/racket/src/port.c @@ -11310,6 +11310,48 @@ void scheme_end_sleeper_thread() #endif +/*========================================================================*/ +/* thread helper */ +/*========================================================================*/ + +/* The scheme_call_sequence() functionc an be used, with some care, + via the FFI to run a computation in a foreign thread and thread + results through. Keeping the number of procedures below + `NUM_COPIED_SEQUENCE_PROCS` can potentially simplify things, too */ + +#define NUM_COPIED_SEQUENCE_PROCS 5 + +typedef void *(*Scheme_Sequenced_Proc)(void *); + +struct Scheme_Proc_Sequence { + Scheme_Object *num_procs; /* pointer simplifies allocation issues */ + void *init_data; + Scheme_Sequenced_Proc p[mzFLEX_ARRAY_DECL]; +}; + +void *scheme_call_sequence_of_procedures(struct Scheme_Proc_Sequence *s) + XFORM_SKIP_PROC +{ + int i, num_procs = SCHEME_INT_VAL(s->num_procs); + void *data = s->init_data; + Scheme_Sequenced_Proc copied[NUM_COPIED_SEQUENCE_PROCS]; + + if (num_procs <= NUM_COPIED_SEQUENCE_PROCS) { + for (i = 0; i < num_procs; i++) { + copied[i] = s->p[i]; + } + } + + for (i = 0; i < num_procs; i++) { + if (num_procs <= NUM_COPIED_SEQUENCE_PROCS) + data = copied[i](data); + else + data = s->p[i](data); + } + + return data; +} + /*========================================================================*/ /* memory debugging help */ /*========================================================================*/ From c706ee2c05148ef1765232eb0312ecce21a83988 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 6 Jan 2016 08:04:06 -0700 Subject: [PATCH 326/369] switch default catalogs to HTTPS --- pkgs/racket-doc/pkg/scribblings/getting-started.scrbl | 6 +++--- pkgs/racket-doc/pkg/scribblings/git-workflow.scrbl | 2 +- pkgs/racket-doc/pkg/scribblings/pkg.scrbl | 8 ++++---- pkgs/racket-doc/scribblings/guide/other.scrbl | 2 +- racket/collects/pkg/private/config.rkt | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pkgs/racket-doc/pkg/scribblings/getting-started.scrbl b/pkgs/racket-doc/pkg/scribblings/getting-started.scrbl index 477148d7ea..65cde89410 100644 --- a/pkgs/racket-doc/pkg/scribblings/getting-started.scrbl +++ b/pkgs/racket-doc/pkg/scribblings/getting-started.scrbl @@ -131,7 +131,7 @@ treated as a explicitly installed package. The PLT @tech{package catalog} at -@centerline{@url{http://pkgs.racket-lang.org}} +@centerline{@url{https://pkgs.racket-lang.org}} provides a centralized listing of available Racket packages. The PLT @tech{package catalog} normally will be the first place you check when @@ -445,7 +445,7 @@ by a simple name until it is listed on a @tech{package catalog}. If you'd like to use the PLT @tech{package catalog}, browse to -@link["http://pkgs.racket-lang.org/"]{http://pkgs.racket-lang.org/} +@link["https://pkgs.racket-lang.org/"]{https://pkgs.racket-lang.org/} and upload a new package. You will need to create an account and log in first. @@ -558,7 +558,7 @@ In your @racket[info.rkt], you should: ] Finally, when listing your package on -@url{http://pkgs.racket-lang-org}, you should supply a GitHub source +@url{https://pkgs.racket-lang-org}, you should supply a GitHub source using the URL format @tt{github://github.com/@nonterm{user}/@nonterm{repo}/@nonterm{rev}@optional{/@nonterm{path}}} (not the @tt{git://} or @exec{http://} format). diff --git a/pkgs/racket-doc/pkg/scribblings/git-workflow.scrbl b/pkgs/racket-doc/pkg/scribblings/git-workflow.scrbl index 1c334de087..f7601c987d 100644 --- a/pkgs/racket-doc/pkg/scribblings/git-workflow.scrbl +++ b/pkgs/racket-doc/pkg/scribblings/git-workflow.scrbl @@ -102,7 +102,7 @@ develops only a few of them. The intended workflow is as follows: @commandline{@command{update} --lookup --catalog @nonterm{catalog} --clone @nonterm{path-to}/@nonterm{pkg-name}} - A suitable @nonterm{catalog} might be @url{http://pkgs.racket-lang.org}.} + A suitable @nonterm{catalog} might be @url{https://pkgs.racket-lang.org}.} @item{A newly cloned package will have the specified (or existing installation's) repository as its Git @exec{origin}. If you want to diff --git a/pkgs/racket-doc/pkg/scribblings/pkg.scrbl b/pkgs/racket-doc/pkg/scribblings/pkg.scrbl index d21a87beef..cc4b025c5e 100644 --- a/pkgs/racket-doc/pkg/scribblings/pkg.scrbl +++ b/pkgs/racket-doc/pkg/scribblings/pkg.scrbl @@ -337,7 +337,7 @@ URL indicates a remote server, and a @litchar{file://} URL indicates a local catalog in the form of an SQLite database or a directory tree. PLT supports two @tech{package catalog} servers that are enabled by -default: @url{http://pkgs.racket-lang.org} for new packages and +default: @url{https://pkgs.racket-lang.org} for new packages and @url{http://planet-compats.racket-lang.org} for automatically generated packages for old @|PLaneT| packages. Anyone may host a @tech{package catalog}, and any file-serving HTTP host can act @@ -1426,10 +1426,10 @@ tests, and documentation from a package before installing it. site (where a Racket distribution downloaded from the site is configured to consult the site for packages), at least for packages associated with the distribution. Beware that -@url{http://pkgs.racket-lang.org/} generally refers to @tech{source +@url{https://pkgs.racket-lang.org/} generally refers to @tech{source packages}, not @tech{built packages}. In the near future, built -variants of the @url{http://pkgs.racket-lang.org/} packages will be -provided at @url{http://pkg-build.racket-lang.org/catalog/}. +variants of the @url{https://pkgs.racket-lang.org/} packages will be +provided at @url{https://pkg-build.racket-lang.org/catalog/}. Some packages have been split at the source level into separate library, test, and documentation packages. For example, diff --git a/pkgs/racket-doc/scribblings/guide/other.scrbl b/pkgs/racket-doc/scribblings/guide/other.scrbl index 1a9b8ea633..7134bfa9dc 100644 --- a/pkgs/racket-doc/scribblings/guide/other.scrbl +++ b/pkgs/racket-doc/scribblings/guide/other.scrbl @@ -28,7 +28,7 @@ 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://pkgs.racket-lang.org/"]{The Racket package repository} +@link["https://pkgs.racket-lang.org/"]{The Racket package repository} offer even more downloadable packages that are contributed by Racketeers. diff --git a/racket/collects/pkg/private/config.rkt b/racket/collects/pkg/private/config.rkt index 73e0feb3ce..994ce8fe1a 100644 --- a/racket/collects/pkg/private/config.rkt +++ b/racket/collects/pkg/private/config.rkt @@ -45,8 +45,8 @@ (define (get-default) (match k ['catalogs - (list "http://pkgs.racket-lang.org" - "http://planet-compats.racket-lang.org")] + (list "https://pkgs.racket-lang.org" + "https://planet-compats.racket-lang.org")] ['default-scope "user"] ['installation-name (version)] ['download-cache-dir (build-path (find-system-path 'addon-dir) From 8dfce379773e354df631a7afcf7c4907b6c91723 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 6 Jan 2016 09:02:27 -0700 Subject: [PATCH 327/369] net/win32-ssl: enable 'secure mode Validate server certificate in 'secure mode. --- racket/collects/net/win32-ssl.rkt | 105 ++++++++++++++++++------------ 1 file changed, 65 insertions(+), 40 deletions(-) diff --git a/racket/collects/net/win32-ssl.rkt b/racket/collects/net/win32-ssl.rkt index fd0860ce5b..2349109154 100644 --- a/racket/collects/net/win32-ssl.rkt +++ b/racket/collects/net/win32-ssl.rkt @@ -18,9 +18,9 @@ win32-ssl-port? win32-ssl-available?) -(define (win32-ssl-connect host port [protocol 'sslv2-or-v3]) +(define (win32-ssl-connect host port [protocol 'auto]) (define-values (i o) (tcp-connect host port)) - (ports->win32-ssl-ports i o #:encrypt protocol)) + (ports->win32-ssl-ports i o #:encrypt protocol #:hostname host)) (define (win32-ssl-abandon-port port) ;; We don't try to implement shutdown, anyway @@ -126,7 +126,7 @@ (define (check-status who r) (unless (zero? r) - (error who "failed: ~x" r))) + (network-error who "failed: ~x" r))) (define-secur32 AcquireCredentialsHandleW (_fun #:abi winapi @@ -262,7 +262,7 @@ ;; Creating a context (i.e., an SSL connection) ;; Returns a context plus initial bytes for stream -(define (create-context protocol i o out-sb in-sb) +(define (create-context protocol hostname i o out-sb in-sb) ;; Pointers to particular SecBuffer records: (define out-sb0 (ptr-ref out-sb _SecBuffer 0)) (define in-sb0 (ptr-ref in-sb _SecBuffer 0)) @@ -278,26 +278,28 @@ ;; Allocate credentials. (define cred (make-cred-handle 0 0)) (AcquireCredentialsHandleW #f - "Microsoft Unified Security Protocol Provider" - SECPKG_CRED_OUTBOUND ; SECPKG_CRED_INBOUND or SECPKG_CRED_OUTBOUND - #f - (make-SCHANNEL_CRED SCHANNEL_CRED_VERSION - 0 #f - #f - 0 #f ; mappers - 0 #f ; algs - (case protocol - [(secure auto sslv2-or-v3) - (bitwise-ior SP_PROT_TLS1)] - [(sslv2) SP_PROT_SSL2] - [(sslv3) SP_PROT_SSL3] - [(tls) SP_PROT_TLS1]) - 0 0 0 - (bitwise-ior SCH_CRED_MANUAL_CRED_VALIDATION) - 0) - #f - #f - cred) + "Microsoft Unified Security Protocol Provider" + SECPKG_CRED_OUTBOUND + #f + (make-SCHANNEL_CRED SCHANNEL_CRED_VERSION + 0 #f + #f + 0 #f ; mappers + 0 #f ; algs + (case protocol + [(secure auto sslv2-or-v3) + (bitwise-ior SP_PROT_TLS1)] + [(sslv2) SP_PROT_SSL2] + [(sslv3) SP_PROT_SSL3] + [(tls tls11 tls12) SP_PROT_TLS1]) + 0 0 0 + (if (eq? protocol 'secure) + 0 + SCH_CRED_MANUAL_CRED_VALIDATION) + 0) + #f + #f + cred) ;; Allocate a content and take responsibility for freeing ;; credientials, but it's not a real content until the @@ -309,11 +311,15 @@ (define-values (r attr) (InitializeSecurityContextW cred (if init? #f (ctx->handle ctx)) - #f + (if (eq? protocol 'secure) + hostname + #f) (bitwise-ior ISC_REQ_REPLAY_DETECT ISC_REQ_SEQUENCE_DETECT ISC_REQ_CONFIDENTIALITY ISC_REQ_STREAM ISC_REQ_ALLOCATE_MEMORY - ISC_REQ_MANUAL_CRED_VALIDATION) + (if (eq? protocol 'secure) + 0 + ISC_REQ_MANUAL_CRED_VALIDATION)) 0 SECURITY_NATIVE_DREP (if init? @@ -348,7 +354,7 @@ (define (get-leftover-bytes) (if (equal? (SecBuffer-BufferType in-sb1) SECBUFFER_EXTRA) - ;; Same the leftover bytes: + ;; Save the leftover bytes: (let ([amt (SecBuffer-cbBuffer in-sb1)]) (log-win32-ssl-debug "init context: leftover ~a" amt) (memcpy buffer (ptr-add buffer (- data-len amt)) amt) @@ -362,12 +368,15 @@ (values ctx (let ([n (get-leftover-bytes)]) (subbytes buffer 0 n)))] - [(= r SEC_I_CONTINUE_NEEDED) + [(or (= r SEC_I_CONTINUE_NEEDED) + (= r SEC_E_INCOMPLETE_MESSAGE)) ;; Pull more data from the server - (define data-len (get-leftover-bytes)) + (define new-data-len (if (= r SEC_E_INCOMPLETE_MESSAGE) + data-len + (get-leftover-bytes))) ;; Unlikely, but maybe it's possible that we don't have room ;; to read more due to leftover bytes: - (when (= data-len buffer-size) + (when (= new-data-len buffer-size) (define new-buffer (malloc (* 2 buffer-size) 'atomic-interior)) (memcpy new-buffer buffer buffer-size) (set! buffer-size (* 2 buffer-size)) @@ -375,14 +384,16 @@ ;; Go back to non-atomic mode for a potentially blocking read: (define n (call-as-nonatomic (lambda () - (read-bytes-avail! buffer i data-len buffer-size)))) + (read-bytes-avail! buffer i new-data-len buffer-size)))) (log-win32-ssl-debug "init context: read ~a" n) - (when (eof-object? n) (error "unexpected EOF")) - (loop (+ data-len n) #f)] + (when (eof-object? n) (network-error "unexpected EOF")) + (loop (+ new-data-len n) (if (= r SEC_I_CONTINUE_NEEDED) + #f + init?))] ;; Some other things are allowed to happen without implying ;; failure, but we don't handle all of them. - [else (error 'create-context - "unexpected result: ~x" r)]))))) + [else (network-error 'create-context + "unexpected result: ~x" r)]))))) (define (decrypt ctx in-pre-r in-post-w out-sb) ;; Read encrypted byte from `in-pre-r', write decrypted bytes to @@ -420,7 +431,7 @@ (and (= SECBUFFER_DATA (SecBuffer-BufferType sb)) sb))) (unless sb - (error "expected decrypted data")) + (network-error "expected decrypted data")) (write-bytes (make-sized-byte-string (SecBuffer-pvBuffer sb) (SecBuffer-cbBuffer sb)) in-post-w) @@ -446,7 +457,7 @@ ;; Other end closed the connection. (close-output-port in-post-w)] [else - (error 'decrypt "unexpected result: ~x" r)]))) + (network-error 'decrypt "unexpected result: ~x" r)]))) (define (encrypt ctx bstr start end out-sb sizes buffer) ;; Encrypt bytes [start, end) from bstr. @@ -497,16 +508,18 @@ ;; The encrypted bytes don't fit in the unencrypted space? (divide-and-conquer)] [else - (error 'decrypt "unexpected result: ~x" r)])])) + (network-error 'decrypt "unexpected result: ~x" r)])])) ;; Wrap input and output ports to produce SSL versions of the ports: -(define (ports->win32-ssl-ports i o #:encrypt [protocol 'sslv2-or-v3]) +(define (ports->win32-ssl-ports i o + #:encrypt [protocol 'auto] + #:hostname [hostname #f]) ;; Working space for encoding, decoding, and more: (define out-sb (make-SecBuffers 4)) (define in-sb (make-SecBuffers 2)) ;; Allocate the encoding/decoding context: - (define-values (ctx init-bytes) (create-context protocol i o out-sb in-sb)) + (define-values (ctx init-bytes) (create-context protocol hostname i o out-sb in-sb)) ;; Get some sizes that we need for encoding: (define sizes (make-SecPkgContext_StreamSizes 0 0 0 0 0)) @@ -664,6 +677,18 @@ ;; Done: (values (register in) (register out))) +;; ---------------------------------------- +;; Errors + +(define network-error + (case-lambda + [(str) (network-error 'win32-ssl str)] + [(who msg . args) + (raise + (exn:fail:network + (format "~a: ~a" who (apply format msg args)) + (current-continuation-marks)))])) + ;; ---------------------------------------- ;; Recognizing win32 ports From 711ab4d98412ff5451bcfd67fabaa6a272e98c57 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 6 Jan 2016 10:58:59 -0700 Subject: [PATCH 328/369] raco pkg: add `PLT_PKG_SSL_NO_VERIFY` environment variable Just in case someone needs to work around an HTTPS server without a valid certifcate. --- pkgs/racket-doc/pkg/scribblings/apis.scrbl | 1 + pkgs/racket-doc/pkg/scribblings/envvars.scrbl | 14 ++++++++++++++ racket/collects/pkg/private/network.rkt | 4 +++- 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 pkgs/racket-doc/pkg/scribblings/envvars.scrbl diff --git a/pkgs/racket-doc/pkg/scribblings/apis.scrbl b/pkgs/racket-doc/pkg/scribblings/apis.scrbl index 437eef5d85..5a816382c9 100644 --- a/pkgs/racket-doc/pkg/scribblings/apis.scrbl +++ b/pkgs/racket-doc/pkg/scribblings/apis.scrbl @@ -53,3 +53,4 @@ to the @exec{raco pkg} sub-subcommands. @include-section["name.scrbl"] @include-section["db.scrbl"] @include-section["dirs-catalog.scrbl"] +@include-section["envvars.scrbl"] diff --git a/pkgs/racket-doc/pkg/scribblings/envvars.scrbl b/pkgs/racket-doc/pkg/scribblings/envvars.scrbl new file mode 100644 index 0000000000..aba0a744ee --- /dev/null +++ b/pkgs/racket-doc/pkg/scribblings/envvars.scrbl @@ -0,0 +1,14 @@ +#lang scribble/manual +@(require "common.rkt") + +@title[#:tag "envvars"]{Package Management Environment Variables} + +If the @indexed-envvar{PLT_PKG_SSL_NO_VERIFY} environment variable is +set, server certificates are not validated for HTTPS connections. When +accessing Git servers over HTTPS, @envvar{GIT_SSL_NO_VERIFY} must be +set, too, to disable certificate validation. + +As noted in the specification of GitHub-repository package sources, if +the @envvar{PLT_USE_GITHUB_API} environment variable is set, GitHub +packages are obtained using the GitHub API protocol instead of using +the Git protocol. diff --git a/racket/collects/pkg/private/network.rkt b/racket/collects/pkg/private/network.rkt index 32baf25aa7..0ed06b0473 100644 --- a/racket/collects/pkg/private/network.rkt +++ b/racket/collects/pkg/private/network.rkt @@ -58,7 +58,9 @@ (lambda (f) (f))) (lambda () (define-values (p hs) - (parameterize ([current-https-protocol 'secure]) + (parameterize ([current-https-protocol (if (getenv "PLT_PKG_SSL_NO_VERIFY") + (current-https-protocol) + 'secure)]) (get-pure-port/headers url headers #:redirections 25 #:status? #t))) From fe1ffbe36f64f1691e06f01e5b181c9dcc638389 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 6 Jan 2016 13:17:44 -0700 Subject: [PATCH 329/369] fix a test for the default package catalog --- pkgs/racket-test/tests/pkg/tests-config.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-test/tests/pkg/tests-config.rkt b/pkgs/racket-test/tests/pkg/tests-config.rkt index bcef764690..92db1deffe 100644 --- a/pkgs/racket-test/tests/pkg/tests-config.rkt +++ b/pkgs/racket-test/tests/pkg/tests-config.rkt @@ -8,7 +8,7 @@ (with-fake-root (shelly-case "reading and writing configs" - $ "raco pkg config catalogs" =stdout> "http://pkgs.racket-lang.org\nhttp://planet-compats.racket-lang.org\n" + $ "raco pkg config catalogs" =stdout> "https://pkgs.racket-lang.org\nhttps://planet-compats.racket-lang.org\n" $ "raco pkg config -u --set catalogs http://localhost:9000" $ "raco pkg config -u catalogs" =stdout> "http://localhost:9000\n" From 69b01c637f217b76e955ea68ef24dc2563ba42aa Mon Sep 17 00:00:00 2001 From: Benjamin Greenman Date: Wed, 6 Jan 2016 15:42:58 -0500 Subject: [PATCH 330/369] typo: `curent` -> `current` --- pkgs/racket-doc/version/version.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/version/version.scrbl b/pkgs/racket-doc/version/version.scrbl index e6c7f05eab..f1bfd22f0e 100644 --- a/pkgs/racket-doc/version/version.scrbl +++ b/pkgs/racket-doc/version/version.scrbl @@ -36,7 +36,7 @@ but may be updated by patches to DrRacket.} Checks the currently available version on the PLT website (@selflink["http://download.racket-lang.org"]) and returns a value that -indicates the current state of the curent installation: +indicates the current state of the current installation: @itemize[ From 18208f76f519c32f816389041ef9f40883f6128b Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Wed, 6 Jan 2016 16:52:53 -0500 Subject: [PATCH 331/369] Improve define-cstruct inline-ability and add #:define-unsafe --- pkgs/base/info.rkt | 2 +- .../scribblings/foreign/types.scrbl | 17 +- racket/collects/ffi/unsafe.rkt | 383 ++++++++++-------- 3 files changed, 222 insertions(+), 180 deletions(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index 89e2e8b06f..f0155438f0 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.3.0.12") +(define version "6.3.0.13") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/pkgs/racket-doc/scribblings/foreign/types.scrbl b/pkgs/racket-doc/scribblings/foreign/types.scrbl index 32b4d78a61..3225084e58 100644 --- a/pkgs/racket-doc/scribblings/foreign/types.scrbl +++ b/pkgs/racket-doc/scribblings/foreign/types.scrbl @@ -1081,7 +1081,8 @@ below for a more efficient approach. (property (code:line #:alignment alignment-expr) (code:line #:malloc-mode malloc-mode-expr) (code:line #:property prop-expr val-expr) - #:no-equal)] + #:no-equal + #:define-unsafe)] #:contracts ([offset-expr exact-integer?] [alignment-expr (or/c #f 1 2 4 8 16)] [malloc-mode-expr (one-of/c 'raw 'atomic 'nonatomic @@ -1130,7 +1131,16 @@ The resulting bindings are as follows: @item{@racketidfont{set-}@racketvarfont{id}@racketidfont{-}@racket[field-id]@racketidfont{!} : a mutator function for each @racket[field-id].} - @item{@racketvarfont{id}: structure-type information compatible with + @item{@racketvarfont{id}@racketidfont{-}@racket[field-id]@racketidfont{-offset} + : the absolute offset, in bytes, of each @racket[field-id], if @racket[#:define-unsafe] is present.} + + @item{@racketidfont{unsafe-}@racketvarfont{id}@racketidfont{-}@racket[field-id] + : an unsafe accessor function for each @racket[field-id], if @racket[#:define-unsafe] is present.} + + @item{@racketidfont{unsafe-set-}@racketvarfont{id}@racketidfont{-}@racket[field-id]@racketidfont{!} + : an unsafe mutator function for each @racket[field-id], if @racket[#:define-unsafe] is present.} + +@item{@racketvarfont{id}: structure-type information compatible with @racket[struct-out] or @racket[match] (but not @racket[struct] or @racket[define-struct]); currently, this information is correct only when no @racket[super-id] @@ -1328,7 +1338,8 @@ expects arguments for both the super fields and the new ones: ] @history[#:changed "6.0.0.6" @elem{Added @racket[#:malloc-mode].} - #:changed "6.1.1.8" @elem{Added @racket[#:offset] for fields.}]} +#:changed "6.1.1.8" @elem{Added @racket[#:offset] for fields.} +#:changed "6.3.0.13" @elem{Added @racket[#:define-unsafe].}]} @; ------------------------------------------------------------ diff --git a/racket/collects/ffi/unsafe.rkt b/racket/collects/ffi/unsafe.rkt index 12ad43c6d6..47511fed3b 100644 --- a/racket/collects/ffi/unsafe.rkt +++ b/racket/collects/ffi/unsafe.rkt @@ -2,7 +2,7 @@ ;; Foreign Racket interface (require '#%foreign setup/dirs racket/unsafe/ops racket/private/for - (for-syntax racket/base racket/list syntax/stx + (for-syntax racket/base racket/list syntax/stx racket/syntax racket/struct-info)) (provide ctype-sizeof ctype-alignof compiler-sizeof @@ -1348,15 +1348,16 @@ [TYPE? (id name "?")] [TYPE-tag (id name "-tag")] [_TYPE/null (id "_" name "/null")]) - #'(define-values (_TYPE _TYPE/null TYPE? TYPE-tag) - (let ([TYPE-tag 'TYPE]) - ;; Make the predicate function have the right inferred name - (define (TYPE? x) - (and (cpointer? x) (cpointer-has-tag? x TYPE-tag))) - (values (_cpointer TYPE-tag ptr-type scheme->c c->scheme) - (_cpointer/null TYPE-tag ptr-type scheme->c c->scheme) - TYPE? - TYPE-tag)))))])) + #'(begin + (define TYPE-tag + (gensym 'TYPE)) + (define _TYPE + (_cpointer TYPE-tag ptr-type scheme->c c->scheme)) + (define _TYPE/null + (_cpointer/null TYPE-tag ptr-type scheme->c c->scheme)) + ;; Make the predicate function have the right inferred name + (define (TYPE? x) + (and (cpointer? x) (cpointer-has-tag? x TYPE-tag))))))])) ;; ---------------------------------------------------------------------------- ;; Struct wrappers @@ -1423,9 +1424,14 @@ ;; type. (provide define-cstruct) (define-syntax (define-cstruct stx) - (define (make-syntax _TYPE-stx has-super? slot-names-stx slot-types-stx slot-offsets-stx - alignment-stx malloc-mode-stx property-stxes property-binding-stxes - no-equal?) + (define (make-syntax + _TYPE-stx has-super? slot-names-stx slot-types-stx slot-offsets-stx + alignment-stx malloc-mode-stx property-stxes property-binding-stxes + no-equal? define-unsafe?) + (define change-unsafe-ids + (if define-unsafe? + (λ (x) x) + generate-temporaries)) (define name (cadr (regexp-match #rx"^_(.+)$" (symbol->string (syntax-e _TYPE-stx))))) (define slot-names (map (lambda (x) (symbol->string (syntax-e x))) @@ -1472,10 +1478,14 @@ [TYPE->list* (id name"->list*")] [TYPE-tag (id name"-tag")] [(stype ...) (ids (lambda (s) `(,name"-",s"-type")))] + [(unsafe-TYPE-SLOT ...) + (change-unsafe-ids (ids (lambda (s) `("unsafe-",name"-",s))))] + [(unsafe-set-TYPE-SLOT! ...) + (change-unsafe-ids (ids (lambda (s) `("unsafe-set-",name"-",s"!"))))] [(TYPE-SLOT ...) (ids (lambda (s) `(,name"-",s)))] [(set-TYPE-SLOT! ...) (ids (lambda (s) `("set-",name"-",s"!")))] - [(offset ...) (generate-temporaries - (ids (lambda (s) `(,s"-offset"))))] + [(offset ...) + (change-unsafe-ids (ids (lambda (s) `(,name"-",s"-offset"))))] [alignment alignment-stx] [malloc-mode (or malloc-mode-stx #'(quote atomic))]) (with-syntax ([get-super-info @@ -1491,42 +1501,39 @@ [add-equality-property (if no-equal? #'values #'add-equality-property)]) - #'(define-values (make-wrap-TYPE struct:cpointer:TYPE) - (let () - (define-values (struct:cpointer:TYPE - cpointer:TYPE - ? - ref - set) - (make-struct-type 'cpointer:TYPE - struct:cpointer:super - (if struct:cpointer:super - 0 - 1) - 0 #f - (add-equality-property - (append - (if struct:cpointer:super - null - (list - (cons prop:cpointer 0))) - (list prop ...))) - (current-inspector) - #f - (if struct:cpointer:super - null - '(0)))) - (values cpointer:TYPE struct:cpointer:TYPE)))))] + #'(define-values (struct:cpointer:TYPE + make-wrap-TYPE + _? + _ref + _set) + (make-struct-type 'cpointer:TYPE + struct:cpointer:super + (if struct:cpointer:super + 0 + 1) + 0 #f + (add-equality-property + (append + (if struct:cpointer:super + null + (list + (cons prop:cpointer 0))) + (list prop ...))) + (current-inspector) + #f + (if struct:cpointer:super + null + '(0))))))] [define-wrap-type (if (null? property-stxes) - #'(define (wrap-TYPE-type t) - (super-wrap-type-type t)) + #'(define wrap-TYPE-type + (procedure-rename super-wrap-type-type 'wrap-TYPE-type)) #'(define (wrap-TYPE-type t) (make-ctype t - values + (λ (x) x) (lambda (p) (and p (make-wrap-TYPE p))))))] - [(property-binding ...) property-binding-stxes] + [([(property-binding-ids ...) . property-binding-form] ...) property-binding-stxes] [(maybe-struct:TYPE ...) (if (null? property-stxes) null (list #'struct:cpointer:TYPE))]) @@ -1540,118 +1547,119 @@ (reverse (list (quote-syntax TYPE-SLOT) ...)) (reverse (list (quote-syntax set-TYPE-SLOT!) ...)) #t)))) - (define-values (_TYPE _TYPE-pointer _TYPE-pointer/null TYPE? TYPE-tag - make-TYPE TYPE-SLOT ... set-TYPE-SLOT! ... - list->TYPE list*->TYPE TYPE->list TYPE->list* - maybe-struct:TYPE ...) - (let-values ([(super-pointer super-tags super-types super-offsets - super->list* list*->super - struct:cpointer:super super-wrap-type-type) - get-super-info] - property-binding ...) - (define-cpointer-type _TYPE super-pointer) - define-wrap-type - ;; these make it possible to use recursive pointer definitions - (define _TYPE-pointer (wrap-TYPE-type _TYPE)) - (define _TYPE-pointer/null (wrap-TYPE-type _TYPE/null)) - (define-values (stype ...) (values slot-type ...)) - (define types (list stype ...)) - (define alignment-v alignment) - (define offsets (compute-offsets types alignment-v (list slot-offset ...))) - (define-values (offset ...) (apply values offsets)) - (define all-tags (cons TYPE-tag super-tags)) - (define _TYPE* - ;; c->scheme adjusts all tags - (let* ([cst (make-cstruct-type types #f alignment-v)] - [t (_cpointer TYPE-tag cst)] - [c->s (ctype-c->scheme t)]) - (wrap-TYPE-type - (make-ctype cst (ctype-scheme->c t) - ;; hack: modify & reuse the procedure made by _cpointer - (lambda (p) - (if p (set-cpointer-tag! p all-tags) (c->s p)) - p))))) - (define-values (all-types all-offsets) - (if (and has-super? super-types super-offsets) - (values (append super-types (cdr types)) - (append super-offsets (cdr offsets))) - (values types offsets))) - (define (TYPE-SLOT x) - (unless (TYPE? x) - (raise-argument-error 'TYPE-SLOT struct-string x)) - (ptr-ref x stype 'abs offset)) - ... - (define (set-TYPE-SLOT! x slot) - (unless (TYPE? x) - (raise-argument-error 'set-TYPE-SLOT! struct-string 0 x slot)) - (ptr-set! x stype 'abs offset slot)) - ... - (define make-TYPE - (if (and has-super? super-types super-offsets) - ;; init using all slots - (lambda vals - (if (= (length vals) (length all-types)) - (let ([block (make-wrap-TYPE (malloc _TYPE* malloc-mode))]) - (set-cpointer-tag! block all-tags) - (for-each (lambda (type ofs value) - (ptr-set! block type 'abs ofs value)) - all-types all-offsets vals) - block) - (error '_TYPE "expecting ~s values, got ~s: ~e" - (length all-types) (length vals) vals))) - ;; normal initializer - (lambda (slot ...) - (let ([block (make-wrap-TYPE (malloc _TYPE* malloc-mode))]) + (define-values (super-pointer super-tags super-types super-offsets + super->list* list*->super + struct:cpointer:super super-wrap-type-type) + get-super-info) + (define-values (property-binding-ids ...) . property-binding-form) ... + (define-cpointer-type _^TYPE super-pointer) + define-wrap-type + ;; these make it possible to use recursive pointer definitions + (define _TYPE-pointer (wrap-TYPE-type _^TYPE)) + (define _TYPE-pointer/null (wrap-TYPE-type _^TYPE/null)) + (define-values (stype ...) (values slot-type ...)) + (define types (list stype ...)) + (define alignment-v alignment) + (define offsets (compute-offsets types alignment-v (list slot-offset ...))) + (define-values (offset ...) (apply values offsets)) + (define all-tags (cons ^TYPE-tag super-tags)) + (define _TYPE + ;; c->scheme adjusts all tags + (let* ([cst (make-cstruct-type types #f alignment-v)] + [t (_cpointer ^TYPE-tag cst)] + [c->s (ctype-c->scheme t)]) + (wrap-TYPE-type + (make-ctype cst (ctype-scheme->c t) + ;; hack: modify & reuse the procedure made by _cpointer + (lambda (p) + (if p (set-cpointer-tag! p all-tags) (c->s p)) + p))))) + (define-values (all-types all-offsets) + (if (and has-super? super-types super-offsets) + (values (append super-types (cdr types)) + (append super-offsets (cdr offsets))) + (values types offsets))) + + (begin + (define (unsafe-TYPE-SLOT x) + (ptr-ref x stype 'abs offset)) + (define (TYPE-SLOT x) + (unless (^TYPE? x) + (raise-argument-error 'TYPE-SLOT struct-string x)) + (unsafe-TYPE-SLOT x))) + ... + (begin + (define (unsafe-set-TYPE-SLOT! x slot) + (ptr-set! x stype 'abs offset slot)) + (define (set-TYPE-SLOT! x slot) + (unless (^TYPE? x) + (raise-argument-error 'set-TYPE-SLOT! struct-string 0 x slot)) + (unsafe-set-TYPE-SLOT! x slot))) + ... + (define make-TYPE + (if (and has-super? super-types super-offsets) + ;; init using all slots + (lambda vals + (if (= (length vals) (length all-types)) + (let ([block (make-wrap-TYPE (malloc _TYPE malloc-mode))]) (set-cpointer-tag! block all-tags) - (ptr-set! block stype 'abs offset slot) - ... - block)))) - define-wrapper-struct - (define (list->TYPE vals) (apply make-TYPE vals)) - (define (list*->TYPE vals) - (cond - [(TYPE? vals) vals] - [(= (length vals) (length all-types)) - (let ([block (malloc _TYPE* malloc-mode)]) + (for-each (lambda (type ofs value) + (ptr-set! block type 'abs ofs value)) + all-types all-offsets vals) + block) + (error '_TYPE "expecting ~s values, got ~s: ~e" + (length all-types) (length vals) vals))) + ;; normal initializer + (lambda (slot ...) + (let ([block (make-wrap-TYPE (malloc _TYPE malloc-mode))]) (set-cpointer-tag! block all-tags) - (for-each - (lambda (type ofs value) - (let-values - ([(ptr tags types offsets T->list* list*->T struct:T wrap) - (cstruct-info - type - (lambda () (values #f '() #f #f #f #f #f values)))]) - (ptr-set! block type 'abs ofs - (if list*->T (list*->T value) value)))) - all-types all-offsets vals) - block)] - [else (error '_TYPE "expecting ~s values, got ~s: ~e" - (length all-types) (length vals) vals)])) - (define (TYPE->list x) - (unless (TYPE? x) - (raise-argument-error 'TYPE-list struct-string x)) - (map (lambda (type ofs) (ptr-ref x type 'abs ofs)) - all-types all-offsets)) - (define (TYPE->list* x) - (unless (TYPE? x) - (raise-argument-error 'TYPE-list struct-string x)) - (map (lambda (type ofs) - (let-values - ([(v) (ptr-ref x type 'abs ofs)] - [(ptr tags types offsets T->list* list*->T struct:T wrap) - (cstruct-info - type - (lambda () (values #f '() #f #f #f #f #f values)))]) - (if T->list* (T->list* v) v))) - all-types all-offsets)) - (cstruct-info - _TYPE* 'set! - _TYPE all-tags all-types all-offsets TYPE->list* list*->TYPE - struct:cpointer:TYPE wrap-TYPE-type) - (values _TYPE* _TYPE-pointer _TYPE-pointer/null TYPE? TYPE-tag - make-TYPE TYPE-SLOT ... set-TYPE-SLOT! ... - list->TYPE list*->TYPE TYPE->list TYPE->list* - maybe-struct:TYPE ...))))))) + (ptr-set! block stype 'abs offset slot) + ... + block)))) + define-wrapper-struct + (define (list->TYPE vals) (apply make-TYPE vals)) + (define (list*->TYPE vals) + (cond + [(^TYPE? vals) vals] + [(= (length vals) (length all-types)) + (let ([block (malloc _TYPE malloc-mode)]) + (set-cpointer-tag! block all-tags) + (for-each + (lambda (type ofs value) + (let-values + ([(ptr tags types offsets T->list* list*->T struct:T wrap) + (cstruct-info + type + (lambda () (values #f '() #f #f #f #f #f values)))]) + (ptr-set! block type 'abs ofs + (if list*->T (list*->T value) value)))) + all-types all-offsets vals) + block)] + [else (error '_TYPE "expecting ~s values, got ~s: ~e" + (length all-types) (length vals) vals)])) + (define (TYPE->list x) + (unless (^TYPE? x) + (raise-argument-error 'TYPE-list struct-string x)) + (map (lambda (type ofs) (ptr-ref x type 'abs ofs)) + all-types all-offsets)) + (define (TYPE->list* x) + (unless (^TYPE? x) + (raise-argument-error 'TYPE-list struct-string x)) + (map (lambda (type ofs) + (let-values + ([(v) (ptr-ref x type 'abs ofs)] + [(ptr tags types offsets T->list* list*->T struct:T wrap) + (cstruct-info + type + (lambda () (values #f '() #f #f #f #f #f values)))]) + (if T->list* (T->list* v) v))) + all-types all-offsets)) + (cstruct-info + _TYPE 'set! + _^TYPE all-tags all-types all-offsets TYPE->list* list*->TYPE + struct:cpointer:TYPE wrap-TYPE-type) + (define TYPE? ^TYPE? #;(procedure-rename 'TYPE?)) + (define TYPE-tag ^TYPE-tag))))) (define (err what . xs) (apply raise-syntax-error #f (if (list? what) (apply string-append what) what) @@ -1664,53 +1672,76 @@ (syntax-case #'type () [(t s) (values #'t #'s)] [_ (values #'type #f)])] - [(alignment malloc-mode properties property-bindings no-equal?) + [(alignment malloc-mode + properties property-bindings + no-equal? define-unsafe?) (let loop ([more #'more] [alignment #f] [malloc-mode #f] [properties null] [property-bindings null] - [no-equal? #f]) + [no-equal? #f] + [define-unsafe? #f]) (define (head) (syntax-case more () [(x . _) #'x])) (syntax-case more () [() (values alignment malloc-mode (reverse properties) (reverse property-bindings) - no-equal?)] + no-equal? + define-unsafe?)] [(#:alignment) (err "missing expression for #:alignment" (head))] [(#:alignment a . rest) (not alignment) - (loop #'rest #'a malloc-mode properties property-bindings no-equal?)] + (loop #'rest + #'a malloc-mode + properties property-bindings + no-equal? define-unsafe?)] [(#:alignment a . rest) (err "multiple specifications of #:alignment" (head))] - [(#:malloc-mode) (err "missing expression for #:malloc-mode" (head))] + [(#:malloc-mode) + (err "missing expression for #:malloc-mode" (head))] [(#:malloc-mode m . rest) (not malloc-mode) - (loop #'rest alignment #'m properties property-bindings no-equal?)] + (loop #'rest + alignment #'m + properties property-bindings + no-equal? define-unsafe?)] [(#:malloc-mode m . rest) (err "multiple specifications of #:malloc-mode" (head))] - [(#:property) (err "missing property expression for #:property" (head))] - [(#:property prop) (err "missing value expression for #:property" (head))] + [(#:property) + (err "missing property expression for #:property" (head))] + [(#:property prop) + (err "missing value expression for #:property" (head))] [(#:property prop val . rest) (let () (define prop-id (car (generate-temporaries '(prop)))) (define val-id (car (generate-temporaries '(prop-val)))) (loop #'rest - alignment - malloc-mode + alignment malloc-mode (list* #`(cons #,prop-id #,val-id) properties) (list* (list (list val-id) #'val) (list (list prop-id) #'(check-is-property prop)) property-bindings) - no-equal?))] + no-equal? define-unsafe?))] [(#:no-equal . rest) (if no-equal? (err "multiple specifications of #:no-equal" (head)) - (loop #'rest alignment malloc-mode properties property-bindings #t))] - [(x . _) (err (if (keyword? (syntax-e #'x)) - "unknown keyword" "unexpected form") - #'x)] + (loop #'rest + alignment malloc-mode + properties property-bindings + #t define-unsafe?))] + [(#:define-unsafe . rest) + (if define-unsafe? + (err "multiple specifications of #:define-unsafe" (head)) + (loop #'rest + alignment malloc-mode + properties property-bindings + no-equal? #t))] + [(x . _) + (err (if (keyword? (syntax-e #'x)) + "unknown keyword" "unexpected form") + #'x)] [else (err "bad syntax")]))]) (unless (identifier? _TYPE) (err "expecting a `_name' identifier or `(_name _super-name)'" @@ -1733,13 +1764,13 @@ #`(#,(datum->syntax _TYPE 'super _TYPE) slot ...) #`(#,_SUPER slot-type ...) #'(0 slot-offset ...) - alignment - malloc-mode - properties - property-bindings - no-equal?) + alignment malloc-mode + properties property-bindings + no-equal? define-unsafe?) (make-syntax _TYPE #f #'(slot ...) #`(slot-type ...) #`(slot-offset ...) - alignment malloc-mode properties property-bindings no-equal?))))] + alignment malloc-mode + properties property-bindings + no-equal? define-unsafe?))))] [(_ type () . more) (identifier? #'type) (err "must have either a supertype or at least one field")] From ccc50ca68f4feaa44b186c69184ab2460ae7683f Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Wed, 6 Jan 2016 17:42:56 -0500 Subject: [PATCH 332/369] Forgot to update racket, just base --- racket/src/racket/src/schvers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 3d4011805a..38ecd3f12b 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.12" +#define MZSCHEME_VERSION "6.3.0.13" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 3 #define MZSCHEME_VERSION_Z 0 -#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) From d3c09ead19eb4af63c3f588e1b7ee7b883337b22 Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Wed, 6 Jan 2016 19:07:33 -0500 Subject: [PATCH 333/369] Fix cpointer tags --- .../tests/racket/foreign-test.rktl | 5 +++++ racket/collects/ffi/unsafe.rkt | 14 ++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/foreign-test.rktl b/pkgs/racket-test-core/tests/racket/foreign-test.rktl index 33b904889f..1a43c52f12 100644 --- a/pkgs/racket-test-core/tests/racket/foreign-test.rktl +++ b/pkgs/racket-test-core/tests/racket/foreign-test.rktl @@ -171,6 +171,11 @@ [c7 _c7_list] [i2 _int])) +(let () + (define-cstruct _posn ([x _int] + [y _int])) + (test #t equal? 'posn posn-tag)) + (define _borl (_union _byte _long)) (define _ic7iorl (_union _ic7i _long)) diff --git a/racket/collects/ffi/unsafe.rkt b/racket/collects/ffi/unsafe.rkt index 47511fed3b..58dc55fd7d 100644 --- a/racket/collects/ffi/unsafe.rkt +++ b/racket/collects/ffi/unsafe.rkt @@ -1334,9 +1334,12 @@ (provide define-cpointer-type) (define-syntax (define-cpointer-type stx) (syntax-case stx () - [(_ _TYPE) #'(define-cpointer-type _TYPE #f #f #f)] - [(_ _TYPE ptr-type) #'(define-cpointer-type _TYPE ptr-type #f #f)] - [(_ _TYPE ptr-type scheme->c c->scheme) + [(_ _TYPE) #'(define-cpointer-type _TYPE #f #f #f #:tag #f)] + [(_ _TYPE #:tag the-tag) #'(define-cpointer-type _TYPE #f #f #f #:tag the-tag)] + [(_ _TYPE ptr-type) #'(define-cpointer-type _TYPE ptr-type #f #f #:tag #f)] + [(_ _TYPE ptr-type #:tag the-tag) #'(define-cpointer-type _TYPE ptr-type #f #f #:tag the-tag)] + [(_ _TYPE ptr-type scheme->c c->scheme) #'(define-cpointer-type _TYPE ptr-type #f #f #:tag #f)] + [(_ _TYPE ptr-type scheme->c c->scheme #:tag the-tag) (and (identifier? #'_TYPE) (regexp-match #rx"^_.+" (symbol->string (syntax-e #'_TYPE)))) (let ([name (cadr (regexp-match #rx"^_(.+)$" @@ -1349,8 +1352,7 @@ [TYPE-tag (id name "-tag")] [_TYPE/null (id "_" name "/null")]) #'(begin - (define TYPE-tag - (gensym 'TYPE)) + (define TYPE-tag (or the-tag 'TYPE)) (define _TYPE (_cpointer TYPE-tag ptr-type scheme->c c->scheme)) (define _TYPE/null @@ -1552,7 +1554,7 @@ struct:cpointer:super super-wrap-type-type) get-super-info) (define-values (property-binding-ids ...) . property-binding-form) ... - (define-cpointer-type _^TYPE super-pointer) + (define-cpointer-type _^TYPE super-pointer #:tag 'TYPE) define-wrap-type ;; these make it possible to use recursive pointer definitions (define _TYPE-pointer (wrap-TYPE-type _^TYPE)) From 961ab31776cffb119cc0c26c837b8cbd75e4dd3d Mon Sep 17 00:00:00 2001 From: Juan Francisco Cantero Hurtado Date: Wed, 6 Jan 2016 23:48:54 +0100 Subject: [PATCH 334/369] Typo: clonse -> clones. --- 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 2541da8ea8..fa015657ac 100644 --- a/racket/collects/pkg/main.rkt +++ b/racket/collects/pkg/main.rkt @@ -692,7 +692,7 @@ ("Specify treatment of multiple clones of a repository;" "s: convert, ask (interactive default), fail (other default), or force")] [(#:sym mode [ff-only try rebase] 'ff-only) pull () - ("Specify `git pull' mode for repository clonse;" + ("Specify `git pull' mode for repository clones;" "s: ff-only (the default), try, or rebase")]) #:update-deps-flags ([#:bool update-deps () "For `search-ask' or `search-auto', also update dependencies"] From 7eee46c4d320db5b9ffc70819633d14ae5ada5e7 Mon Sep 17 00:00:00 2001 From: Leif Andersen Date: Mon, 4 Jan 2016 13:49:40 -0700 Subject: [PATCH 335/369] => should not be hyperlinked to cond arrow. --- pkgs/racket-doc/scribblings/guide/pattern-macros.scrbl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-doc/scribblings/guide/pattern-macros.scrbl b/pkgs/racket-doc/scribblings/guide/pattern-macros.scrbl index a9e790d4a1..48440d9c2b 100644 --- a/pkgs/racket-doc/scribblings/guide/pattern-macros.scrbl +++ b/pkgs/racket-doc/scribblings/guide/pattern-macros.scrbl @@ -453,11 +453,11 @@ Step-by-step, expansion proceeds as follows: @racketblock[ (define-for-cbr do-f (a b) () (swap a b)) -=> (define-for-cbr do-f (b) +(unsyntax @tt{=>}) (define-for-cbr do-f (b) ([a get_1 put_1]) (swap a b)) -=> (define-for-cbr do-f () +(unsyntax @tt{=>}) (define-for-cbr do-f () ([a get_1 put_1] [b get_2 put_2]) (swap a b)) -=> (define (do-f get_1 get_2 put_1 put_2) +(unsyntax @tt{=>}) (define (do-f get_1 get_2 put_1 put_2) (define-get/put-id a get_1 put_1) (define-get/put-id b get_2 put_2) (swap a b)) From c9348f7cd72ddc1ff5ea7d4bbadf79ef5d6e7122 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 6 Jan 2016 15:33:10 -0700 Subject: [PATCH 336/369] fix Mac OS X pre-built libssl install --- racket/src/native-libs/install.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/src/native-libs/install.rkt b/racket/src/native-libs/install.rkt index beda881d3b..27f08774b3 100644 --- a/racket/src/native-libs/install.rkt +++ b/racket/src/native-libs/install.rkt @@ -333,7 +333,7 @@ (format "~a/~a.dylib" from s) (format "~a.dylib" s) p-new))) - libs) + (append libs nonwin-libs)) (system (format "strip -S ~a" p-new))) (define platform (~a (if m32? From bfe9b4aefdd08d834ec3ddf0141677bc417cd168 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 7 Jan 2016 06:11:05 -0700 Subject: [PATCH 337/369] fix CFNetwork reference for old OS X --- racket/collects/net/osx-ssl.rkt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/racket/collects/net/osx-ssl.rkt b/racket/collects/net/osx-ssl.rkt index 4311988040..b6ca990ca5 100644 --- a/racket/collects/net/osx-ssl.rkt +++ b/racket/collects/net/osx-ssl.rkt @@ -24,7 +24,11 @@ (ffi-lib "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation"))) (define net-lib (and (eq? 'macosx (system-type)) - (ffi-lib "/System/Library/Frameworks/CFNetwork.framework/CFNetwork"))) + (ffi-lib + "/System/Library/Frameworks/CFNetwork.framework/CFNetwork" + #:fail (lambda () + ;; Path inside "CoreServices.framework" needed for OS X 10.5 + (ffi-lib "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CFNetwork.framework/CFNetwork"))))) (define-ffi-definer define-cf cf-lib #:default-make-fail make-not-available) From 9a6726b10dd2a5fbd0eec61525edb3d352f7d2d4 Mon Sep 17 00:00:00 2001 From: Gustavo Massaccesi Date: Mon, 4 Jan 2016 21:12:15 -0300 Subject: [PATCH 338/369] sequence-length: more O(1) special cases --- racket/collects/racket/sequence.rkt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/racket/collects/racket/sequence.rkt b/racket/collects/racket/sequence.rkt index 494ade427c..d8d1e26848 100644 --- a/racket/collects/racket/sequence.rkt +++ b/racket/collects/racket/sequence.rkt @@ -2,6 +2,8 @@ (require "stream.rkt" "private/sequence.rkt" + "fixnum.rkt" + "flonum.rkt" racket/contract/combinator racket/contract/base (for-syntax racket/base) @@ -41,8 +43,13 @@ (define (sequence-length s) (unless (sequence? s) (raise-argument-error 'sequence-length "sequence?" s)) - (cond [(list? s) (length s)] + (cond [(exact-nonnegative-integer? s) s] + [(list? s) (length s)] [(vector? s) (vector-length s)] + [(flvector? s) (flvector-length s)] + [(fxvector? s) (fxvector-length s)] + [(string? s) (string-length s)] + [(bytes? s) (bytes-length s)] [(hash? s) (hash-count s)] [else (for/fold ([c 0]) ([i (in-values*-sequence s)]) From 7db904e984f12e9b075f9e7015c351ea7d990ea7 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 7 Jan 2016 06:55:57 -0700 Subject: [PATCH 339/369] net/osx-ssl: fix error handling --- racket/collects/net/osx-ssl.rkt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/racket/collects/net/osx-ssl.rkt b/racket/collects/net/osx-ssl.rkt index b6ca990ca5..2698554ff8 100644 --- a/racket/collects/net/osx-ssl.rkt +++ b/racket/collects/net/osx-ssl.rkt @@ -394,7 +394,7 @@ (cond [(zero? n) (wrap-evt always-evt (lambda (v) #f))] - [(n . < . -1) + [(negative? n) (raise-osx-ssl-network-error 'write-bytes (CFWriteStreamGetError out))] [else n]))] @@ -461,6 +461,7 @@ (close-output-port p))) (define (raise-osx-ssl-network-error who err) - (exn:fail:network - (~a who ": failed " (CFStreamError->list err)) - (current-continuation-marks))) + (raise + (exn:fail:network + (~a who ": failed " (CFStreamError->list err)) + (current-continuation-marks)))) From d04dfb67df29a0699b200c7aacb7baea634c84c3 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 5 Jan 2016 10:07:27 -0600 Subject: [PATCH 340/369] remove stray printf --- pkgs/racket-test/tests/racket/contract/all.rkt | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/racket-test/tests/racket/contract/all.rkt b/pkgs/racket-test/tests/racket/contract/all.rkt index 348f900764..818c02999d 100644 --- a/pkgs/racket-test/tests/racket/contract/all.rkt +++ b/pkgs/racket-test/tests/racket/contract/all.rkt @@ -130,7 +130,6 @@ [(list? exp) (for-each loop exp)] [else (void)])) - (unless deps (printf "no deps ~a\n" file)) deps) (define (dep Date: Wed, 6 Jan 2016 15:37:01 -0600 Subject: [PATCH 341/369] remove extraneous ? --- pkgs/racket-doc/scribblings/reference/contracts.scrbl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index b21ab2794c..25b2aacab6 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -2290,8 +2290,8 @@ the other; both are provided for convenience and clarity. Returns @racket[#t] when @racket[b] does not have both parties. } -@defproc[(blame-add-missing-party? [b (and/c blame? blame-missing-party?)] - [missing-party any/c]) +@defproc[(blame-add-missing-party [b (and/c blame? blame-missing-party?)] + [missing-party any/c]) (and/c blame? (not/c blame-missing-party?))]{ Produces a new blame object like @racket[b], except that the missing party is replaced with @racket[missing-party]. From 578b42fc2bd97c56b1562a4f48b615e1ef2f38ca Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 6 Jan 2016 15:41:27 -0600 Subject: [PATCH 342/369] add docs for contract-late-neg-projection and contract-val-first-projection --- .../scribblings/reference/contracts.scrbl | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index 25b2aacab6..e8a4eb1d10 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -2848,8 +2848,28 @@ Produces the name used to describe the contract in error messages. @history[#:added "6.0.1.12"] } +@defproc[(contract-late-neg-projection [c contract?]) (-> blame? (-> any/c (or/c #f any/c) any/c))]{ + Produces the projection defining a contract's behavior. + + The first argument, @racket[blame?] object encapsulates information about + the contract checking, mostly used to create a meaningful error message if + a contract violation is detected. The resulting function's first argument + is the value that should have the contract and its second argument is + a ``missing party'' from the blame object, to be passed to @racket[raise-contract-error]. + + If possible, use this function instead of @racket[contract-val-first-projection] or + @racket[contract-projection]. +} + + @defproc[(contract-projection [c contract?]) (-> blame? (-> any/c any/c))]{ - Produces the projection defining a contract's behavior on protected values. + Produces the projection defining a contract's behavior. See also + @racket[contract-late-neg-projection]. +} + +@defproc[(contract-val-first-projection [c contract?]) (-> blame? (-> any/c (-> any/c any/c)))]{ + Produces the projection defining a contract's behavior. + See also @racket[contract-late-neg-projection]. } @defproc[(make-none/c [sexp-name any/c]) contract?]{ From c24ddb4a7cb6db7aca3c493189b939e23692ba52 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 7 Jan 2016 09:58:01 -0600 Subject: [PATCH 343/369] improve the way plus-one arity functions fall back when they can't see the application site In particular, instead of going directly back to the chaperone, handle the case where the function doesn't accept keyword arguments with a less expensive fallback. The less expensive fallback uses a case-lambda wrapper (wrapped inside a make-keyword-procedure) to close over the neg-party and avoid the chaperone creation. With this commit, the program below gets about 3x faster, and is only about 20% slower than the version that replaces the "(let ([f f]) ...)" with its body #lang racket/base (module m racket/base (require racket/contract/base) (provide (contract-out [f (-> integer? integer?)])) (define (f x) x)) (require 'm) (collect-garbage) (time (for ([x (in-range 5000000)]) (let ([f f]) (f 1)))) Thanks, @samth! --- .../scribblings/reference/contract-util.rkt | 27 ++++++++++ .../tests/racket/contract/contract-out.rkt | 54 +++++++++++++++++++ .../private/application-arity-checking.rkt | 41 +++++++++++++- .../racket/contract/private/provide.rkt | 42 ++++++++++++--- 4 files changed, 154 insertions(+), 10 deletions(-) create mode 100644 pkgs/racket-doc/scribblings/reference/contract-util.rkt diff --git a/pkgs/racket-doc/scribblings/reference/contract-util.rkt b/pkgs/racket-doc/scribblings/reference/contract-util.rkt new file mode 100644 index 0000000000..ba361b2aba --- /dev/null +++ b/pkgs/racket-doc/scribblings/reference/contract-util.rkt @@ -0,0 +1,27 @@ +#lang racket/base +(require scribble/manual) + +(provide add-use-sources declare-exporting-ctc) + +(define-syntax-rule + (add-use-sources (x y ...)) + (x y ... + #:use-sources + (racket/contract/private/base + racket/contract/private/misc + racket/contract/private/provide + racket/contract/private/guts + racket/contract/private/prop + racket/contract/private/blame + racket/contract/private/ds + racket/contract/private/opt + racket/contract/private/basic-opters + + racket/contract/private/box + racket/contract/private/hash + racket/contract/private/vector + racket/contract/private/struct-dc))) + +(define-syntax-rule + (declare-exporting-ctc mod) + (add-use-sources (declare-exporting mod racket/contract racket))) diff --git a/pkgs/racket-test/tests/racket/contract/contract-out.rkt b/pkgs/racket-test/tests/racket/contract/contract-out.rkt index d995ad3f13..3f467e29f5 100644 --- a/pkgs/racket-test/tests/racket/contract/contract-out.rkt +++ b/pkgs/racket-test/tests/racket/contract/contract-out.rkt @@ -996,6 +996,60 @@ (provide a))) (eval '(dynamic-require ''provide/contract51-m2 'a))) '(1 2 3 4)) + + (test/spec-passed/result + 'provide/contract52 + '(let () + (eval '(module provide/contract52-m1 racket/base + (require racket/contract/base) + (provide (contract-out + [f (->* (integer?) (boolean? char? any/c) any)])) + (define (f x [y #f] [z #\a] [w 0]) (list x y z w)))) + (eval '(module provide/contract52-m2 racket/base + (require 'provide/contract52-m1) + (provide a) + (define a + (let ([f f]) + (list (f 1 #t #\x) + (f 1)))))) + (eval '(dynamic-require ''provide/contract52-m2 'a))) + '((1 #t #\x 0) (1 #f #\a 0))) + + (test/spec-passed/result + 'provide/contract53 + '(let () + (eval '(module provide/contract53-m1 racket/base + (require racket/contract/base) + (provide (contract-out + [f (->* (integer?) (boolean? char? any/c) #:rest any/c any)])) + (define (f x [y #f] [z #\a] [w 0] . rest) (list* x y z w rest)))) + (eval '(module provide/contract53-m2 racket/base + (require 'provide/contract53-m1) + (provide a) + (define a + (let ([f f]) + (list (f 1 #t #\x 11 22 33 44 55 66) + (f 1)))))) + (eval '(dynamic-require ''provide/contract53-m2 'a))) + '((1 #t #\x 11 22 33 44 55 66) (1 #f #\a 0))) + + (test/spec-passed/result + 'provide/contract54 + '(let () + (eval '(module provide/contract54-m1 racket/base + (require racket/contract/base) + (provide (contract-out + [f (->* (#:x integer?) (#:y boolean? #:z char? #:w any/c) any)])) + (define (f #:x x #:y [y #f] #:z [z #\a] #:w [w 0]) (list x y z w)))) + (eval '(module provide/contract54-m2 racket/base + (require 'provide/contract54-m1) + (provide a) + (define a + (let ([f f]) + (list (f #:x 1 #:y #t #:z #\x) + (f #:x 1)))))) + (eval '(dynamic-require ''provide/contract54-m2 'a))) + '((1 #t #\x 0) (1 #f #\a 0))) (contract-error-test 'contract-error-test8 diff --git a/racket/collects/racket/contract/private/application-arity-checking.rkt b/racket/collects/racket/contract/private/application-arity-checking.rkt index f8cf5ec8a9..bc6e651230 100644 --- a/racket/collects/racket/contract/private/application-arity-checking.rkt +++ b/racket/collects/racket/contract/private/application-arity-checking.rkt @@ -1,5 +1,5 @@ #lang racket/base - +(require (for-template racket/base)) #| Used to check an application site of a well-known @@ -13,7 +13,8 @@ a valid-app-shape. |# (provide (struct-out valid-app-shapes) - valid-argument-list?) + valid-argument-list? + generate-medium-speed-wrapper) ;; valid-arities : (or/c (listof nat) (improper-listof nat)) ;; -- if improper, then the last nat indicates that any number @@ -63,6 +64,42 @@ a valid-app-shape. ans?] [else #t])) +;; called in the case that the identifier isn't used directly in an +;; application. Try to generate a case-lambda that can still avoid +;; the chaperone creation +(define (generate-medium-speed-wrapper the-valid-app-shape + chaperone-expr + extra-arg-function + neg-party-id + add-medium-speed-kwd-wrapper-id + expected-name) + (cond + [(and the-valid-app-shape + (null? (valid-app-shapes-mandatory-kwds the-valid-app-shape)) + (null? (valid-app-shapes-optional-kwds the-valid-app-shape))) + (define chaperone-expr-id (car (generate-temporaries '(medium-speed-wrapper)))) + (define (mk-n-ids n) (generate-temporaries (build-list n (λ (x) 'medium-speed-wrapper-arg)))) + (define case-lambda-clauses + (let loop ([valid-arities (valid-app-shapes-valid-arities the-valid-app-shape)]) + (cond + [(null? valid-arities) + (list #`[args (apply #,chaperone-expr-id args)])] + [(number? valid-arities) + (with-syntax ([(x ...) (mk-n-ids valid-arities)] + [(rest-arg) (generate-temporaries '(medium-speed-wrapper-dot-arg))]) + (list + #`[(x ... . rest-arg) (apply #,extra-arg-function #,neg-party-id x ... rest-arg)]))] + [else + (with-syntax ([(x ...) (mk-n-ids (car valid-arities))]) + (cons #`[(x ...) (#,extra-arg-function #,neg-party-id x ...)] + (loop (cdr valid-arities))))]))) + #`(let ([#,chaperone-expr-id #,chaperone-expr]) + (#,add-medium-speed-kwd-wrapper-id + #,chaperone-expr-id + (let ([#,expected-name (case-lambda #,@case-lambda-clauses)]) + #,expected-name)))] + [else chaperone-expr])) + (define-logger optimizer) (define (log-problem stx) (log-optimizer-warning diff --git a/racket/collects/racket/contract/private/provide.rkt b/racket/collects/racket/contract/private/provide.rkt index 066c37d0f9..1469936117 100644 --- a/racket/collects/racket/contract/private/provide.rkt +++ b/racket/collects/racket/contract/private/provide.rkt @@ -88,7 +88,8 @@ (saved-ho-id-table partially-applied-id extra-neg-party-argument-fn - valid-argument-lists) + valid-argument-lists + ex-id) #:property prop:set!-transformer (λ (self stx) @@ -96,8 +97,9 @@ [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)] - [valid-arg-lists (provide/contract-arrow-transformer-valid-argument-lists self)] - [rename-id (provide/contract-info-rename-id self)]) + [the-valid-arg-shapes (provide/contract-arrow-transformer-valid-argument-lists self)] + [rename-id (provide/contract-info-rename-id self)] + [ex-id (provide/contract-arrow-transformer-ex-id self)]) (with-syntax ([partially-applied-id partially-applied-id] [extra-neg-party-argument-fn extra-neg-party-argument-fn]) (if (eq? 'expression (syntax-local-context)) @@ -124,7 +126,15 @@ (add-rename-id rename-id (syntax-local-lift-expression (add-lifted-property - #'(partially-applied-id lifted-neg-party)))))))) + (generate-medium-speed-wrapper + the-valid-arg-shapes + #'(partially-applied-id lifted-neg-party) + (add-neg-party (add-rename-id + rename-id + #'extra-neg-party-argument-fn)) + #'lifted-neg-party + #'add-medium-speed-kwd-wrapper + ex-id)))))))) (when key (hash-set! saved-ho-id-table key lifted-ctc-val)) (adjust-location (syntax-local-introduce lifted-ctc-val))) (syntax-case stx (set!) @@ -138,7 +148,7 @@ stx #'id)] [(name more ...) (with-syntax ([app (datum->syntax stx '#%app)]) - (if (valid-argument-list? stx valid-arg-lists) + (if (valid-argument-list? stx the-valid-arg-shapes) (with-syntax ([lifted-neg-party (syntax-local-introduce lifted-neg-party)]) (adjust-location #`(app #,(add-neg-party (add-rename-id @@ -209,12 +219,27 @@ #`(app #,id args ...))] [x (identifier? #'x) id]))))) - (define (make-provide/contract-arrow-transformer rename-id contract-id id pai enpfn val) + (define (make-provide/contract-arrow-transformer rename-id contract-id id pai enpfn val ex-id) (provide/contract-arrow-transformer rename-id contract-id id (make-hasheq) - pai enpfn val))) + pai enpfn val ex-id))) +(define (add-medium-speed-kwd-wrapper chapone-contracted-proc no-keywords-path) + (make-keyword-procedure + (λ (kwds kwd-args . args) + (keyword-apply chapone-contracted-proc kwds kwd-args args)) + no-keywords-path)) + +(define-syntax (maybe-add-name stx) + (syntax-case stx () + [(_ expr) + (let () + (define name (syntax-local-name)) + (printf "name! ~s\n" name) + (if (symbol? name) + #`(let ([#,name expr]) #,name) + #'expr))])) ;; tl-code-for-one-id/new-name : syntax syntax syntax (union syntax #f) -> (values syntax syntax) ;; given the syntax for an identifier and a contract, @@ -317,7 +342,8 @@ (quote-syntax contract-id) (quote-syntax id) (quote-syntax partially-applied-id) (quote-syntax extra-neg-party-argument-fn) - #,the-valid-app-shapes) + #,the-valid-app-shapes + '#,ex-id) #`(make-provide/contract-transformer (quote-syntax #,id-rename) (quote-syntax contract-id) (quote-syntax id) From 3e53a3ea42479be76fafbb8a6e3f0fa3f79a17bb Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 7 Jan 2016 12:57:46 -0600 Subject: [PATCH 344/369] make impersonator vector contracts use impersonate-vector, not chaperone-vector closes #1198 --- pkgs/racket-test/tests/racket/contract/vector.rkt | 15 +++++++++++++-- .../collects/racket/contract/private/vector.rkt | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-test/tests/racket/contract/vector.rkt b/pkgs/racket-test/tests/racket/contract/vector.rkt index cc61440459..5d169532fe 100644 --- a/pkgs/racket-test/tests/racket/contract/vector.rkt +++ b/pkgs/racket-test/tests/racket/contract/vector.rkt @@ -1,7 +1,8 @@ #lang racket/base (require "test-util.rkt") (parameterize ([current-contract-namespace - (make-basic-contract-namespace)]) + (make-basic-contract-namespace + 'racket/contract/combinator)]) (test/spec-passed 'vectorof1 @@ -137,4 +138,14 @@ '(let ([x (vector-immutable 1 2 3)]) (eq? (contract (vectorof integer?) x 'pos 'neg) x)) - '#true)) + '#true) + + (test/spec-passed/result + 'vector/c-impersonator + '(vector-ref (contract (vectorof (make-contract #:late-neg-projection (λ (b) (λ (x n) (+ x 1))))) + (vector 0) + 'pos 'neg) + 0) + 1) + + ) diff --git a/racket/collects/racket/contract/private/vector.rkt b/racket/collects/racket/contract/private/vector.rkt index 9cc5eb8442..f0bcf66865 100644 --- a/racket/collects/racket/contract/private/vector.rkt +++ b/racket/collects/racket/contract/private/vector.rkt @@ -218,7 +218,7 @@ #:name vectorof-name #:first-order vectorof-first-order #:stronger vectorof-stronger - #:late-neg-projection (vectorof-late-neg-ho-projection chaperone-vector))) + #:late-neg-projection (vectorof-late-neg-ho-projection impersonate-vector))) (define-syntax (wrap-vectorof stx) (syntax-case stx () From 666c5f1557703ed24272387f9272321ded2ecf7f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 7 Jan 2016 15:47:08 -0700 Subject: [PATCH 345/369] Windows code-signing and ".tgz" options for distro-build --- INSTALL.txt | 12 ++++++++++-- Makefile | 21 +++++++++++++++------ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/INSTALL.txt b/INSTALL.txt index 3654772566..e7da5d0243 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -514,12 +514,20 @@ In more detail: `make'. The `README' value is used as a file name to download from the server. - For a Mac OS X installer, set `SIGN_IDENTITY' to sign the - installer, where the value of `SIGN_IDENTITY' is the name to + To create a ".tgz" archive instead of an installer (or any + platform), set `TGZ_MODE' to "--tgz". + + For a Mac OS X installer, set `SIGN_IDENTITY' as the name to which the signing certificate is associated. Set `MAC_PKG_MODE' to "--mac-pkg" to create a ".pkg" installer instead of a ".dmg" image. + For a Windows installer, set `OSSLSIGNCODE_ARGS_BASE64` as a + Base64 encoding of an S-expression for a list of argument strings + for `osslsigncode`. The `-n', `-t', `-in', and `-out' arguments + are provided to `osslsigncode` automatically, so supply the + others. + The `SERVER_CATALOG_PATH' and `SERVER_COLLECTS_PATH' makefile variables specify paths at `SERVER' plus `SERVER_PORT' to access the package catalog and pre-built "collects" tree needed for a diff --git a/Makefile b/Makefile index 50e6312fd5..550ec36e1d 100644 --- a/Makefile +++ b/Makefile @@ -234,6 +234,9 @@ VERSIONLESS_MODE = # instead of a ".dmg" for drag-and-drop installation: MAC_PKG_MODE = +# Set to "--tgz" to create a ".tgz" archive instead of an installer: +TGZ_MODE = + # Set to "--source --no-setup" to include packages in an installer # (or archive) only in source form: PKG_SOURCE_MODE = @@ -264,10 +267,14 @@ BUILD_STAMP = # the default as the version number: INSTALL_NAME = -# A signing identity (spaces allowed) for Mac OS X binaries in an +# For Mac OS X, a signing identity (spaces allowed) for binaries in an # installer: SIGN_IDENTITY = +# For Windows, `osslsigncode' arguments other than `-n', `-t', `-in', +# and `-out' as a Base64-encoded, S-expression, list of strings: +OSSLSIGNCODE_ARGS_BASE64 = + # URL for a README file to include in an installer (empty for none, # spaces allowed): README = http://$(SVR_PRT)/README.txt @@ -443,11 +450,12 @@ PROP_ARGS = SERVER=$(SERVER) SERVER_PORT=$(SERVER_PORT) SERVER_HOSTS="$(SERVER_H 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)"\ + PKG_SOURCE_MODE="$(PKG_SOURCE_MODE)" INSTALL_NAME="$(INSTALL_NAME)" \ DIST_NAME="$(DIST_NAME)" DIST_BASE=$(DIST_BASE) \ DIST_DIR=$(DIST_DIR) DIST_SUFFIX=$(DIST_SUFFIX) UPLOAD="$(UPLOAD)" \ - DIST_DESC="$(DIST_DESC)" README="$(README)" SIGN_IDENTITY="$(SIGN_IDENTITY)"\ - JOB_OPTIONS="$(JOB_OPTIONS)" + DIST_DESC="$(DIST_DESC)" README="$(README)" SIGN_IDENTITY="$(SIGN_IDENTITY)" \ + OSSLSIGNCODE_ARGS_BASE64="$(OSSLSIGNCODE_ARGS_BASE64)" JOB_OPTIONS="$(JOB_OPTIONS)" \ + TGZ_MODE=$(TGZ_MODE) COPY_ARGS = $(PROP_ARGS) \ SERVER_CATALOG_PATH=$(SERVER_CATALOG_PATH) SERVER_COLLECTS_PATH=$(SERVER_COLLECTS_PATH) @@ -496,9 +504,10 @@ bundle-from-server: $(RACKET) -l setup/unixstyle-install post-adjust "$(SOURCE_MODE)" "$(PKG_SOURCE_MODE)" racket 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) \ +DIST_ARGS_q = $(UPLOAD_q) $(RELEASE_MODE) $(SOURCE_MODE) $(VERSIONLESS_MODE) \ + $(MAC_PKG_MODE) $(TGZ_MODE) \ "$(DIST_NAME)" $(DIST_BASE) $(DIST_DIR) "$(DIST_SUFFIX)" \ - "$(SIGN_IDENTITY)" + "$(SIGN_IDENTITY)" "$(OSSLSIGNCODE_ARGS_BASE64)" # Create an installer from the build (with installed packages) that's # in "bundle/racket": From 393d72f153af0f826183b763d2f5d1e4e7d89c6a Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 7 Jan 2016 22:12:27 -0600 Subject: [PATCH 346/369] add test case that makes sure we preserve chaperone-of for contract-out functions --- .../tests/racket/contract/contract-out.rkt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pkgs/racket-test/tests/racket/contract/contract-out.rkt b/pkgs/racket-test/tests/racket/contract/contract-out.rkt index 3f467e29f5..19d0382670 100644 --- a/pkgs/racket-test/tests/racket/contract/contract-out.rkt +++ b/pkgs/racket-test/tests/racket/contract/contract-out.rkt @@ -1050,6 +1050,24 @@ (f #:x 1)))))) (eval '(dynamic-require ''provide/contract54-m2 'a))) '((1 #t #\x 0) (1 #f #\a 0))) + + (test/spec-passed/result + 'provide/contract55 + '(let () + (eval '(module provide/contract55-m1 racket/base + (require racket/contract/base) + (provide + (contract-out + [an-s s?] + [s-x (-> s? integer?)])) + (struct s (x)) + (define an-s (s 5)))) + (eval '(module provide/contract55-m2 racket/base + (require 'provide/contract55-m1) + (provide a) + (define a (s-x (chaperone-struct an-s s-x (λ (s x) x)))))) + (eval '(dynamic-require ''provide/contract55-m2 'a))) + '5) (contract-error-test 'contract-error-test8 From 32a79a22ec9b9cececf41195faed9eed68757bee Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 7 Jan 2016 22:13:38 -0600 Subject: [PATCH 347/369] Revert "improve the way plus-one arity functions fall back when they can't see the application site" This reverts commit c24ddb4a7cb6db7aca3c493189b939e23692ba52. This optimization was bogus, as shown by the test case in 393d72f153 (Thanks to Sam again for the test case.) --- .../scribblings/reference/contract-util.rkt | 27 ------------ .../private/application-arity-checking.rkt | 41 +----------------- .../racket/contract/private/provide.rkt | 42 ++++--------------- 3 files changed, 10 insertions(+), 100 deletions(-) delete mode 100644 pkgs/racket-doc/scribblings/reference/contract-util.rkt diff --git a/pkgs/racket-doc/scribblings/reference/contract-util.rkt b/pkgs/racket-doc/scribblings/reference/contract-util.rkt deleted file mode 100644 index ba361b2aba..0000000000 --- a/pkgs/racket-doc/scribblings/reference/contract-util.rkt +++ /dev/null @@ -1,27 +0,0 @@ -#lang racket/base -(require scribble/manual) - -(provide add-use-sources declare-exporting-ctc) - -(define-syntax-rule - (add-use-sources (x y ...)) - (x y ... - #:use-sources - (racket/contract/private/base - racket/contract/private/misc - racket/contract/private/provide - racket/contract/private/guts - racket/contract/private/prop - racket/contract/private/blame - racket/contract/private/ds - racket/contract/private/opt - racket/contract/private/basic-opters - - racket/contract/private/box - racket/contract/private/hash - racket/contract/private/vector - racket/contract/private/struct-dc))) - -(define-syntax-rule - (declare-exporting-ctc mod) - (add-use-sources (declare-exporting mod racket/contract racket))) diff --git a/racket/collects/racket/contract/private/application-arity-checking.rkt b/racket/collects/racket/contract/private/application-arity-checking.rkt index bc6e651230..f8cf5ec8a9 100644 --- a/racket/collects/racket/contract/private/application-arity-checking.rkt +++ b/racket/collects/racket/contract/private/application-arity-checking.rkt @@ -1,5 +1,5 @@ #lang racket/base -(require (for-template racket/base)) + #| Used to check an application site of a well-known @@ -13,8 +13,7 @@ a valid-app-shape. |# (provide (struct-out valid-app-shapes) - valid-argument-list? - generate-medium-speed-wrapper) + valid-argument-list?) ;; valid-arities : (or/c (listof nat) (improper-listof nat)) ;; -- if improper, then the last nat indicates that any number @@ -64,42 +63,6 @@ a valid-app-shape. ans?] [else #t])) -;; called in the case that the identifier isn't used directly in an -;; application. Try to generate a case-lambda that can still avoid -;; the chaperone creation -(define (generate-medium-speed-wrapper the-valid-app-shape - chaperone-expr - extra-arg-function - neg-party-id - add-medium-speed-kwd-wrapper-id - expected-name) - (cond - [(and the-valid-app-shape - (null? (valid-app-shapes-mandatory-kwds the-valid-app-shape)) - (null? (valid-app-shapes-optional-kwds the-valid-app-shape))) - (define chaperone-expr-id (car (generate-temporaries '(medium-speed-wrapper)))) - (define (mk-n-ids n) (generate-temporaries (build-list n (λ (x) 'medium-speed-wrapper-arg)))) - (define case-lambda-clauses - (let loop ([valid-arities (valid-app-shapes-valid-arities the-valid-app-shape)]) - (cond - [(null? valid-arities) - (list #`[args (apply #,chaperone-expr-id args)])] - [(number? valid-arities) - (with-syntax ([(x ...) (mk-n-ids valid-arities)] - [(rest-arg) (generate-temporaries '(medium-speed-wrapper-dot-arg))]) - (list - #`[(x ... . rest-arg) (apply #,extra-arg-function #,neg-party-id x ... rest-arg)]))] - [else - (with-syntax ([(x ...) (mk-n-ids (car valid-arities))]) - (cons #`[(x ...) (#,extra-arg-function #,neg-party-id x ...)] - (loop (cdr valid-arities))))]))) - #`(let ([#,chaperone-expr-id #,chaperone-expr]) - (#,add-medium-speed-kwd-wrapper-id - #,chaperone-expr-id - (let ([#,expected-name (case-lambda #,@case-lambda-clauses)]) - #,expected-name)))] - [else chaperone-expr])) - (define-logger optimizer) (define (log-problem stx) (log-optimizer-warning diff --git a/racket/collects/racket/contract/private/provide.rkt b/racket/collects/racket/contract/private/provide.rkt index 1469936117..066c37d0f9 100644 --- a/racket/collects/racket/contract/private/provide.rkt +++ b/racket/collects/racket/contract/private/provide.rkt @@ -88,8 +88,7 @@ (saved-ho-id-table partially-applied-id extra-neg-party-argument-fn - valid-argument-lists - ex-id) + valid-argument-lists) #:property prop:set!-transformer (λ (self stx) @@ -97,9 +96,8 @@ [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)] - [the-valid-arg-shapes (provide/contract-arrow-transformer-valid-argument-lists self)] - [rename-id (provide/contract-info-rename-id self)] - [ex-id (provide/contract-arrow-transformer-ex-id self)]) + [valid-arg-lists (provide/contract-arrow-transformer-valid-argument-lists self)] + [rename-id (provide/contract-info-rename-id self)]) (with-syntax ([partially-applied-id partially-applied-id] [extra-neg-party-argument-fn extra-neg-party-argument-fn]) (if (eq? 'expression (syntax-local-context)) @@ -126,15 +124,7 @@ (add-rename-id rename-id (syntax-local-lift-expression (add-lifted-property - (generate-medium-speed-wrapper - the-valid-arg-shapes - #'(partially-applied-id lifted-neg-party) - (add-neg-party (add-rename-id - rename-id - #'extra-neg-party-argument-fn)) - #'lifted-neg-party - #'add-medium-speed-kwd-wrapper - ex-id)))))))) + #'(partially-applied-id lifted-neg-party)))))))) (when key (hash-set! saved-ho-id-table key lifted-ctc-val)) (adjust-location (syntax-local-introduce lifted-ctc-val))) (syntax-case stx (set!) @@ -148,7 +138,7 @@ stx #'id)] [(name more ...) (with-syntax ([app (datum->syntax stx '#%app)]) - (if (valid-argument-list? stx the-valid-arg-shapes) + (if (valid-argument-list? stx valid-arg-lists) (with-syntax ([lifted-neg-party (syntax-local-introduce lifted-neg-party)]) (adjust-location #`(app #,(add-neg-party (add-rename-id @@ -219,27 +209,12 @@ #`(app #,id args ...))] [x (identifier? #'x) id]))))) - (define (make-provide/contract-arrow-transformer rename-id contract-id id pai enpfn val ex-id) + (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) - pai enpfn val ex-id))) + pai enpfn val))) -(define (add-medium-speed-kwd-wrapper chapone-contracted-proc no-keywords-path) - (make-keyword-procedure - (λ (kwds kwd-args . args) - (keyword-apply chapone-contracted-proc kwds kwd-args args)) - no-keywords-path)) - -(define-syntax (maybe-add-name stx) - (syntax-case stx () - [(_ expr) - (let () - (define name (syntax-local-name)) - (printf "name! ~s\n" name) - (if (symbol? name) - #`(let ([#,name expr]) #,name) - #'expr))])) ;; tl-code-for-one-id/new-name : syntax syntax syntax (union syntax #f) -> (values syntax syntax) ;; given the syntax for an identifier and a contract, @@ -342,8 +317,7 @@ (quote-syntax contract-id) (quote-syntax id) (quote-syntax partially-applied-id) (quote-syntax extra-neg-party-argument-fn) - #,the-valid-app-shapes - '#,ex-id) + #,the-valid-app-shapes) #`(make-provide/contract-transformer (quote-syntax #,id-rename) (quote-syntax contract-id) (quote-syntax id) From 3c496777efe68311874f6ae938d53aac2f2437d9 Mon Sep 17 00:00:00 2001 From: Ben Greenman Date: Mon, 21 Dec 2015 10:58:29 -0500 Subject: [PATCH 348/369] add 'combinations' and 'in-combinations' --- .../scribblings/reference/pairs.scrbl | 25 ++++++ pkgs/racket-test-core/tests/racket/list.rktl | 36 +++++++++ racket/collects/racket/list.rkt | 80 +++++++++++++++++++ 3 files changed, 141 insertions(+) diff --git a/pkgs/racket-doc/scribblings/reference/pairs.scrbl b/pkgs/racket-doc/scribblings/reference/pairs.scrbl index a39319377d..bad5ca7aa5 100644 --- a/pkgs/racket-doc/scribblings/reference/pairs.scrbl +++ b/pkgs/racket-doc/scribblings/reference/pairs.scrbl @@ -1252,9 +1252,34 @@ returns @racket[#f]. Returns a list with all elements from @racket[lst], randomly shuffled. @mz-examples[#:eval list-eval + (shuffle '(1 2 3 4 5 6)) + (shuffle '(1 2 3 4 5 6)) (shuffle '(1 2 3 4 5 6))]} +@defproc*[([(combinations [lst list?]) list?] + [(combinations [lst list?] [size exact-nonnegative-integer?]) list?])]{ +@margin-note{Wikipedia @hyperlink["https://en.wikipedia.org/wiki/Combination"]{combinations}} +Return a list of all combinations of elements in the input list +(aka the @index["powerset"]{powerset} of @racket[lst]). +If @racket[size] is given, limit results to combinations of @racket[size] elements. + +@mz-examples[#:eval list-eval + (combinations '(1 2 3)) + (combinations '(1 2 3) 2)]} + + +@defproc*[([(in-combinations [lst list?]) list?] + [(in-combinations [lst list?] [size exact-nonnegative-integer?]) sequence?])]{ +@index["in-powerset"]{Returns} a sequence of all combinations of elements in the input list, + or all combinations of length @racket[size] if @racket[size] is given. +Builds combinations one-by-one instead of all at once. + +@mz-examples[#:eval list-eval + (time (begin (combinations (range 15)) (void))) + (time (begin (in-combinations (range 15)) (void)))]} + + @defproc[(permutations [lst list?]) list?]{ diff --git a/pkgs/racket-test-core/tests/racket/list.rktl b/pkgs/racket-test-core/tests/racket/list.rktl index cc185354c4..51eb4b4452 100644 --- a/pkgs/racket-test-core/tests/racket/list.rktl +++ b/pkgs/racket-test-core/tests/racket/list.rktl @@ -422,6 +422,42 @@ (test expected length+sum (shuffle l))) (when (pair? l) (loop (cdr l)))) +;; ---------- combinations ---------- +(let () + (define (comblist a)) +(define (combinations l [k #f]) + (for/list ([x (in-combinations l k)]) x)) + +;; Generate combinations of the list `l`. +;; - If `k` is a natural number, generate all combinations of size `k`. +;; - If `k` is #f, generate all combinations of any size (powerset of `l`). +(define (in-combinations l [k #f]) + (unless (list? l) + (raise-argument-error 'in-combinations "list?" 0 l)) + (when (and k (not (exact-nonnegative-integer? k))) + (raise-argument-error 'in-combinations "exact-nonnegative-integer?" 1 k)) + (define v (list->vector l)) + (define N (vector-length v)) + (define N-1 (- N 1)) + (define gen-combinations + (cond + [(not k) + ;; Enumerate all binary numbers [1..2**N]. + ;; Produce the combination with elements in `v` at the same + ;; positions as the 1's in the binary number. + (define limit (expt 2 N)) + (define curr-box (box 0)) + (lambda () + (let ([curr (unbox curr-box)]) + (if (< curr limit) + (begin0 + (for/fold ([acc '()]) + ([i (in-range N-1 -1 -1)]) + (if (bitwise-bit-set? curr i) + (cons (vector-ref v i) acc) + acc)) + (set-box! curr-box (+ curr 1))) + #f)))] + [(< N k) + (lambda () #f)] + [else + ;; Keep a vector `k*` that contains `k` indices + ;; Use `k*` to generate combinations + (define k* #f) ; (U #f (Vectorof Index)) + (define k-1 (- k 1)) + ;; `k*-incr` tries to increment the positions in `k*`. + ;; On success, can use `k*` to build a combination. + ;; Returns #f on failure. + (define (k*-incr) + (cond + [(not k*) + ;; 1. Initialize the vector `k*` to the first {0..k-1} indices + (set! k* (build-vector k (lambda (i) i)))] + [(zero? k) + ;; (Cannot increment a zero vector) + #f] + [else + (or + ;; 2. Try incrementing the leftmost index that is + ;; at least 2 less than the following index in `k*`. + (for/or ([i (in-range 0 k-1)]) + (let ([k*_i (vector-ref k* i)] + [k*_i+1 (vector-ref k* (+ i 1))]) + (and (< k*_i (- k*_i+1 1)) + (vector-set! k* i (+ k*_i 1))))) + ;; 3. Increment the rightmost index, up to a max of `N-1`. + ;; Also replace the first `k-1` indices to `[0..k-2]` + (let ([k*_last (vector-ref k* k-1)]) + (if (< k*_last N-1) + (begin + (vector-set! k* k-1 (+ k*_last 1)) + (for ([i (in-range k-1)]) + (vector-set! k* i i))) + #f)))])) + (define (k*->combination) + ;; Get the `k` elements indexed by `k*` + (for/fold ([acc '()]) + ([i (in-range k-1 -1 -1)]) + (cons (vector-ref v (vector-ref k* i)) acc))) + (lambda () + (and (k*-incr) (k*->combination)))])) + (in-producer gen-combinations #f)) + ;; This implements an algorithm known as "Ord-Smith". (It is described in a ;; paper called "Permutation Generation Methods" by Robert Sedgewlck, listed as ;; Algorithm 8.) It has a number of good properties: it is very fast, returns From b078cbc0ef449663b6d468321d59289bf95b3bbd Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Fri, 8 Jan 2016 11:02:05 -0500 Subject: [PATCH 349/369] Add define-rename-transformer-parameter and friends --- pkgs/base/info.rkt | 2 +- .../scribblings/reference/stx-param.scrbl | 28 +++++++++++++ .../scribblings/reference/stx-trans.scrbl | 10 +++-- .../scribblings/reference/syntax.scrbl | 4 +- .../tests/racket/stxparam.rktl | 18 ++++++++ racket/collects/racket/private/stxparam.rkt | 32 +++++++++++---- .../collects/racket/private/stxparamkey.rkt | 41 ++++++++++++++++--- racket/collects/racket/stxparam.rkt | 33 ++++++++++----- racket/src/racket/src/schvers.h | 4 +- 9 files changed, 139 insertions(+), 33 deletions(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index f0155438f0..3212dd1af8 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.3.0.13") +(define version "6.3.0.14") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/pkgs/racket-doc/scribblings/reference/stx-param.scrbl b/pkgs/racket-doc/scribblings/reference/stx-param.scrbl index d6ae7ab106..047e00384b 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-param.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-param.scrbl @@ -79,6 +79,34 @@ the target's value. (if t then else)))])) ]} +@defform[(define-rename-transformer-parameter id expr)]{ + +Binds @racket[id] as syntax to a @tech{syntax parameter} that must +be bound to a @racket[make-rename-transformer] result and, unlike +@racket[define-syntax-parameter], @racket[syntax-local-value] of +@racket[id] @emph{does} produce the target's value, including inside +of @racket[syntax-parameterize]. + +@examples[#:eval the-eval #:escape UNSYNTAX + (define-syntax (test stx) + (syntax-case stx () + [(_ t) + #`#,(syntax-local-value #'t)])) + (define-syntax one 1) + (define-syntax two 2) + (define-syntax-parameter not-num + (make-rename-transformer #'one)) + (test not-num) + + (define-rename-transformer-parameter num + (make-rename-transformer #'one)) + (test num) + (syntax-parameterize ([num (make-rename-transformer #'two)]) + (test num)) +] + +@history[#:added "6.3.0.14"]} + @; ---------------------------------------------------------------------- @section{Syntax Parameter Inspection} diff --git a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl index ae05333533..6e9de282cf 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl @@ -198,10 +198,12 @@ 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. -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. +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. The returned identifier +should probably have the @racket['not-free-identifier=?] syntax +property. 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") diff --git a/pkgs/racket-doc/scribblings/reference/syntax.scrbl b/pkgs/racket-doc/scribblings/reference/syntax.scrbl index 9e2a88413b..fde18939ba 100644 --- a/pkgs/racket-doc/scribblings/reference/syntax.scrbl +++ b/pkgs/racket-doc/scribblings/reference/syntax.scrbl @@ -2926,8 +2926,8 @@ Similar to @racket[quote], but produces a @tech{syntax object} that preserves the @tech{lexical information} and source-location information attached to @racket[datum] at expansion time. -When @racket[#:local] is specified, than all @tech{scopes} in the -syntax object's @tech{lexical information} is preserved. When +When @racket[#:local] is specified, then all @tech{scopes} in the +syntax object's @tech{lexical information} are preserved. When @racket[#:local] is omitted, then the @tech{scope sets} within @racket[datum] are pruned to omit the @tech{scope} for any binding form that appears between the @racket[quote-syntax] form and the diff --git a/pkgs/racket-test-core/tests/racket/stxparam.rktl b/pkgs/racket-test-core/tests/racket/stxparam.rktl index 317614f3b8..b8daa79546 100644 --- a/pkgs/racket-test-core/tests/racket/stxparam.rktl +++ b/pkgs/racket-test-core/tests/racket/stxparam.rktl @@ -132,5 +132,23 @@ ;; ---------------------------------------- +(let () + (define-syntax (slv stx) + (syntax-case stx () + [(_ t) + #`#,(syntax-local-value #'t)])) + (define-syntax one 1) + (define-syntax two 2) + (define-rename-transformer-parameter num + (make-rename-transformer #'one)) + (test #t = (slv num) 1) + (syntax-parameterize ([num (make-rename-transformer #'two)]) + (test #t = (slv num) 2)) + (splicing-syntax-parameterize ([num (make-rename-transformer #'two)]) + (define too (slv num))) + (test #t = too 2)) + +;; ---------------------------------------- + (report-errs) diff --git a/racket/collects/racket/private/stxparam.rkt b/racket/collects/racket/private/stxparam.rkt index f9af1c8e9b..6fed01c96e 100644 --- a/racket/collects/racket/private/stxparam.rkt +++ b/racket/collects/racket/private/stxparam.rkt @@ -12,7 +12,7 @@ (syntax-case stx () [(_ ([id val] ...) body ...) (let ([ids (syntax->list #'(id ...))]) - (with-syntax ([(gen-id ...) + (with-syntax ([((gen-id must-be-renamer?) ...) (map (lambda (id) (unless (identifier? id) (raise-syntax-error @@ -20,19 +20,29 @@ "not an identifier" stx id)) - (let* ([rt (syntax-local-value id (lambda () #f))] - [sp (if (set!-transformer? rt) - (set!-transformer-procedure rt) - rt)]) + (let*-values + ;; If it is a rename-transformer-parameter, then + ;; we need to get the parameter and not what it + ;; points to, otherwise, we can keep going. + ([(rt* rt-target) + (syntax-local-value/immediate id (lambda () #f))] + [(rt) (if (syntax-parameter? rt*) + rt* + (or rt-target rt*))] + [(sp) (if (set!-transformer? rt) + (set!-transformer-procedure rt) + rt)]) (unless (syntax-parameter? sp) (raise-syntax-error #f "not bound as a syntax parameter" stx id)) - (syntax-local-get-shadower - (syntax-local-introduce (syntax-parameter-target sp)) - #t))) + (list + (syntax-local-get-shadower + (syntax-local-introduce (syntax-parameter-target sp)) + #t) + (rename-transformer-parameter? sp)))) ids)]) (let ([dup (check-duplicate-identifier ids)]) (when dup @@ -52,6 +62,10 @@ (list ids) #'())]) (syntax/loc stx - (let-syntaxes ([(gen-id) (convert-renamer val)] ...) + (let-syntaxes ([(gen-id) + (convert-renamer + (if must-be-renamer? (quote-syntax val) #f) + val)] + ...) orig ... body ...)))))]))) diff --git a/racket/collects/racket/private/stxparamkey.rkt b/racket/collects/racket/private/stxparamkey.rkt index 14884d6443..8a597dfbfe 100644 --- a/racket/collects/racket/private/stxparamkey.rkt +++ b/racket/collects/racket/private/stxparamkey.rkt @@ -4,10 +4,34 @@ "stxcase.rkt" "stxloc.rkt" "with-stx.rkt") (-define-struct wrapped-renamer (renamer)) - (-define-struct parameter-binding (val param)) + + (define-values (struct:parameter-binding make-parameter-binding parameter-binding? parameter-binding-ref parameter-binding-set!) + (make-struct-type 'parameter-binding #f 2 0 #f null (current-inspector) #f '(0 1))) + (define parameter-binding-val (make-struct-field-accessor parameter-binding-ref 0)) + (define parameter-binding-param (make-struct-field-accessor parameter-binding-ref 1)) + + (define (parameter-binding-rt-target pbr) + (rename-transformer-target (wrapped-renamer-renamer (parameter-binding-val pbr)))) + (define-values (struct:parameter-binding-rt make-parameter-binding-rt parameter-binding-rt? parameter-binding-rt-ref parameter-binding-rt-set!) + (make-struct-type 'parameter-binding-rt struct:parameter-binding 0 0 #f (list (cons prop:rename-transformer parameter-binding-rt-target)) (current-inspector) #f)) + (define-values (struct:syntax-parameter make-syntax-parameter syntax-parameter? syntax-parameter-ref syntax-parameter-set!) - (make-struct-type 'syntax-parameter #f 2 0 #f null (current-inspector) 0)) + (make-struct-type 'syntax-parameter #f 2 0 #f null (current-inspector) 0 '(0 1))) + + (define (rename-transformer-parameter-target rtp) + (define t (syntax-parameter-target rtp)) + ;; XXX (syntax-transforming?) is not always true when the + ;; prop:rename-transformer procedure is evaluated. I think this is + ;; because it used to test rename-transformer? + (define lt + (if (syntax-transforming?) + (syntax-local-get-shadower t #t) + t)) + (syntax-property lt 'not-free-identifier=? #t)) + + (define-values (struct:rename-transformer-parameter make-rename-transformer-parameter rename-transformer-parameter? rename-transformer-parameter-ref rename-transformer-parameter-set!) + (make-struct-type 'rename-transformer-parameter struct:syntax-parameter 0 0 #f (list (cons prop:rename-transformer rename-transformer-parameter-target)) (current-inspector) #f)) (define (syntax-parameter-target sp) (syntax-parameter-ref sp 1)) @@ -36,12 +60,17 @@ (let ([v (target-value target)]) (parameter-binding-param v))) - (define (convert-renamer v) - (make-parameter-binding + (define (convert-renamer must-be-renamer?-stx v) + (when must-be-renamer?-stx + (unless (rename-transformer? v) + (raise-syntax-error #f "rename-transformer-parameter must be bound to rename-transformer" must-be-renamer?-stx))) + ((if must-be-renamer?-stx + make-parameter-binding-rt + make-parameter-binding) (if (rename-transformer? v) (make-wrapped-renamer v) v) - ;; comile-time parameter needed for `splicing-syntax-parameterize': + ;; compile-time parameter needed for `splicing-syntax-parameterize': (make-parameter #f))) (define (apply-transformer v stx set!-stx) @@ -84,6 +113,8 @@ apply-transformer syntax-parameter? make-syntax-parameter + rename-transformer-parameter? + make-rename-transformer-parameter syntax-parameter-target syntax-parameter-target-value syntax-parameter-target-parameter)) diff --git a/racket/collects/racket/stxparam.rkt b/racket/collects/racket/stxparam.rkt index ab198b4f06..cf3c561a07 100644 --- a/racket/collects/racket/stxparam.rkt +++ b/racket/collects/racket/stxparam.rkt @@ -10,6 +10,7 @@ "private/stxloc.rkt" "private/stxparamkey.rkt")) (#%provide define-syntax-parameter + define-rename-transformer-parameter syntax-parameterize (for-syntax syntax-parameter-value make-parameter-rename-transformer)) @@ -18,16 +19,28 @@ (syntax-case stx () [(_ id init-val) (with-syntax ([gen-id (car (generate-temporaries (list #'id)))]) - #'(begin - (define-syntax gen-id (convert-renamer init-val)) - (define-syntax id - (let ([gen-id #'gen-id]) - (make-set!-transformer - (make-syntax-parameter - (lambda (stx) - (let ([v (syntax-parameter-target-value gen-id)]) - (apply-transformer v stx #'set!))) - gen-id))))))])) + #'(begin + (define-syntax gen-id (convert-renamer #f init-val)) + (define-syntax id + (let ([gen-id #'gen-id]) + (make-set!-transformer + (make-syntax-parameter + (lambda (stx) + (let ([v (syntax-parameter-target-value gen-id)]) + (apply-transformer v stx #'set!))) + gen-id))))))])) + + (define-syntax (define-rename-transformer-parameter stx) + (syntax-case stx () + [(_ id init-val) + (with-syntax ([gen-id (car (generate-temporaries (list #'id)))]) + #'(begin + (define-syntax gen-id (convert-renamer #'init-val init-val)) + (define-syntax id + (let ([gen-id #'gen-id]) + (make-rename-transformer-parameter + #f + gen-id)))))])) (define-syntax (syntax-parameterize stx) (do-syntax-parameterize stx #'let-syntaxes #f #f))) diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 38ecd3f12b..c869cac2f3 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.13" +#define MZSCHEME_VERSION "6.3.0.14" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 3 #define MZSCHEME_VERSION_Z 0 -#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 7bae604711534708f9678334b71b9a5f746db452 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 8 Jan 2016 09:53:44 -0700 Subject: [PATCH 350/369] fix default source catalog for `make` --- Makefile | 2 +- racket/src/pkgs-config.rkt | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 550ec36e1d..eaa9894469 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ 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 +DEFAULT_SRC_CATALOG = https://pkgs.racket-lang.org CPUS = diff --git a/racket/src/pkgs-config.rkt b/racket/src/pkgs-config.rkt index d7401fa91b..84549ee756 100644 --- a/racket/src/pkgs-config.rkt +++ b/racket/src/pkgs-config.rkt @@ -34,8 +34,9 @@ ((length l) . >= . 1) (equal? (car l) catalog-relative-path-str))) (define has-src-catalog? - (member (if src-catalog-is-default? #f src-catalog) - l)) + (or (and src-catalog-is-default? + (member #f l)) + (member src-catalog l))) (unless (and starts-as-expected? has-src-catalog?) (error 'pkgs-catalog From d4f3dfb3d0766bd8d6257df4ca9b0e08e3abd89a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 8 Jan 2016 10:00:40 -0700 Subject: [PATCH 351/369] make `SRC_CATALOG` work with `win32-in-place` --- Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index eaa9894469..f4496a8e29 100644 --- a/Makefile +++ b/Makefile @@ -69,7 +69,7 @@ plain-in-place: win32-in-place: $(MAKE) win32-base - $(MAKE) win32-pkgs-catalog + $(MAKE) win32-pkgs-catalog SRC_CATALOG="$(SRC_CATALOG)" $(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) @@ -346,8 +346,10 @@ pkgs-catalog: $(RUN_RACKET) $(PKGS_CONFIG) "$(DEFAULT_SRC_CATALOG)" "$(SRC_CATALOG)" $(RUN_RACKET) racket/src/pkgs-check.rkt racket/share/pkgs-catalog +COPY_PKGS_ARGS = PLAIN_RACKET="$(WIN32_PLAIN_RACKET)" SRC_CATALOG="$(SRC_CATALOG)" + win32-pkgs-catalog: - $(MAKE) pkgs-catalog PLAIN_RACKET="$(WIN32_PLAIN_RACKET)" + $(MAKE) pkgs-catalog $(COPY_PKGS_ARGS) # ------------------------------------------------------------ # On a server platform (for an installer build): From 30005d41ac8035899b048ef7ba1eca6d142a2093 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 8 Jan 2016 16:22:44 -0700 Subject: [PATCH 352/369] repair for cross-build of OS X executables --- racket/collects/compiler/private/mach-o.rkt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/racket/collects/compiler/private/mach-o.rkt b/racket/collects/compiler/private/mach-o.rkt index 4e45f3838d..c6e4473ed4 100644 --- a/racket/collects/compiler/private/mach-o.rkt +++ b/racket/collects/compiler/private/mach-o.rkt @@ -1,10 +1,11 @@ #lang racket/base +(require setup/cross-system) (provide add-plt-segment get/set-dylib-path) (define exe-id - (if (equal? (path->bytes (system-library-subpath #f)) #"x86_64-macosx") + (if (equal? (path->bytes (cross-system-library-subpath #f)) #"x86_64-macosx") #xFeedFacf #xFeedFace)) From 8e162082e1852d65c3102a29cc99ad1066f7d8ad Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 8 Jan 2016 16:40:58 -0700 Subject: [PATCH 353/369] fix foreign library references for cross-build --- racket/collects/db/private/sqlite3/ffi.rkt | 8 +++++--- racket/collects/openssl/libcrypto.rkt | 6 ++++-- racket/collects/openssl/libssl.rkt | 6 ++++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/racket/collects/db/private/sqlite3/ffi.rkt b/racket/collects/db/private/sqlite3/ffi.rkt index 2dde57c10e..d1c4692a0c 100644 --- a/racket/collects/db/private/sqlite3/ffi.rkt +++ b/racket/collects/db/private/sqlite3/ffi.rkt @@ -1,15 +1,17 @@ #lang racket/base -(require (for-syntax racket/base) +(require (for-syntax racket/base + setup/cross-system) racket/runtime-path ffi/unsafe - ffi/unsafe/define) + ffi/unsafe/define + setup/cross-system) (require "ffi-constants.rkt") (provide (all-from-out "ffi-constants.rkt") (protect-out (all-defined-out))) ;; raco distribute should include Racket's sqlite3 if present (define-runtime-path sqlite-so - (case (system-type) + (case (cross-system-type) [(windows) '(so "sqlite3")] [else '(so "libsqlite3" ("0" #f))])) diff --git a/racket/collects/openssl/libcrypto.rkt b/racket/collects/openssl/libcrypto.rkt index 772e9b5d1a..64e3df7e18 100644 --- a/racket/collects/openssl/libcrypto.rkt +++ b/racket/collects/openssl/libcrypto.rkt @@ -1,7 +1,9 @@ #lang racket/base (require ffi/unsafe racket/runtime-path - (for-syntax racket/base)) + setup/cross-system + (for-syntax racket/base + setup/cross-system)) (provide libcrypto libcrypto-load-fail-reason @@ -42,7 +44,7 @@ ;; We need to declare because they might be distributed with Racket, ;; in which case they should get bundled with stand-alone executables: (define-runtime-path libcrypto-so - (case (system-type) + (case (cross-system-type) [(windows) '(so "libeay32")] [(macosx) ;; Version "1.0.0" is bundled with Racket diff --git a/racket/collects/openssl/libssl.rkt b/racket/collects/openssl/libssl.rkt index 214b4fe28a..f4c4ac1682 100644 --- a/racket/collects/openssl/libssl.rkt +++ b/racket/collects/openssl/libssl.rkt @@ -1,7 +1,9 @@ #lang racket/base (require ffi/unsafe racket/runtime-path - (for-syntax racket/base) + setup/cross-system + (for-syntax racket/base + setup/cross-system) "libcrypto.rkt") (provide libssl @@ -12,7 +14,7 @@ ;; We need to declare because they might be distributed with PLT Scheme ;; in which case they should get bundled with stand-alone executables: (define-runtime-path libssl-so - (case (system-type) + (case (cross-system-type) [(windows) '(so "ssleay32")] [(macosx) ;; Version "1.0.0" is bundled with Racket From 7b4c91ea217b4fae31a5057d7698aa3e7f4e6afd Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 8 Jan 2016 18:27:43 -0700 Subject: [PATCH 354/369] setup/cross-system: configure reader properly --- racket/collects/setup/cross-system.rkt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/racket/collects/setup/cross-system.rkt b/racket/collects/setup/cross-system.rkt index 1b1c565c25..0da414457e 100644 --- a/racket/collects/setup/cross-system.rkt +++ b/racket/collects/setup/cross-system.rkt @@ -15,9 +15,11 @@ (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)]) + (let ([ht (call-with-default-reading-parameterization + (lambda () + (call-with-input-file* + f + read)))]) (and (hash? ht) (for/and ([sym (in-list (list* 'library-subpath From dafb6d722e5fd3e5871e1a6663ba417a9ad2222c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 8 Jan 2016 19:31:46 -0700 Subject: [PATCH 355/369] Makefile: move `SRC_CATALOG` definition to ealier Accommodate nmake.exe, which needs the definition before the use in `win32-in-place`. --- Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index f4496a8e29..fde73a4428 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,10 @@ WIN32_RUN_RACO = $(WIN32_RUN_RACKET) -N raco -l- raco DEFAULT_SRC_CATALOG = https://pkgs.racket-lang.org +# Belongs in the "Configuration options" section, but here +# to accomodate nmake: +SRC_CATALOG = $(DEFAULT_SRC_CATALOG) + CPUS = in-place: @@ -194,8 +198,8 @@ racket/src/build/cross/Makefile: racket/src/configure racket/src/Makefile.in # end in "_q" or "_qq", don't use any quote marks on the right-hand # side of its definition. -# Catalog for package sources: -SRC_CATALOG = $(DEFAULT_SRC_CATALOG) +# Catalog for package sources (defined above): +# SRC_CATALOG = $(DEFAULT_SRC_CATALOG) # A URL embedded in documentation for remote searches, where a Racket # version and search key are added as query fields to the URL, and "" From 3e5c889b7d5d923c57020b5059d5f373fa8fc14d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 9 Jan 2016 06:09:36 -0700 Subject: [PATCH 356/369] adjust non-JIT application of chaperone with only properties Don't push elements to the runstack that aren't popped back off. I can't construct an example that demonstrates a problem, but fix it just in case. --- racket/src/racket/src/fun.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/racket/src/racket/src/fun.c b/racket/src/racket/src/fun.c index f28ba52c48..3eb1a51433 100644 --- a/racket/src/racket/src/fun.c +++ b/racket/src/racket/src/fun.c @@ -3746,21 +3746,6 @@ Scheme_Object *scheme_apply_chaperone(Scheme_Object *o, int argc, Scheme_Object int need_pop_mark; Scheme_Cont_Frame_Data cframe; - if (argv == MZ_RUNSTACK) { - /* Pushing onto the runstack ensures that `(vector-ref px->redirects 0)' won't - modify argv. */ - if (MZ_RUNSTACK > MZ_RUNSTACK_START) { - --MZ_RUNSTACK; - *MZ_RUNSTACK = NULL; - need_restore = 1; - } else { - /* Can't push! Just allocate a copy. */ - argv2 = MALLOC_N(Scheme_Object *, argc); - memcpy(argv2, argv, sizeof(Scheme_Object*) * argc); - argv = argv2; - } - } - if (SCHEME_RPAIRP(o)) { /* An applicable struct, where a layer of struct chaperones has been removed from the object to apply, but we will @@ -3804,6 +3789,21 @@ Scheme_Object *scheme_apply_chaperone(Scheme_Object *o, int argc, Scheme_Object return _scheme_tail_apply(px->prev, argc, argv); } + if (argv == MZ_RUNSTACK) { + /* Pushing onto the runstack ensures that `(vector-ref px->redirects 0)' won't + modify argv. */ + if (MZ_RUNSTACK > MZ_RUNSTACK_START) { + --MZ_RUNSTACK; + *MZ_RUNSTACK = NULL; + need_restore = 1; + } else { + /* Can't push! Just allocate a copy. */ + argv2 = MALLOC_N(Scheme_Object *, argc); + memcpy(argv2, argv, sizeof(Scheme_Object*) * argc); + argv = argv2; + } + } + /* Ensure that the original procedure accepts `argc' arguments: */ if (argc != SCHEME_INT_VAL(SCHEME_VEC_ELS(px->redirects)[1])) { a[0] = px->prev; From 034d2e95316a5bd170e747b19e967ff3916749fb Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 9 Jan 2016 06:12:46 -0700 Subject: [PATCH 357/369] declare NSSupportsAutomaticGraphicsSwitching Related to #1193 --- racket/src/mac/osx_appl.rkt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/racket/src/mac/osx_appl.rkt b/racket/src/mac/osx_appl.rkt index e9f83c924e..4230d0e2c1 100644 --- a/racket/src/mac/osx_appl.rkt +++ b/racket/src/mac/osx_appl.rkt @@ -112,7 +112,8 @@ (assoc-pair "CFBundleShortVersionString" ,(version)) (assoc-pair "NSPrincipalClass" "NSApplicationMain") - (assoc-pair "NSHighResolutionCapable" (true)))) + (assoc-pair "NSHighResolutionCapable" (true)) + (assoc-pair "NSSupportsAutomaticGraphicsSwitching" (true)))) (create-app (build-path (current-directory) (if for-3m? 'up 'same)) (string-append "GRacket" suffix) From 01e889570a8fa4098642834a9aaec95c34e1f384 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 9 Jan 2016 08:28:20 -0700 Subject: [PATCH 358/369] net/win32-ssl: enable TLS 1.1 and 1.2 --- racket/collects/net/win32-ssl.rkt | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/racket/collects/net/win32-ssl.rkt b/racket/collects/net/win32-ssl.rkt index 2349109154..c65223adae 100644 --- a/racket/collects/net/win32-ssl.rkt +++ b/racket/collects/net/win32-ssl.rkt @@ -117,6 +117,12 @@ (define SP_PROT_TLS1_SERVER #x00000040) (define SP_PROT_TLS1_CLIENT #x00000080) (define SP_PROT_TLS1 (bitwise-ior SP_PROT_TLS1_SERVER SP_PROT_TLS1_CLIENT)) +(define SP_PROT_TLS1_1_SERVER #x00000100) +(define SP_PROT_TLS1_1_CLIENT #x00000200) +(define SP_PROT_TLS1_1 (bitwise-ior SP_PROT_TLS1_1_SERVER SP_PROT_TLS1_1_CLIENT)) +(define SP_PROT_TLS1_2_SERVER #x00000400) +(define SP_PROT_TLS1_2_CLIENT #x00000800) +(define SP_PROT_TLS1_2 (bitwise-ior SP_PROT_TLS1_2_SERVER SP_PROT_TLS1_2_CLIENT)) (define SCH_CRED_MANUAL_CRED_VALIDATION #x00000008) (define SCH_CRED_NO_DEFAULT_CREDS #x00000010) (define SCHANNEL_CRED_VERSION #x00000004) @@ -287,11 +293,14 @@ 0 #f ; mappers 0 #f ; algs (case protocol - [(secure auto sslv2-or-v3) - (bitwise-ior SP_PROT_TLS1)] + [(secure auto) + (bitwise-ior SP_PROT_TLS1 SP_PROT_TLS1_1 SP_PROT_TLS1_2)] [(sslv2) SP_PROT_SSL2] [(sslv3) SP_PROT_SSL3] - [(tls tls11 tls12) SP_PROT_TLS1]) + [(tls) SP_PROT_TLS1] + [(tls11) SP_PROT_TLS1_1] + [(tls12) SP_PROT_TLS1_2] + [else 0]) 0 0 0 (if (eq? protocol 'secure) 0 From c2e99efefc5c6ccd61f4eae3afdae6db1743afcf Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Sat, 9 Jan 2016 11:31:31 -0500 Subject: [PATCH 359/369] Post-release version for the v6.4 release --- pkgs/base/info.rkt | 2 +- racket/src/racket/src/schvers.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index 3212dd1af8..6c64727430 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.3.0.14") +(define version "6.4.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 c869cac2f3..9e553a66fd 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.14" +#define MZSCHEME_VERSION "6.4.0.1" #define MZSCHEME_VERSION_X 6 -#define MZSCHEME_VERSION_Y 3 +#define MZSCHEME_VERSION_Y 4 #define MZSCHEME_VERSION_Z 0 -#define MZSCHEME_VERSION_W 14 +#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 0d3066d8dbdcabb8bd6c3dcf1f08d3f127db57ba Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 9 Jan 2016 09:00:00 -0700 Subject: [PATCH 360/369] adjust doc example to avoid a dependence on "algol60" Merge to v6.4 --- pkgs/racket-doc/scribblings/reference/read.scrbl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/read.scrbl b/pkgs/racket-doc/scribblings/reference/read.scrbl index a397aadfce..127ea8052e 100644 --- a/pkgs/racket-doc/scribblings/reference/read.scrbl +++ b/pkgs/racket-doc/scribblings/reference/read.scrbl @@ -156,8 +156,10 @@ interpretation of results is up to external tools, such as DrRacket (see If no information is available for a given key, the result should be the second argument. @mz-examples[ -((read-language (open-input-string "#lang algol60")) 'color-lexer #f) -((read-language (open-input-string "#lang algol60")) 'something-else #f) +(define scribble-manual-info + (read-language (open-input-string "#lang scribble/manual"))) +(scribble-manual-info 'color-lexer #f) +(scribble-manual-info 'something-else #f) ] The @racketidfont{get-info} function itself is applied to five From 417d9b0e73abadc4836b9d8cc4c4bd01c146d868 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 9 Jan 2016 09:41:12 -0700 Subject: [PATCH 361/369] define-runtime-path: add a `#:runtime?-id` option The expression in a `define-runtime-path` form is used in both a run-time context and a compile-time context. The latter is used for `raco exe`. In a cross-build context, you might need to load OpenSSL support for Linux (say) at build time while generating executables that refer to Windows (say) OpenSSL support. In that case, `#:runtime?-id` lets you choose between `(cross-system-type)` and `(system-type)`. Merge to v6.4 --- .../scribblings/reference/filesystem.scrbl | 17 ++++++++++++----- racket/collects/db/private/sqlite3/ffi.rkt | 3 ++- racket/collects/openssl/libcrypto.rkt | 3 ++- racket/collects/openssl/libssl.rkt | 3 ++- racket/collects/racket/runtime-path.rkt | 18 +++++++++++------- 5 files changed, 29 insertions(+), 15 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/filesystem.scrbl b/pkgs/racket-doc/scribblings/reference/filesystem.scrbl index cfc031b488..d5f0f5213a 100644 --- a/pkgs/racket-doc/scribblings/reference/filesystem.scrbl +++ b/pkgs/racket-doc/scribblings/reference/filesystem.scrbl @@ -641,13 +641,18 @@ In addition to the bindings described below, @tech{phase level} 1, since string constants are often used as compile-time expressions with @racket[define-runtime-path]. -@defform[(define-runtime-path id expr)]{ +@defform[(define-runtime-path id maybe-runtime?-id expr) + #:grammar ([maybe-runtime? code:blank + (code:line #:runtime?-id runtime?-id)])]{ Uses @racket[expr] as both a compile-time (i.e., @tech{phase} 1) expression and a run-time (i.e., @tech{phase} 0) expression. In either context, @racket[expr] should produce a path, a string that represents a path, a list of the form @racket[(list 'lib _str ...+)], or a list of the form @racket[(list 'so _str)] or @racket[(list 'so _str _vers)]. +If @racket[runtime?-id] is provided, then it is bound in the context +of @racket[expr] to @racket[#f] for the compile-time instance of +@racket[expr] and @racket[#t] for the run-time instance of @racket[expr]. For run time, @racket[id] is bound to a path that is based on the result of @racket[expr]. The path is normally computed by taking a @@ -781,23 +786,25 @@ Examples: [(windows) '(so "ssleay32")] [else '(so "libssl")])) (define libssl (ffi-lib libssl-so)) -]} +] + +@history[#:changed "6.4" @elem{Added @racket[#:runtime?-id].}]} -@defform[(define-runtime-paths (id ...) expr)]{ +@defform[(define-runtime-paths (id ...) maybe-runtime?-id expr)]{ Like @racket[define-runtime-path], but declares and binds multiple paths at once. The @racket[expr] should produce as many values as @racket[id]s.} -@defform[(define-runtime-path-list id expr)]{ +@defform[(define-runtime-path-list id maybe-runtime?-id expr)]{ Like @racket[define-runtime-path], but @racket[expr] should produce a list of paths.} -@defform[(define-runtime-module-path-index id module-path-expr)]{ +@defform[(define-runtime-module-path-index id maybe-runtime?-id module-path-expr)]{ Similar to @racket[define-runtime-path], but @racket[id] is bound to a @tech{module path index} that encapsulates the result of diff --git a/racket/collects/db/private/sqlite3/ffi.rkt b/racket/collects/db/private/sqlite3/ffi.rkt index d1c4692a0c..d560fd16a2 100644 --- a/racket/collects/db/private/sqlite3/ffi.rkt +++ b/racket/collects/db/private/sqlite3/ffi.rkt @@ -11,7 +11,8 @@ ;; raco distribute should include Racket's sqlite3 if present (define-runtime-path sqlite-so - (case (cross-system-type) + #:runtime?-id runtime? + (case (if runtime? (system-type) (cross-system-type)) [(windows) '(so "sqlite3")] [else '(so "libsqlite3" ("0" #f))])) diff --git a/racket/collects/openssl/libcrypto.rkt b/racket/collects/openssl/libcrypto.rkt index 64e3df7e18..774d9611ca 100644 --- a/racket/collects/openssl/libcrypto.rkt +++ b/racket/collects/openssl/libcrypto.rkt @@ -44,7 +44,8 @@ ;; We need to declare because they might be distributed with Racket, ;; in which case they should get bundled with stand-alone executables: (define-runtime-path libcrypto-so - (case (cross-system-type) + #:runtime?-id runtime? + (case (if runtime? (system-type) (cross-system-type)) [(windows) '(so "libeay32")] [(macosx) ;; Version "1.0.0" is bundled with Racket diff --git a/racket/collects/openssl/libssl.rkt b/racket/collects/openssl/libssl.rkt index f4c4ac1682..66c0f882d6 100644 --- a/racket/collects/openssl/libssl.rkt +++ b/racket/collects/openssl/libssl.rkt @@ -14,7 +14,8 @@ ;; We need to declare because they might be distributed with PLT Scheme ;; in which case they should get bundled with stand-alone executables: (define-runtime-path libssl-so - (case (cross-system-type) + #:runtime?-id runtime? + (case (if runtime? (system-type) (cross-system-type)) [(windows) '(so "ssleay32")] [(macosx) ;; Version "1.0.0" is bundled with Racket diff --git a/racket/collects/racket/runtime-path.rkt b/racket/collects/racket/runtime-path.rkt index 5058e00fdf..98e71c34b5 100644 --- a/racket/collects/racket/runtime-path.rkt +++ b/racket/collects/racket/runtime-path.rkt @@ -161,7 +161,7 @@ (define-syntax (-define-runtime-path stx) (syntax-case stx () - [(_ orig-stx (id ...) expr to-list to-values need-dir?) + [(_ orig-stx (id ...) expr to-list to-values need-dir? runtime?-id) (let ([ids (syntax->list #'(id ...))]) (unless (memq (syntax-local-context) '(module module-begin top-level)) (raise-syntax-error #f "allowed only at the top level" #'orig-stx)) @@ -180,7 +180,7 @@ #'orig-stx))) #`(begin (define-values (id ...) - (let-values ([(id ...) expr]) + (let-values ([(id ...) (let ([runtime?-id #t]) expr)]) (let ([get-dir #,(if (syntax-e #'need-dir?) #`(lambda () (path-of @@ -195,24 +195,28 @@ (begin-for-syntax (register-ext-files (#%variable-reference) - (let-values ([(id ...) expr]) + (let-values ([(id ...) (let ([runtime?-id #f]) expr)]) (to-list id ...))))))])) (define-syntax (define-runtime-path stx) (syntax-case stx () - [(_ id expr) #`(-define-runtime-path #,stx (id) expr list values #t)])) + [(_ id expr) #`(-define-runtime-path #,stx (id) expr list values #t runtime?)] + [(_ id #:runtime?-id runtime?-id expr) #`(-define-runtime-path #,stx (id) expr list values #t runtime?-id)])) (define-syntax (define-runtime-paths stx) (syntax-case stx () - [(_ (id ...) expr) #`(-define-runtime-path #,stx (id ...) expr list values #t)])) + [(_ (id ...) expr) #`(-define-runtime-path #,stx (id ...) expr list values #t runtime?)] + [(_ (id ...) #:runtime?-id runtime?-id expr) #`(-define-runtime-path #,stx (id ...) expr list values #t runtime?-id)])) (define-syntax (define-runtime-path-list stx) (syntax-case stx () - [(_ id expr) #`(-define-runtime-path #,stx (id) expr values list #t)])) + [(_ id expr) #`(-define-runtime-path #,stx (id) expr values list #t runtime?)] + [(_ id #:runtime?-id runtime?-id expr) #`(-define-runtime-path #,stx (id) expr values list #t runtime?-id)])) (define-syntax (define-runtime-module-path-index stx) (syntax-case stx () - [(_ id expr) #`(-define-runtime-path #,stx (id) `(module ,expr ,(#%variable-reference)) list values #f)])) + [(_ id expr) #`(-define-runtime-path #,stx (id) `(module ,expr ,(#%variable-reference)) list values #f runtime?)] + [(_ id #:runtime?-id runtime?-id expr) #`(-define-runtime-path #,stx (id) `(module ,expr ,(#%variable-reference)) list values #f runtime?-id)])) (define-for-syntax required-module-paths (make-hash)) (define-syntax (runtime-require stx) From 34f52deeb1aa05104e5462dbe281932718827388 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 8 Dec 2015 16:25:21 -0500 Subject: [PATCH 362/369] Fix struct error for bad #:constructor-name --- racket/collects/racket/private/define-struct.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/racket/private/define-struct.rkt b/racket/collects/racket/private/define-struct.rkt index b5c7bb727e..9a8a80be04 100644 --- a/racket/collects/racket/private/define-struct.rkt +++ b/racket/collects/racket/private/define-struct.rkt @@ -323,7 +323,7 @@ (when (lookup config '#:constructor-name) (bad "multiple" "#:constructor-name or #:extra-constructor-name" "s" (car p))) (unless (identifier? (cadr p)) - (bad "need an identifier after" (car p) (cadr p))) + (bad "need an identifier after" (car p) "" (cadr p))) (loop (cddr p) (extend-config (extend-config config '#:constructor-name (cadr p)) '#:only-constructor? From 6ea9e963c4c25948f94f9f9406df604750833a1c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 13 Jan 2016 07:44:31 -0700 Subject: [PATCH 363/369] add context properties to a `module` expansion Add 'module-body-inside-context, 'module-body-outside-context, and 'module-body-context-simple? properties to the expansion of a `module` form. These properties expose scopes that are used by `module->namespace` and taht appear in marshaled bytecode. --- .../scribblings/raco/zo-struct.scrbl | 17 +++--- .../scribblings/reference/stx-expand.scrbl | 38 +++++++++++++ .../scribblings/reference/syntax-model.scrbl | 23 ++++++-- .../racket-test-core/tests/racket/module.rktl | 29 ++++++++++ racket/src/racket/src/module.c | 54 +++++++++++++++++-- 5 files changed, 146 insertions(+), 15 deletions(-) diff --git a/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl b/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl index d0f86d547f..c3a69d40f3 100644 --- a/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl +++ b/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl @@ -274,12 +274,17 @@ binding, constructor, etc.} The @racket[lang-info] value specifies an optional module path that provides information about the module's implementation language. - The @racket[internal-context] value describes the lexical - context of the body of the module. This value is used by - @racket[module->namespace]. A @racket[#f] value means that the - context is unavailable or empty. A @racket[#t] value means that the - context is computed by re-importing all required modules. A - syntax-object value embeds an arbitrary lexical context. + The @racket[internal-context] value describes the lexical context of + the body of the module. This value is used by + @racket[module->namespace]. A @racket[#f] value means that the + context is unavailable or empty. A @racket[#t] value means that the + context is computed by re-importing all required modules. A + syntax-object value embeds lexical information; the syntax object + should contain a vector of two elements, where the first element of + the vector is a syntax object for the module's body, which includes + the outside-edge and inside-edge scopes, and the second element of + the vector is a syntax object that has just the module's inside-edge + scope. The @racket[binding-names] value provides additional information to @racket[module->namespace] to correlate symbol names for variables diff --git a/pkgs/racket-doc/scribblings/reference/stx-expand.scrbl b/pkgs/racket-doc/scribblings/reference/stx-expand.scrbl index 895f9f9bdc..b01ed3b522 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-expand.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-expand.scrbl @@ -105,6 +105,14 @@ to the syntax object: list of @tech{module path index}es (or symbols) representing the modules explicitly for-template imported into the module.} + @item{@indexed-racket['module-direct-for-meta-requires] --- a list of + lists: each list is an integer or @racket[#f] representing a + @tech{phase level} followed by a list of @tech{module path index}es + (or symbols) representing the modules explicitly imported into the + module at the corresponding phase. + + @history[#:added "6.4.0.1"]} + @item{@indexed-racket['module-variable-provides] --- a list of provided items, where each item is one of the following: @@ -138,5 +146,35 @@ to the syntax object: be exported indirectly through macro expansions. Definitions of macro-generated identifiers create uninterned symbols in this list.} + @item{@indexed-racket['module-body-inside-context] --- a syntax + object whose @tech{lexical information} corresponds to the inside of + the module, so it includes the expansion's @tech{outside-edge scope} + and its @tech{inside-edge scope}; that is, the syntax object + simulates an identifier that is present in the original module body + and inaccessible to manipulation by any macro, so that its lexical + information includes bindings for the module's imports and + definitions. + + @history[#:added "6.4.0.1"]} + + @item{@indexed-racket['module-body-outside-context] --- a syntax + object whose @tech{lexical information} corresponds to an identifier + that starts with no lexical context and is moved into the macro, so + that it includes only the expansions's @tech{inside-edge scope}. + + @history[#:added "6.4.0.1"]} + + @item{@indexed-racket['module-body-context-simple?] --- a boolean, + where @racket[#t] indicates that the bindings of the module's body + (as recorded in the @tech{lexical information} of the value of the + @racket['module-body-inside-context] property) can be directly + reconstructed from the values of @racket['module-direct-requires], + @racket['module-direct-for-syntax-requires], + @racket['module-direct-for-template-requires], and + @racket['module-direct-for-meta-requires]. + + @history[#:added "6.4.0.1"]} + + ] diff --git a/pkgs/racket-doc/scribblings/reference/syntax-model.scrbl b/pkgs/racket-doc/scribblings/reference/syntax-model.scrbl index 0b9fdab175..3028db2646 100644 --- a/pkgs/racket-doc/scribblings/reference/syntax-model.scrbl +++ b/pkgs/racket-doc/scribblings/reference/syntax-model.scrbl @@ -742,9 +742,7 @@ internal-definition context are equivalent to local binding via @racket[letrec-syntaxes+values]; macro expansion converts internal definitions to a @racket[letrec-syntaxes+values] form. -Expansion of an internal-definition context begins with the -introduction of a fresh @tech{scope} for the context. Thereafter, -expansion relies on @tech{partial expansion} of each @racket[_body] in +Expansion relies on @tech{partial expansion} of each @racket[_body] in an internal-definition sequence. Partial expansion of each @racket[_body] produces a form matching one of the following cases: @@ -782,8 +780,25 @@ are then converted to bindings in a @racket[letrec-syntaxes+values] form, and all expressions after the last definition become the body of the @racket[letrec-syntaxes+values] form. +Before partial expansion begins, expansion of an internal-definition +context begins with the introduction of a fresh @deftech{outside-edge +scope} on the content of the internal-definition context. This +outside-edge scope effectively identifies syntax objects that are +present in the original form. An @deftech{inside-edge scope} is also +created and added to the original content; furthermore, the +inside-edge scope is added to the result of any partial expansion. +This inside-edge scope ensures that all bindings introduced by the +internal-definition context have a particular scope in common. + @;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@subsection[#:tag "mod-parse"]{Module Phases and Visits} +@subsection[#:tag "mod-parse"]{Module Expansion, Phases, and Visits} + +Expansion of a @racket[module] form proceeds in a similar way to +@seclink["intdef-body"]{expansion of an internal-definition context}: +an @tech{outside-edge scope} is created for the original module +content, and an @tech{inside-edge scope} is added to both the original +module and any form that appears during a partial expansion of the +module's top-level forms to uncover definitions and imports. A @racket[require] form not only introduces @tech{bindings} at expansion time, but also @deftech{visits} the referenced module when diff --git a/pkgs/racket-test-core/tests/racket/module.rktl b/pkgs/racket-test-core/tests/racket/module.rktl index 6333e70c86..579c1f67ed 100644 --- a/pkgs/racket-test-core/tests/racket/module.rktl +++ b/pkgs/racket-test-core/tests/racket/module.rktl @@ -1719,6 +1719,35 @@ case of module-leve bindings; it doesn't cover local bindings. (require 'exports-x**-as-x) (test 5 'five (x)) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check 'module-body-context-simple? and 'module-body-...context properties + +(define (check-module-body-context-properties with-kar?) + (define m (expand `(module m racket/base + ,@(if with-kar? + `((require (rename-in racket/base [car kar]))) + null) + (define inside 7)))) + + (test (not with-kar?) syntax-property m 'module-body-context-simple?) + + (define i (syntax-property m 'module-body-inside-context)) + (define o (syntax-property m 'module-body-outside-context)) + + (test #t syntax? i) + (test #t syntax? o) + + (test car eval-syntax (datum->syntax i 'car)) + (test 'inside cadr (identifier-binding (datum->syntax i 'inside))) + (test #f identifier-binding (datum->syntax o 'inside)) + (test (if with-kar? 'car #f) + 'kar-binding + (let ([v (identifier-binding (datum->syntax i 'kar))]) + (and v (cadr v))))) + +(check-module-body-context-properties #f) +(check-module-body-context-properties #t) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index 3c5822bf0c..214e3e115a 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -7433,8 +7433,14 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, cons(fm, scheme_null)))); fm = scheme_datum_to_syntax(fm, form, ctx_form, 0, 2); + + /* for future expansion, shift away from self_modidx: */ + ps = scheme_make_shift(NULL, self_modidx, this_empty_self_modidx, NULL, NULL, NULL); + fm = scheme_stx_add_shift(fm, ps); if (hints) { + Scheme_Object *stx, *l; + fm = scheme_stx_property(fm, scheme_intern_symbol("module-direct-requires"), m->requires); @@ -7444,6 +7450,24 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, fm = scheme_stx_property(fm, scheme_intern_symbol("module-direct-for-template-requires"), m->tt_requires); + + l = scheme_null; + if (!SCHEME_NULLP(m->dt_requires)) + l = scheme_make_pair(scheme_make_pair(scheme_false, m->dt_requires), + l); + if (m->other_requires) { + int i; + for (i = 0; i < m->other_requires->size; i++) { + if (m->other_requires->vals[i]) { + l = scheme_make_pair(scheme_make_pair(m->other_requires->keys[i], + m->other_requires->vals[i]), + l); + } + } + } + fm = scheme_stx_property(fm, + scheme_intern_symbol("module-direct-for-meta-requires"), + l); fm = scheme_stx_property(fm, scheme_intern_symbol("module-variable-provides"), @@ -7463,11 +7487,25 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, fm = scheme_stx_property(fm, scheme_intern_symbol("module-self-path-index"), this_empty_self_modidx); - } - /* for future expansion, shift away from self_modidx: */ - ps = scheme_make_shift(NULL, self_modidx, this_empty_self_modidx, NULL, NULL, NULL); - fm = scheme_stx_add_shift(fm, ps); + fm = scheme_stx_property(fm, + scheme_intern_symbol("module-body-context-simple?"), + (SAME_OBJ(scheme_true, m->rn_stx) + ? scheme_true + : scheme_false)); + + stx = scheme_datum_to_syntax(scheme_intern_symbol("inside"), scheme_false, scheme_false, 0, 0); + stx = scheme_stx_add_module_context(stx, rn_set); + fm = scheme_stx_property(fm, + scheme_intern_symbol("module-body-inside-context"), + scheme_stx_add_shift(stx, ps)); + + stx = scheme_datum_to_syntax(scheme_intern_symbol("outside"), scheme_false, scheme_false, 0, 0); + stx = scheme_stx_introduce_to_module_context(stx, rn_set); + fm = scheme_stx_property(fm, + scheme_intern_symbol("module-body-outside-context"), + scheme_stx_add_shift(stx, ps)); + } /* make self_modidx like the empty modidx */ if (SAME_OBJ(this_empty_self_modidx, empty_self_modidx)) @@ -8383,7 +8421,7 @@ static Scheme_Object *do_module_begin(Scheme_Object *orig_form, Scheme_Comp_Env result = scheme_null; - /* kernel re-export info (always #f): */ + /* kernel re-export info (now always #f): */ result = scheme_make_pair(scheme_false, result); /* Indirect provides */ @@ -8467,6 +8505,12 @@ static Scheme_Object *do_module_begin(Scheme_Object *orig_form, Scheme_Comp_Env add_binding_names_from_environment(env->genv->module, bnenv); } } + } else { + /* For a property on the expanded module: */ + if (*all_simple_bindings && env->genv->module->rn_stx) { + /* We will be able to reconstruct binding for `module->namespace`: */ + env->genv->module->rn_stx = scheme_true; + } } if (rec[drec].comp || has_submodules) { From 052c7e4c066ff30129d4655a458ad2fa959393f7 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 13 Jan 2016 07:53:50 -0700 Subject: [PATCH 364/369] pick better names for new module-expansion properties In retrospect, 'module-body-outside-context wasn't a good name for a property that turned out to hold only an inside-edge scope. --- pkgs/racket-doc/scribblings/reference/stx-expand.scrbl | 4 ++-- pkgs/racket-test-core/tests/racket/module.rktl | 4 ++-- racket/src/racket/src/module.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/stx-expand.scrbl b/pkgs/racket-doc/scribblings/reference/stx-expand.scrbl index b01ed3b522..df0faf8063 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-expand.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-expand.scrbl @@ -146,7 +146,7 @@ to the syntax object: be exported indirectly through macro expansions. Definitions of macro-generated identifiers create uninterned symbols in this list.} - @item{@indexed-racket['module-body-inside-context] --- a syntax + @item{@indexed-racket['module-body-context] --- a syntax object whose @tech{lexical information} corresponds to the inside of the module, so it includes the expansion's @tech{outside-edge scope} and its @tech{inside-edge scope}; that is, the syntax object @@ -157,7 +157,7 @@ to the syntax object: @history[#:added "6.4.0.1"]} - @item{@indexed-racket['module-body-outside-context] --- a syntax + @item{@indexed-racket['module-body-inside-context] --- a syntax object whose @tech{lexical information} corresponds to an identifier that starts with no lexical context and is moved into the macro, so that it includes only the expansions's @tech{inside-edge scope}. diff --git a/pkgs/racket-test-core/tests/racket/module.rktl b/pkgs/racket-test-core/tests/racket/module.rktl index 579c1f67ed..d09c32cac6 100644 --- a/pkgs/racket-test-core/tests/racket/module.rktl +++ b/pkgs/racket-test-core/tests/racket/module.rktl @@ -1731,8 +1731,8 @@ case of module-leve bindings; it doesn't cover local bindings. (test (not with-kar?) syntax-property m 'module-body-context-simple?) - (define i (syntax-property m 'module-body-inside-context)) - (define o (syntax-property m 'module-body-outside-context)) + (define i (syntax-property m 'module-body-context)) + (define o (syntax-property m 'module-body-inside-context)) (test #t syntax? i) (test #t syntax? o) diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index 214e3e115a..f76b9fbb2f 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -7497,13 +7497,13 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, stx = scheme_datum_to_syntax(scheme_intern_symbol("inside"), scheme_false, scheme_false, 0, 0); stx = scheme_stx_add_module_context(stx, rn_set); fm = scheme_stx_property(fm, - scheme_intern_symbol("module-body-inside-context"), + scheme_intern_symbol("module-body-context"), scheme_stx_add_shift(stx, ps)); stx = scheme_datum_to_syntax(scheme_intern_symbol("outside"), scheme_false, scheme_false, 0, 0); stx = scheme_stx_introduce_to_module_context(stx, rn_set); fm = scheme_stx_property(fm, - scheme_intern_symbol("module-body-outside-context"), + scheme_intern_symbol("module-body-inside-context"), scheme_stx_add_shift(stx, ps)); } From 0fb11e61e6cf4327cf31d7c30ce5a34d11bf60cd Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Fri, 8 Jan 2016 13:50:17 -0800 Subject: [PATCH 365/369] update copyright from 2015 to 2016 --- 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/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 +- 78 files changed, 78 insertions(+), 78 deletions(-) diff --git a/README.txt b/README.txt index e6c1d2d36e..d1e2c2b132 100644 --- a/README.txt +++ b/README.txt @@ -5,7 +5,7 @@ License ------- Racket -Copyright (c) 2010-2015 PLT Design Inc. +Copyright (c) 2010-2016 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 1f2645dc9c..056171aee8 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-2015 PLT Design Inc. +Copyright (c) 2010-2016 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 7396cb7383..9a979f3f73 100644 --- a/pkgs/base/LICENSE.txt +++ b/pkgs/base/LICENSE.txt @@ -1,5 +1,5 @@ base -Copyright (c) 2010-2015 PLT Design Inc. +Copyright (c) 2010-2016 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 51edf17571..a13beb37cf 100644 --- a/pkgs/racket-doc/LICENSE.txt +++ b/pkgs/racket-doc/LICENSE.txt @@ -1,5 +1,5 @@ racket-doc -Copyright (c) 2010-2015 PLT Design Inc. +Copyright (c) 2010-2016 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 fd82edbca7..3d17c1c0c4 100644 --- a/pkgs/racket-index/LICENSE.txt +++ b/pkgs/racket-index/LICENSE.txt @@ -1,5 +1,5 @@ racket-index -Copyright (c) 2010-2015 PLT Design Inc. +Copyright (c) 2010-2016 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 f2984b252f..1b53202392 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-2015 PLT Design Inc. + Copyright (c) 2010-2016 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 9b2aface7f..fda0e79022 100644 --- a/pkgs/racket-lib/LICENSE.txt +++ b/pkgs/racket-lib/LICENSE.txt @@ -1,5 +1,5 @@ racket-lib -Copyright (c) 2010-2015 PLT Design Inc. +Copyright (c) 2010-2016 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 46232662cc..413cec8000 100644 --- a/pkgs/racket-test-core/LICENSE.txt +++ b/pkgs/racket-test-core/LICENSE.txt @@ -1,5 +1,5 @@ racket-test -Copyright (c) 2010-2015 PLT Design Inc. +Copyright (c) 2010-2016 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 46232662cc..413cec8000 100644 --- a/pkgs/racket-test/LICENSE.txt +++ b/pkgs/racket-test/LICENSE.txt @@ -1,5 +1,5 @@ racket-test -Copyright (c) 2010-2015 PLT Design Inc. +Copyright (c) 2010-2016 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 27f08774b3..5f7ce5657d 100644 --- a/racket/src/native-libs/install.rkt +++ b/racket/src/native-libs/install.rkt @@ -264,7 +264,7 @@ #:exists 'truncate (lambda (o) (displayln pkg-name o) - (displayln "Copyright (c) 2010-2015 PLT Design Inc." o) + (displayln "Copyright (c) 2010-2016 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 b0edc8e823..3261033ba6 100644 --- a/racket/src/racket/dynsrc/mzdyn.c +++ b/racket/src/racket/dynsrc/mzdyn.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 6d117330f2..abe690a720 100644 --- a/racket/src/racket/include/escheme.h +++ b/racket/src/racket/include/escheme.h @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 c9419db4e1..dcaa235510 100644 --- a/racket/src/racket/include/scheme.h +++ b/racket/src/racket/include/scheme.h @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 2c65759161..2e6b294613 100644 --- a/racket/src/racket/main.c +++ b/racket/src/racket/main.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 0e8cea20d4..022c488d84 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-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 29659ffda8..f73197ba3b 100644 --- a/racket/src/racket/src/bignum.c +++ b/racket/src/racket/src/bignum.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 20cee7e098..4be93d6a68 100644 --- a/racket/src/racket/src/bool.c +++ b/racket/src/racket/src/bool.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 5ccb0167a6..8bf11e9c0b 100644 --- a/racket/src/racket/src/builtin.c +++ b/racket/src/racket/src/builtin.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 a0a19e7ee0..0ad270afa3 100644 --- a/racket/src/racket/src/char.c +++ b/racket/src/racket/src/char.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 34eaaae6d9..7ee37f5a05 100644 --- a/racket/src/racket/src/compenv.c +++ b/racket/src/racket/src/compenv.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 4500c8fa1e..5aefc655d1 100644 --- a/racket/src/racket/src/compile.c +++ b/racket/src/racket/src/compile.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 e913396d5f..e1f2d65ad1 100644 --- a/racket/src/racket/src/complex.c +++ b/racket/src/racket/src/complex.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 42f24b9380..d2176c24eb 100644 --- a/racket/src/racket/src/dynext.c +++ b/racket/src/racket/src/dynext.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 6b91ab4701..34ec6d26f5 100644 --- a/racket/src/racket/src/env.c +++ b/racket/src/racket/src/env.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 ec7db16c28..21f7ddbca1 100644 --- a/racket/src/racket/src/error.c +++ b/racket/src/racket/src/error.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 c02a180cf5..c00b679ded 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 1d0c40f16d..4792da8f25 100644 --- a/racket/src/racket/src/file.c +++ b/racket/src/racket/src/file.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 3eb1a51433..889cc2008e 100644 --- a/racket/src/racket/src/fun.c +++ b/racket/src/racket/src/fun.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 ba46ad5222..46342ecfb1 100644 --- a/racket/src/racket/src/future.c +++ b/racket/src/racket/src/future.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2006-2015 PLT Design Inc. + Copyright (c) 2006-2016 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 220c16f528..98dee6ccbc 100644 --- a/racket/src/racket/src/hash.c +++ b/racket/src/racket/src/hash.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 52b8c9704d..8282905d7d 100644 --- a/racket/src/racket/src/jit.c +++ b/racket/src/racket/src/jit.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2006-2015 PLT Design Inc. + Copyright (c) 2006-2016 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 9213bf8a7a..8ae0f9c6eb 100644 --- a/racket/src/racket/src/jitalloc.c +++ b/racket/src/racket/src/jitalloc.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2006-2015 PLT Design Inc. + Copyright (c) 2006-2016 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 a84b039f0d..e363df3050 100644 --- a/racket/src/racket/src/jitarith.c +++ b/racket/src/racket/src/jitarith.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2006-2015 PLT Design Inc. + Copyright (c) 2006-2016 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 fc2d056fa2..ffeabfd26c 100644 --- a/racket/src/racket/src/jitcall.c +++ b/racket/src/racket/src/jitcall.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2006-2015 PLT Design Inc. + Copyright (c) 2006-2016 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 7c271f64b3..98d34274e1 100644 --- a/racket/src/racket/src/jitcommon.c +++ b/racket/src/racket/src/jitcommon.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2006-2015 PLT Design Inc. + Copyright (c) 2006-2016 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 efea7983fd..3b0fef43d3 100644 --- a/racket/src/racket/src/jitinline.c +++ b/racket/src/racket/src/jitinline.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2006-2015 PLT Design Inc. + Copyright (c) 2006-2016 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 ec147332d8..3b8978f81c 100644 --- a/racket/src/racket/src/jitprep.c +++ b/racket/src/racket/src/jitprep.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 b13b2577d3..3663ac665d 100644 --- a/racket/src/racket/src/jitstack.c +++ b/racket/src/racket/src/jitstack.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2006-2015 PLT Design Inc. + Copyright (c) 2006-2016 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 029c07628c..e3e71591c2 100644 --- a/racket/src/racket/src/jitstate.c +++ b/racket/src/racket/src/jitstate.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2006-2015 PLT Design Inc. + Copyright (c) 2006-2016 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 328b2aa1dd..e705bed2c8 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-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 ad9f007de0..d12fa9424d 100644 --- a/racket/src/racket/src/list.c +++ b/racket/src/racket/src/list.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 7efa4de367..f3041afe1d 100644 --- a/racket/src/racket/src/marshal.c +++ b/racket/src/racket/src/marshal.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 f76b9fbb2f..18ea5061a9 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 bdaa9dc143..21c8441902 100644 --- a/racket/src/racket/src/mzrt.c +++ b/racket/src/racket/src/mzrt.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2009-2015 PLT Design Inc. + Copyright (c) 2009-2016 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 3ceb734c72..d76e61e4df 100644 --- a/racket/src/racket/src/mzsj86.c +++ b/racket/src/racket/src/mzsj86.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 76a42abdf8..3e5d938121 100644 --- a/racket/src/racket/src/network.c +++ b/racket/src/racket/src/network.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 315d6a4034..36030db974 100644 --- a/racket/src/racket/src/numarith.c +++ b/racket/src/racket/src/numarith.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 31d14914f5..62e6321ef9 100644 --- a/racket/src/racket/src/number.c +++ b/racket/src/racket/src/number.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 a3923119c4..1ba5d8594a 100644 --- a/racket/src/racket/src/numcomp.c +++ b/racket/src/racket/src/numcomp.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 7109d75d0d..0a5bfa20f7 100644 --- a/racket/src/racket/src/nummacs.h +++ b/racket/src/racket/src/nummacs.h @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 c0fe380ea7..eca6de2817 100644 --- a/racket/src/racket/src/numstr.c +++ b/racket/src/racket/src/numstr.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 6457f0f9e6..3d700107e2 100644 --- a/racket/src/racket/src/optimize.c +++ b/racket/src/racket/src/optimize.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 44faed0e92..25e3add246 100644 --- a/racket/src/racket/src/place.c +++ b/racket/src/racket/src/place.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2009-2015 PLT Design Inc. + Copyright (c) 2009-2016 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 00ec531b0b..58770af789 100644 --- a/racket/src/racket/src/port.c +++ b/racket/src/racket/src/port.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 0f6c4b0c13..b8cf3bf747 100644 --- a/racket/src/racket/src/portfun.c +++ b/racket/src/racket/src/portfun.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 e0cb524dea..35710c4532 100644 --- a/racket/src/racket/src/print.c +++ b/racket/src/racket/src/print.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 4dda7a6f94..c36aaae1b7 100644 --- a/racket/src/racket/src/rational.c +++ b/racket/src/racket/src/rational.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 5ce623bfaa..93bcdbd24e 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 b2e7fa76cb..d3858ded49 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-2015 PLT Design Inc. + * Copyright (c) 2004-2016 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 90787abaa0..90b728ac11 100644 --- a/racket/src/racket/src/resolve.c +++ b/racket/src/racket/src/resolve.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 5ecfc0377b..df8d9fe91c 100644 --- a/racket/src/racket/src/salloc.c +++ b/racket/src/racket/src/salloc.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 c315a9ec2a..76bede83c8 100644 --- a/racket/src/racket/src/schemef.h +++ b/racket/src/racket/src/schemef.h @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 f7553b13d0..aaf03123f1 100644 --- a/racket/src/racket/src/schemex.h +++ b/racket/src/racket/src/schemex.h @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 17b13f9bc5..22aa6fa1e9 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 c0bffa8477..90e9628fc9 100644 --- a/racket/src/racket/src/sema.c +++ b/racket/src/racket/src/sema.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 27ee9a843f..e69c1eed10 100644 --- a/racket/src/racket/src/setjmpup.c +++ b/racket/src/racket/src/setjmpup.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 e2f93aeb71..3cc0d7c3cb 100644 --- a/racket/src/racket/src/sfs.c +++ b/racket/src/racket/src/sfs.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 56026cd0f5..07d341c095 100644 --- a/racket/src/racket/src/string.c +++ b/racket/src/racket/src/string.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 840f03cfcf..979d9238ee 100644 --- a/racket/src/racket/src/struct.c +++ b/racket/src/racket/src/struct.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 ececb055d9..f40dd0fca4 100644 --- a/racket/src/racket/src/symbol.c +++ b/racket/src/racket/src/symbol.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 de2cc3ae1b..3af574b018 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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/type.c b/racket/src/racket/src/type.c index a4ab0285a7..27ac99a182 100644 --- a/racket/src/racket/src/type.c +++ b/racket/src/racket/src/type.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 e6b7640c89..3edcfe0d40 100644 --- a/racket/src/racket/src/validate.c +++ b/racket/src/racket/src/validate.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 ddaf1c8adb..4f58f759ff 100644 --- a/racket/src/racket/src/vector.c +++ b/racket/src/racket/src/vector.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2016 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 4285e87b35..a540f0f4fa 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-2015 PLT Design Inc.\0" + VALUE "LegalCopyright", "Copyright 1995-2016 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 4f5554d967..772d1cc57a 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-2015 PLT Design Inc." + VALUE "LegalCopyright", "Copyright 2000-2016 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 9bbc8a1fe7..284a817679 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-2015 PLT Design Inc.\0" + VALUE "LegalCopyright", "Copyright 1995-2016 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 cfec867857..48ff60773c 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-2015 PLT Design Inc.\0" + VALUE "LegalCopyright", "Copyright 1996-2016 PLT Design Inc.\0" #ifdef MRSTART VALUE "OriginalFilename", "MrStart.exe\0" #endif From be82c27db3294cb88e33d54211175bb0b158da7f Mon Sep 17 00:00:00 2001 From: Gustavo Massaccesi Date: Mon, 4 Jan 2016 14:30:37 -0300 Subject: [PATCH 366/369] fix bug in shifting of types during inlining During inlining, the type information gathered in code that was inside the lambda is copied to the outer context. But the coordinates of the type information were shifted in the wrong direction, so the type was assigned to the wrong variable. This bug is difficult to trigger, so the test is convoluted. Merge to v6.4 --- .../tests/racket/optimize.rktl | 28 +++++++++++++++++-- racket/src/racket/src/optimize.c | 6 ++-- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index 01ab2b1f16..df465a98f8 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -3629,6 +3629,30 @@ (set! f 0)) #f) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check that the type information is shifted in the +;; right direction while inlining. +;; The first example triggered a bug in 6.3. + +(test-comp '(let ([zz (lambda (x) (lambda (y) 0))]) + (lambda (a b c) + ((zz (let ([loop (lambda () 0)]) loop)) (car a)) + (list c (pair? c)))) + '(let ([zz (lambda (x) (lambda (y) 0))]) + (lambda (a b c) + ((zz (let ([loop (lambda () 0)]) loop)) (car a)) + (list c #t))) + #f) + +(test-comp '(let ([zz (lambda (x) (lambda (y) 0))]) + (lambda (a b c) + ((zz (let ([loop (lambda () 0)]) loop)) (car a)) + (list a (pair? a)))) + '(let ([zz (lambda (x) (lambda (y) 0))]) + (lambda (a b c) + ((zz (let ([loop (lambda () 0)]) loop)) (car a)) + (list a #t)))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Check that the unused continuations are removed @@ -4179,9 +4203,9 @@ (test-values '(-100001.0t0 100001.0t0) tail))) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Check for corect fixpoint calculation when lifting +;; Check for correct fixpoint calculation when lifting -;; This test is especilly fragile. It's a minimized(?) variant +;; This test is especially fragile. It's a minimized(?) variant ;; of PR 12910, where just enbought `with-continuation-mark's ;; are needed to thwart inlining, and enough functions are ;; present in the right order to require enough fixpoint diff --git a/racket/src/racket/src/optimize.c b/racket/src/racket/src/optimize.c index 3d700107e2..11cf2f1ac5 100644 --- a/racket/src/racket/src/optimize.c +++ b/racket/src/racket/src/optimize.c @@ -1959,7 +1959,7 @@ Scheme_Object *optimize_for_inline(Optimize_Info *info, Scheme_Object *le, int a id_offset, orig_le, prev); if (id_offset) { optimize_info_done(sub_info, NULL); - merge_types(sub_info, info, id_offset); + merge_types(sub_info, info, -id_offset); } return le; } else { @@ -5922,7 +5922,7 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline, i info->single_result = sub_info->single_result; info->preserves_marks = sub_info->preserves_marks; optimize_info_done(sub_info, NULL); - merge_types(sub_info, info, 1); + merge_types(sub_info, info, -1); } return form; @@ -5948,7 +5948,7 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline, i info->single_result = sub_info->single_result; info->preserves_marks = sub_info->preserves_marks; optimize_info_done(sub_info, NULL); - merge_types(sub_info, info, 1); + merge_types(sub_info, info, -1); return body; } } From 9498bdd80f16e9d962bbb6f06ecc8c10fa174f44 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 13 Jan 2016 19:53:24 -0700 Subject: [PATCH 367/369] make `raco distribute` work with non-writable exe Closes PR 15214 Merge to v6.4 --- racket/collects/compiler/distribute.rkt | 10 ++++++++- racket/collects/compiler/embed.rkt | 18 +--------------- .../collects/compiler/private/write-perm.rkt | 21 +++++++++++++++++++ 3 files changed, 31 insertions(+), 18 deletions(-) create mode 100644 racket/collects/compiler/private/write-perm.rkt diff --git a/racket/collects/compiler/distribute.rkt b/racket/collects/compiler/distribute.rkt index e486817b1c..e026d8023a 100644 --- a/racket/collects/compiler/distribute.rkt +++ b/racket/collects/compiler/distribute.rkt @@ -11,7 +11,8 @@ "private/macfw.rkt" "private/windlldir.rkt" "private/elf.rkt" - "private/collects-path.rkt") + "private/collects-path.rkt" + "private/write-perm.rkt") (provide assemble-distribution) @@ -59,6 +60,10 @@ orig-binaries sub-dirs types)] + [old-permss (and executables? + (eq? (system-type) 'unix) + (for/list ([b (in-list binaries)]) + (ensure-writable b)))] [single-mac-app? (and executables? (eq? 'macosx (cross-system-type)) (= 1 (length types)) @@ -150,6 +155,9 @@ exts-dir relative-exts-dir relative->binary-relative) + ;; Restore executable permissions: + (when old-permss + (map done-writable binaries old-permss)) ;; Done! (void)))))) diff --git a/racket/collects/compiler/embed.rkt b/racket/collects/compiler/embed.rkt index 00c783b475..9c58d28b80 100644 --- a/racket/collects/compiler/embed.rkt +++ b/racket/collects/compiler/embed.rkt @@ -21,6 +21,7 @@ "private/pe-rsrc.rkt" "private/collects-path.rkt" "private/configdir.rkt" + "private/write-perm.rkt" "find-exe.rkt") @@ -1804,20 +1805,3 @@ [(list? p) (map mac-mred-collects-path-adjust p)] [(relative-path? p) (build-path 'up 'up 'up p)] [else p])) - -;; Returns #f (no change needed) or old permissions -(define (ensure-writable dest-exe) - (cond - [(member 'write (file-or-directory-permissions dest-exe)) - ;; No change needed - #f] - [else - (define old-perms - (file-or-directory-permissions dest-exe 'bits)) - (file-or-directory-permissions dest-exe (bitwise-ior old-perms #o200)) - old-perms])) - -;; Restores old permissions (if not #f) -(define (done-writable dest-exe old-perms) - (when old-perms - (file-or-directory-permissions dest-exe old-perms))) diff --git a/racket/collects/compiler/private/write-perm.rkt b/racket/collects/compiler/private/write-perm.rkt new file mode 100644 index 0000000000..56fdb17885 --- /dev/null +++ b/racket/collects/compiler/private/write-perm.rkt @@ -0,0 +1,21 @@ +#lang racket/base + +(provide ensure-writable + done-writable) + +;; Returns #f (no change needed) or old permissions +(define (ensure-writable dest-exe) + (cond + [(member 'write (file-or-directory-permissions dest-exe)) + ;; No change needed + #f] + [else + (define old-perms + (file-or-directory-permissions dest-exe 'bits)) + (file-or-directory-permissions dest-exe (bitwise-ior old-perms #o200)) + old-perms])) + +;; Restores old permissions (if not #f) +(define (done-writable dest-exe old-perms) + (when old-perms + (file-or-directory-permissions dest-exe old-perms))) From 3cb100ba17e5a22effffa3d489853b2aa7ff11d8 Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Thu, 14 Jan 2016 17:15:22 -0500 Subject: [PATCH 368/369] Clean up stxparam interface --- racket/collects/racket/private/stxparam.rkt | 13 +------------ racket/collects/racket/private/stxparamkey.rkt | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/racket/collects/racket/private/stxparam.rkt b/racket/collects/racket/private/stxparam.rkt index 6fed01c96e..93a943b9d2 100644 --- a/racket/collects/racket/private/stxparam.rkt +++ b/racket/collects/racket/private/stxparam.rkt @@ -20,18 +20,7 @@ "not an identifier" stx id)) - (let*-values - ;; If it is a rename-transformer-parameter, then - ;; we need to get the parameter and not what it - ;; points to, otherwise, we can keep going. - ([(rt* rt-target) - (syntax-local-value/immediate id (lambda () #f))] - [(rt) (if (syntax-parameter? rt*) - rt* - (or rt-target rt*))] - [(sp) (if (set!-transformer? rt) - (set!-transformer-procedure rt) - rt)]) + (let ([sp (syntax-parameter-local-value id)]) (unless (syntax-parameter? sp) (raise-syntax-error #f diff --git a/racket/collects/racket/private/stxparamkey.rkt b/racket/collects/racket/private/stxparamkey.rkt index 8a597dfbfe..bbd82e118c 100644 --- a/racket/collects/racket/private/stxparamkey.rkt +++ b/racket/collects/racket/private/stxparamkey.rkt @@ -36,6 +36,21 @@ (define (syntax-parameter-target sp) (syntax-parameter-ref sp 1)) + ;; If it is a rename-transformer-parameter, then we need to get the + ;; parameter and not what it points to, otherwise, we can keep + ;; going. + (define (syntax-parameter-local-value id) + (let*-values + ([(rt* rt-target) + (syntax-local-value/immediate id (lambda () #f))] + [(rt) (if (syntax-parameter? rt*) + rt* + (or rt-target rt*))] + [(sp) (if (set!-transformer? rt) + (set!-transformer-procedure rt) + rt)]) + sp)) + (define (target-value target) (syntax-local-value (syntax-local-get-shadower target #t) (lambda () @@ -115,6 +130,7 @@ make-syntax-parameter rename-transformer-parameter? make-rename-transformer-parameter + syntax-parameter-local-value syntax-parameter-target syntax-parameter-target-value syntax-parameter-target-parameter)) From df29c4e7e283c4ace5034321c134e5c075b664ac Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Thu, 14 Jan 2016 17:26:46 -0500 Subject: [PATCH 369/369] adjust double splicing behavior of rename-transformer-parameter --- .../tests/racket/stxparam.rktl | 7 ++++++- .../collects/racket/private/stxparamkey.rkt | 20 +++++++++++++++++-- racket/collects/racket/splicing.rkt | 5 +---- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/stxparam.rktl b/pkgs/racket-test-core/tests/racket/stxparam.rktl index b8daa79546..179adf31dc 100644 --- a/pkgs/racket-test-core/tests/racket/stxparam.rktl +++ b/pkgs/racket-test-core/tests/racket/stxparam.rktl @@ -139,6 +139,7 @@ #`#,(syntax-local-value #'t)])) (define-syntax one 1) (define-syntax two 2) + (define-syntax three 3) (define-rename-transformer-parameter num (make-rename-transformer #'one)) (test #t = (slv num) 1) @@ -146,7 +147,11 @@ (test #t = (slv num) 2)) (splicing-syntax-parameterize ([num (make-rename-transformer #'two)]) (define too (slv num))) - (test #t = too 2)) + (test #t = too 2) + (splicing-syntax-parameterize ([num (make-rename-transformer #'two)]) + (splicing-syntax-parameterize ([num (make-rename-transformer #'three)]) + (define trois (slv num)))) + (test #t = trois 3)) ;; ---------------------------------------- diff --git a/racket/collects/racket/private/stxparamkey.rkt b/racket/collects/racket/private/stxparamkey.rkt index bbd82e118c..1faa3dc710 100644 --- a/racket/collects/racket/private/stxparamkey.rkt +++ b/racket/collects/racket/private/stxparamkey.rkt @@ -51,6 +51,22 @@ rt)]) sp)) + (define (syntax-parameter-local-value-pre id) + (define-values (rt* rt-target) (syntax-local-value/immediate id (λ () #f))) + (cond + [(not rt-target) + rt*] + [(syntax-parameter? rt*) + rt-target] + [(parameter-binding? rt*) + rt*] + [else + (syntax-parameter-local-value-pre rt-target)])) + + (define (syntax-parameter-local-value-for-parameter target) + (or (syntax-parameter-local-value-pre (syntax-local-get-shadower target #t)) + (syntax-parameter-local-value-pre target))) + (define (target-value target) (syntax-local-value (syntax-local-get-shadower target #t) (lambda () @@ -69,10 +85,10 @@ v)]) (if (wrapped-renamer? v) (wrapped-renamer-renamer v) - v))) + v))) (define (syntax-parameter-target-parameter target) - (let ([v (target-value target)]) + (let ([v (syntax-parameter-local-value-for-parameter target)]) (parameter-binding-param v))) (define (convert-renamer must-be-renamer?-stx v) diff --git a/racket/collects/racket/splicing.rkt b/racket/collects/racket/splicing.rkt index b911623deb..5096983a64 100644 --- a/racket/collects/racket/splicing.rkt +++ b/racket/collects/racket/splicing.rkt @@ -350,10 +350,7 @@ 'transparent)])) (define-for-syntax (parameter-of id) - (let* ([rt (syntax-local-value id)] - [sp (if (set!-transformer? rt) - (set!-transformer-procedure rt) - rt)]) + (let ([sp (syntax-parameter-local-value id)]) (syntax-parameter-target-parameter (syntax-parameter-target sp))))