1(module serialize racket/base 2 (require syntax/modcollapse 3 racket/struct 4 racket/list 5 racket/flonum 6 racket/fixnum 7 "relative-path.rkt" 8 "serialize-structs.rkt") 9 10 ;; This module implements the core serializer. The syntactic 11 ;; `define-serializable-struct' layer is implemented separately 12 ;; (and differently for old-style vs. new-style `define-struct'). 13 14 (provide prop:serializable 15 make-serialize-info 16 make-deserialize-info 17 18 ;; Checks whether a value is serializable: 19 serializable? 20 21 ;; The two main routines: 22 serialize 23 deserialize 24 25 serialized=? 26 27 deserialize-module-guard) 28 29 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 30 ;; serialize 31 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 32 33 (define (serializable? v) 34 (or (serializable-struct? v) 35 (and (struct? v) 36 (prefab-struct-key v) 37 #t) 38 (boolean? v) 39 (null? v) 40 (number? v) 41 (char? v) 42 (and (symbol? v) 43 (or (symbol-interned? v) 44 (eq? v (string->unreadable-symbol (symbol->string v))))) 45 (keyword? v) 46 (regexp? v) 47 (byte-regexp? v) 48 (string? v) 49 (path-for-some-system? v) 50 (bytes? v) 51 (vector? v) 52 (flvector? v) 53 (fxvector? v) 54 (pair? v) 55 (mpair? v) 56 (hash? v) 57 (box? v) 58 (void? v) 59 (date? v) 60 (arity-at-least? v) 61 (module-path-index? v) 62 (srcloc? v))) 63 64 ;; If a module is dynamic-required through a path, 65 ;; then it can cause simplified module paths to be paths; 66 ;; keep the literal path, but marshal it to bytes. 67 (define (protect-path p deser-path->relative-path) 68 (cond 69 [(path? p) (let ([rel (deser-path->relative-path p)]) 70 (if rel 71 `(relative . ,rel) 72 (path->bytes p)))] 73 [(and (pair? p) (eq? (car p) 'submod) (path? (cadr p))) 74 `(submod ,(protect-path (cadr p) deser-path->relative-path) . ,(cddr p))] 75 [else p])) 76 (define (unprotect-path p) 77 (cond 78 [(bytes? p) (bytes->path p)] 79 [(and (pair? p) (eq? (car p) 'submod) (or (bytes? (cadr p)) 80 (list? (cadr p)))) 81 `(submod ,(unprotect-path (cadr p)) . ,(cddr p))] 82 [(and (pair? p) (eq? (car p) 'relative)) 83 (relative-path-elements->path (cdr p))] 84 [else p])) 85 86 ;; A deserialization function is provided from a `deserialize-info` 87 ;; module: 88 (define (add-submodule p) 89 (module-path-index-join '(submod "." deserialize-info) 90 (if (resolved-module-path? p) 91 p 92 (module-path-index-join 93 p 94 #f)))) 95 96 (define (revive-symbol s) 97 (if (string? s) 98 (string->unreadable-symbol s) 99 s)) 100 101 (define deserialize-module-guard (make-parameter (lambda (mod-path sym) 102 (void)) 103 #f 104 'deserialize-module-guard)) 105 (define varref (#%variable-reference varref)) 106 107 (define (collapse/resolve-module-path-index mpi deser-path->relative-path) 108 (let ([v (collapse-module-path-index mpi deser-path->relative-path)]) 109 (if (path? v) 110 ;; If collapsing gives a path, then we can't do any better than 111 ;; resolving --- and we must resolved, because the mpi may record 112 ;; a more accurate path inside. 113 (let ([v2 (resolved-module-path-name (module-path-index-resolve mpi))]) 114 (if (symbol? v2) 115 `(quote ,v2) 116 v2)) 117 v))) 118 119 (define (mod-to-id info mod-map cache deser-path->relative-path) 120 (let ([deserialize-id (serialize-info-deserialize-id info)]) 121 (hash-ref 122 cache deserialize-id 123 (lambda () 124 (define id 125 (let ([path+name 126 (let loop ([deserialize-id deserialize-id]) 127 (cond 128 [(procedure? deserialize-id) 129 (loop (deserialize-id))] 130 [(identifier? deserialize-id) 131 (let ([b (identifier-binding deserialize-id (variable-reference->phase varref))]) 132 (cons 133 (and (list? b) 134 (if (symbol? (caddr b)) 135 (caddr b) 136 (protect-path 137 (collapse/resolve-module-path-index 138 (caddr b) 139 (build-path (serialize-info-dir info) 140 "here.ss")) 141 deser-path->relative-path))) 142 (syntax-e deserialize-id)))] 143 [(symbol? deserialize-id) 144 (cons #f deserialize-id)] 145 [else 146 (cons 147 (if (symbol? (cdr deserialize-id)) 148 (cdr deserialize-id) 149 (protect-path 150 (collapse/resolve-module-path-index 151 (cdr deserialize-id) 152 (build-path (serialize-info-dir info) 153 "here.ss")) 154 deser-path->relative-path)) 155 (car deserialize-id))]))]) 156 (hash-ref 157 mod-map path+name 158 (lambda () 159 (let ([id (hash-count mod-map)]) 160 (hash-set! mod-map path+name id) 161 id))))) 162 (hash-set! cache deserialize-id id) 163 id)))) 164 165 (define (is-mutable? o) 166 (or (and (or (mpair? o) 167 (box? o) 168 (vector? o) 169 (hash? o)) 170 (not (immutable? o))) 171 (and (serializable-struct? o) 172 (serialize-info-can-cycle? (serializable-info o))) 173 (flvector? o) 174 (fxvector? o) 175 (let ([k (prefab-struct-key o)]) 176 (and k 177 ;; Check whether all fields are mutable: 178 (pair? k) 179 (let-values ([(si skipped?) (struct-info o)]) 180 (let loop ([si si]) 181 (let*-values ([(name init auto acc mut imms super skipped?) (struct-type-info si)]) 182 (and (null? imms) 183 (or (not super) 184 (loop super)))))))))) 185 186 ;; Finds a mutable object among those that make the 187 ;; current cycle. 188 (define (find-mutable v cycle-stack share cycle) 189 ;; Walk back through cycle-stack to find something 190 ;; mutable. If we get to v without anything being 191 ;; mutable, then we're stuck. 192 (define (potentially-shared! v) 193 (unless (hash-ref share v #f) 194 (hash-set! share v (share-id share cycle)))) 195 (potentially-shared! v) 196 (let loop ([cycle-stack cycle-stack]) 197 (define o (car cycle-stack)) 198 (cond 199 [(eq? o v) 200 (error 'serialize "cannot serialize cycle of immutable values: ~e" v)] 201 [(is-mutable? o) 202 o] 203 [else 204 (potentially-shared! o) 205 (loop (cdr cycle-stack))]))) 206 207 208 (define (share-id share cycle) 209 (+ (hash-count share) 210 (hash-count cycle))) 211 212 ;; Traverses v to find cycles and sharing. Shared 213 ;; objects go in the `shared' table, and cycle-breakers go in 214 ;; `cycle'. In each case, the object is mapped to a number that is 215 ;; incremented as shared/cycle objects are discovered, so 216 ;; when the objects are deserialized, build them in reverse 217 ;; order. 218 (define (find-cycles-and-sharing v cycle share) 219 (let ([tmp-cycle (make-hasheq)] ;; candidates for sharing 220 [tmp-share (make-hasheq)] ;; candidates for cycles 221 [cycle-stack null]) ;; same as in tmpcycle, but for finding mutable 222 (let loop ([v v]) 223 (cond 224 [(or (boolean? v) 225 (number? v) 226 (char? v) 227 (symbol? v) 228 (keyword? v) 229 (null? v) 230 (void? v) 231 (srcloc? v)) 232 (void)] 233 [(hash-ref cycle v #f) 234 ;; We already know that this value is 235 ;; part of a cycle 236 (void)] 237 [(hash-ref tmp-cycle v #f) 238 ;; We've just learned that this value is 239 ;; part of a cycle. 240 (let ([mut-v (if (is-mutable? v) 241 v 242 (find-mutable v cycle-stack share cycle))]) 243 (unless (hash-ref cycle mut-v #f) 244 (hash-set! cycle mut-v (share-id share cycle))))] 245 [(hash-ref share v #f) 246 ;; We already know that this value is shared 247 (void)] 248 [(hash-ref tmp-share v #f) 249 ;; We've just learned that this value is 250 ;; shared 251 (hash-set! share v (share-id share cycle))] 252 [else 253 (hash-set! tmp-share v #t) 254 (hash-set! tmp-cycle v #t) 255 (set! cycle-stack (cons v cycle-stack)) 256 (cond 257 [(serializable-struct? v) 258 (let* ([info (serializable-info v)] 259 [vec ((serialize-info-vectorizer info) v)]) 260 (for ([x (in-vector vec)]) 261 (loop x)))] 262 [(and (struct? v) 263 (prefab-struct-key v)) 264 (for-each loop (struct->list v))] 265 [(or (string? v) 266 (bytes? v) 267 (regexp? v) 268 (byte-regexp? v) 269 (path-for-some-system? v)) 270 ;; No sub-structure 271 (void)] 272 [(vector? v) 273 (for ([x (in-vector v)]) 274 (loop x))] 275 [(flvector? v) (void)] 276 [(fxvector? v) (void)] 277 [(pair? v) 278 (loop (car v)) 279 (loop (cdr v))] 280 [(mpair? v) 281 (loop (mcar v)) 282 (loop (mcdr v))] 283 [(box? v) 284 (loop (unbox v))] 285 [(date*? v) 286 (for-each loop (take (struct->list v) 12))] 287 [(date? v) 288 (for-each loop (take (struct->list v) 10))] 289 [(hash? v) 290 (for ([(k v) (in-hash v)]) 291 (loop k) 292 (loop v))] 293 [(arity-at-least? v) 294 (loop (arity-at-least-value v))] 295 [(module-path-index? v) 296 (let-values ([(path base) (module-path-index-split v)]) 297 (loop path) 298 (loop base))] 299 [else (raise-argument-error 300 'serialize 301 "serializable?" 302 v)]) 303 ;; No more possibility for this object in 304 ;; a cycle: 305 (hash-remove! tmp-cycle v) 306 (set! cycle-stack (cdr cycle-stack))])))) 307 308 (define (quotable? v) 309 (if (pair? v) 310 (eq? (car v) 'q) 311 (or (boolean? v) 312 (number? v) 313 (char? v) 314 (null? v) 315 (string? v) 316 (symbol? v) 317 (keyword? v) 318 (regexp? v) 319 (byte-regexp? v) 320 (bytes? v)))) 321 322 (define (serialize-one v share check-share? mod-map mod-map-cache path->relative-path deser-path->relative-path) 323 (define ((serial check-share?) v) 324 (cond 325 [(or (boolean? v) 326 (number? v) 327 (char? v) 328 (null? v) 329 (keyword? v)) 330 v] 331 [(symbol? v) 332 (if (symbol-interned? v) 333 v 334 (cons 'su (symbol->string v)))] 335 [(void? v) 336 '(void)] 337 [(and check-share? 338 (hash-ref share v #f)) 339 => (lambda (v) (cons '? v))] 340 [(and (or (string? v) 341 (bytes? v)) 342 (immutable? v)) 343 v] 344 [(or (regexp? v) 345 (byte-regexp? v)) 346 v] 347 [(serializable-struct? v) 348 (let ([info (serializable-info v)]) 349 (cons (mod-to-id info mod-map mod-map-cache deser-path->relative-path) 350 (let ([loop (serial #t)] 351 [vec ((serialize-info-vectorizer info) v)]) 352 (for/list ([x (in-vector vec)]) 353 (loop x)))))] 354 [(and (struct? v) 355 (prefab-struct-key v)) 356 => (lambda (k) 357 (cons 'f 358 (cons 359 k 360 (map (serial #t) (struct->list v)))))] 361 [(or (string? v) 362 (bytes? v)) 363 (cons 'u v)] 364 [(path-for-some-system? v) 365 (let ([v-rel (and (path? v) (path->relative-path v))]) 366 (if v-rel 367 (cons 'p* v-rel) 368 (list* 'p+ (path->bytes v) (path-convention-type v))))] 369 [(vector? v) 370 (define elems 371 (let ([loop (serial #t)]) 372 (for/list ([x (in-vector v)]) 373 (loop x)))) 374 (if (and (immutable? v) 375 (andmap quotable? elems)) 376 (cons 'q v) 377 (cons (if (immutable? v) 'v 'v!) elems))] 378 [(flvector? v) 379 (cons 'vl (for/list ([i (in-flvector v)]) i))] 380 [(fxvector? v) 381 (cons 'vx (for/list ([i (in-fxvector v)]) i))] 382 [(pair? v) 383 (let ([loop (serial #t)]) 384 (let ([a (loop (car v))] 385 [d (loop (cdr v))]) 386 (cond 387 [(and (quotable? a) (quotable? d)) 388 (cons 'q v)] 389 [else 390 (cons 'c (cons a d))])))] 391 [(mpair? v) 392 (let ([loop (serial #t)]) 393 (cons 'm 394 (cons (loop (mcar v)) 395 (loop (mcdr v)))))] 396 [(box? v) 397 (cons (if (immutable? v) 'b 'b!) 398 ((serial #t) (unbox v)))] 399 [(hash? v) 400 (list* 'h 401 (if (immutable? v) '- '!) 402 (append 403 (if (hash-equal? v) '(equal) null) 404 (if (hash-eqv? v) '(eqv) null) 405 (if (hash-weak? v) '(weak) null)) 406 (let ([loop (serial #t)]) 407 (for/list ([(k v) (in-hash v)]) 408 (cons (loop k) 409 (loop v)))))] 410 [(date*? v) 411 (cons 'date* 412 (map (serial #t) (take (struct->list v) 12)))] 413 [(date? v) 414 (cons 'date 415 (map (serial #t) (take (struct->list v) 10)))] 416 [(arity-at-least? v) 417 (cons 'arity-at-least 418 ((serial #t) (arity-at-least-value v)))] 419 [(module-path-index? v) 420 (let-values ([(path base) (module-path-index-split v)]) 421 (cons 'mpi 422 (cons ((serial #t) path) 423 ((serial #t) base))))] 424 [(srcloc? v) 425 (cons 'srcloc 426 (map (serial #t) (take (struct->list v) 5)))] 427 [else (error 'serialize "shouldn't get here")])) 428 ((serial check-share?) v)) 429 430 (define (serial-shell v mod-map mod-map-cache deser-path->relative-path) 431 (cond 432 [(serializable-struct? v) 433 (let ([info (serializable-info v)]) 434 (mod-to-id info mod-map mod-map-cache deser-path->relative-path))] 435 [(vector? v) 436 (cons 'v (vector-length v))] 437 [(mpair? v) 438 'm] 439 [(box? v) 440 'b] 441 [(hash? v) 442 (cons 'h (append 443 (if (hash-equal? v) '(equal) null) 444 (if (hash-eqv? v) '(eqv) null) 445 (if (hash-weak? v) '(weak) null)))] 446 [else 447 ;; A mutable prefab 448 (cons 'pf (cons (prefab-struct-key v) 449 (sub1 (vector-length (struct->vector v)))))])) 450 451 (define (serialize v 452 #:relative-directory [rel-to #f] 453 #:deserialize-relative-directory [deser-rel-to rel-to]) 454 (let ([mod-map (make-hasheq)] 455 [mod-map-cache (make-hash)] 456 [share (make-hasheq)] 457 [cycle (make-hasheq)] 458 [path->relative-path (make-path->relative-path-elements rel-to #:who 'serialize)] 459 [deser-path->relative-path (make-path->relative-path-elements deser-rel-to #:who 'serialize)]) 460 ;; First, traverse V to find cycles and sharing 461 (find-cycles-and-sharing v cycle share) 462 ;; To simplify, all add the cycle records to shared. 463 ;; (but keep cycle info, too). 464 (hash-for-each cycle 465 (lambda (k v) 466 (hash-set! share k v))) 467 (let ([ordered (map car (sort (hash-map share cons) 468 (lambda (a b) (< (cdr a) (cdr b)))))]) 469 (let ([serializeds (map (lambda (v) 470 (if (hash-ref cycle v #f) 471 ;; Box indicates cycle record allocation 472 ;; followed by normal serialization 473 (box (serial-shell v mod-map mod-map-cache deser-path->relative-path)) 474 ;; Otherwise, normal serialization 475 (serialize-one v share #f mod-map mod-map-cache path->relative-path deser-path->relative-path))) 476 ordered)] 477 [fixups (hash-map 478 cycle 479 (lambda (v n) 480 (cons n 481 (serialize-one v share #f mod-map mod-map-cache path->relative-path deser-path->relative-path))))] 482 [main-serialized (serialize-one v share #t mod-map mod-map-cache path->relative-path deser-path->relative-path)] 483 [mod-map-l (map car (sort (hash-map mod-map cons) 484 (lambda (a b) (< (cdr a) (cdr b)))))]) 485 (list (if (or rel-to deser-rel-to) '(4) '(3)) ;; serialization-format version 486 (hash-count mod-map) 487 (map (lambda (v) (if (symbol-interned? (cdr v)) 488 v 489 (cons (car v) (symbol->string (cdr v))))) 490 mod-map-l) 491 (length serializeds) 492 serializeds 493 fixups 494 main-serialized))))) 495 496 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 497 ;; deserialize 498 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 499 500 (define (make-hash/flags v) 501 (if (null? v) 502 (make-hasheq) 503 (case (car v) 504 [(equal) 505 (if (null? (cdr v)) 506 (make-hash) 507 (make-weak-hash))] 508 [(eqv) 509 (if (null? (cdr v)) 510 (make-hasheqv) 511 (make-weak-hasheqv))] 512 [(weak) 513 (make-weak-hasheq)]))) 514 515 (define-struct not-ready (shares fixup)) 516 517 (define (lookup-shared! share n mod-map module-path-index-join) 518 ;; The shared list is not necessarily in order of 519 ;; referreds before referees. A `not-ready' object 520 ;; indicates a reference before a value is ready, 521 ;; so we need to recur to make it ready. Cycles 522 ;; have been broken, though, so we don't run into 523 ;; trouble with an infinite loop here. 524 (let ([sv (vector-ref share n)]) 525 (if (not-ready? sv) 526 (let* ([v (vector-ref (not-ready-shares sv) n)] 527 [val (if (box? v) 528 (deserial-shell (unbox v) mod-map (not-ready-fixup sv) n) 529 (deserialize-one v share mod-map module-path-index-join))]) 530 (vector-set! share n val) 531 val) 532 sv))) 533 534 (define (deserialize-one v share mod-map module-path-index-join) 535 (let loop ([v v]) 536 (cond 537 [(or (boolean? v) 538 (number? v) 539 (char? v) 540 (symbol? v) 541 (keyword? v) 542 (regexp? v) 543 (byte-regexp? v) 544 (null? v)) 545 v] 546 [(string? v) 547 (string->immutable-string v)] 548 [(bytes? v) 549 (bytes->immutable-bytes v)] 550 [(number? (car v)) 551 ;; Struct instance: 552 (let ([info (vector-ref mod-map (car v))]) 553 (apply (deserialize-info-maker info) (map loop (cdr v))))] 554 [else 555 (case (car v) 556 [(?) (lookup-shared! share (cdr v) mod-map module-path-index-join)] 557 [(q) (cdr v)] 558 [(f) (apply make-prefab-struct (cadr v) (map loop (cddr v)))] 559 [(void) (void)] 560 [(su) (string->unreadable-symbol (cdr v))] 561 [(u) (let ([x (cdr v)]) 562 (cond 563 [(string? x) (string-copy x)] 564 [(bytes? x) (bytes-copy x)]))] 565 [(p) (bytes->path (cdr v))] 566 [(p+) (bytes->path (cadr v) (cddr v))] 567 [(p*) (relative-path-elements->path (cdr v))] 568 [(c) (cons (loop (cadr v)) (loop (cddr v)))] 569 [(c!) (cons (loop (cadr v)) (loop (cddr v)))] 570 [(m) (mcons (loop (cadr v)) (loop (cddr v)))] 571 [(v) (apply vector-immutable (map loop (cdr v)))] 572 [(v!) (list->vector (map loop (cdr v)))] 573 [(vl) (apply flvector (map loop (cdr v)))] 574 [(vx) (apply fxvector (map loop (cdr v)))] 575 [(b) (box-immutable (loop (cdr v)))] 576 [(b!) (box (loop (cdr v)))] 577 [(h) (let ([al (map (lambda (p) 578 (cons (loop (car p)) 579 (loop (cdr p)))) 580 (cdddr v))]) 581 (if (eq? '! (cadr v)) 582 (let ([ht (make-hash/flags (caddr v))]) 583 (for-each (lambda (p) 584 (hash-set! ht (car p) (cdr p))) 585 al) 586 ht) 587 (if (null? (caddr v)) 588 (make-immutable-hasheq al) 589 (if (eq? (caaddr v) 'equal) 590 (make-immutable-hash al) 591 (make-immutable-hasheqv al)))))] 592 [(date) (apply make-date (map loop (cdr v)))] 593 [(date*) (apply make-date* (map loop (cdr v)))] 594 [(arity-at-least) (make-arity-at-least (loop (cdr v)))] 595 [(mpi) (module-path-index-join (loop (cadr v)) 596 (loop (cddr v)))] 597 [(srcloc) (apply make-srcloc (map loop (cdr v)))] 598 [else (error 'serialize "ill-formed serialization")])]))) 599 600 (define (deserial-shell v mod-map fixup n) 601 (cond 602 [(number? v) 603 ;; Struct instance 604 (let* ([info (vector-ref mod-map v)]) 605 (let-values ([(obj fix) ((deserialize-info-cycle-maker info))]) 606 (vector-set! fixup n fix) 607 obj))] 608 [(pair? v) 609 (case (car v) 610 [(v) 611 ;; Vector 612 (let* ([m (cdr v)] 613 [v0 (make-vector m #f)]) 614 (vector-set! fixup n (lambda (v) 615 (let loop ([i m]) 616 (unless (zero? i) 617 (let ([i (sub1 i)]) 618 (vector-set! v0 i (vector-ref v i)) 619 (loop i)))))) 620 v0)] 621 [(h) 622 ;; Hash table 623 (let ([ht0 (make-hash/flags (cdr v))]) 624 (vector-set! fixup n (lambda (ht) 625 (for ([(k v) (in-hash ht)]) 626 (hash-set! ht0 k v)))) 627 ht0)] 628 [(pf) 629 ;; Prefab 630 (let ([s (apply make-prefab-struct 631 (cadr v) 632 (make-list (cddr v) #f))]) 633 (vector-set! fixup n (lambda (v) 634 (let-values ([(si skipped?) (struct-info s)]) 635 (let loop ([si si]) 636 (let*-values ([(name init auto acc mut imms super skipped?) (struct-type-info si)]) 637 (let ([count (+ init auto)]) 638 (for ([i (in-range 0 count)]) 639 (mut s i (acc v i))) 640 (when super 641 (loop super)))))))) 642 s)])] 643 [else 644 (case v 645 [(c) 646 (let ([c (cons #f #f)]) 647 (vector-set! fixup n (lambda (p) 648 (error 'deserialize "cannot restore pair in cycle"))) 649 c)] 650 [(m) 651 (let ([p0 (mcons #f #f)]) 652 (vector-set! fixup n (lambda (p) 653 (set-mcar! p0 (mcar p)) 654 (set-mcdr! p0 (mcdr p)))) 655 p0)] 656 [(b) 657 (let ([b0 (box #f)]) 658 (vector-set! fixup n (lambda (b) 659 (set-box! b0 (unbox b)))) 660 b0)] 661 [(date) 662 (error 'deserialize "cannot restore date in cycle")] 663 [(arity-at-least) 664 (error 'deserialize "cannot restore arity-at-least in cycle")] 665 [(mpi) 666 (error 'deserialize "cannot restore module-path-index in cycle")])])) 667 668 (define (deserialize-with-map mod-map vers l module-path-index-join) 669 (let ([share-n (list-ref l 2)] 670 [shares (list-ref l 3)] 671 [fixups (list-ref l 4)] 672 [result (list-ref l 5)]) 673 ;; Create vector for sharing: 674 (let* ([fixup (make-vector share-n #f)] 675 [share (make-vector share-n (make-not-ready 676 (list->vector shares) 677 fixup))]) 678 ;; Deserialize into sharing array: 679 (let loop ([n 0][l shares]) 680 (unless (= n share-n) 681 (lookup-shared! share n mod-map module-path-index-join) 682 (loop (add1 n) (cdr l)))) 683 ;; Fixup shell for graphs 684 (for-each (lambda (n+v) 685 (let ([v (deserialize-one (cdr n+v) share mod-map module-path-index-join)]) 686 ((vector-ref fixup (car n+v)) v))) 687 fixups) 688 ;; Deserialize final result. (If there's no sharing, then 689 ;; all the work is actually here.) 690 (deserialize-one result share mod-map module-path-index-join)))) 691 692 (define (extract-version l) 693 (if (pair? (car l)) 694 (values (caar l) (cdr l)) 695 (values 0 l))) 696 697 (define (deserialize l) 698 (let-values ([(vers l) (extract-version l)]) 699 (let ([mod-map (make-vector (list-ref l 0))] 700 [mod-map-l (list-ref l 1)]) 701 ;; Load constructor mapping 702 (let loop ([n 0][l mod-map-l]) 703 (unless (null? l) 704 (let* ([path+name (car l)] 705 [des (if (car path+name) 706 (let ([serial-p (unprotect-path (car path+name))] 707 [serial-sym (revive-symbol (cdr path+name))]) 708 (define maybe-binding ((deserialize-module-guard) serial-p serial-sym)) 709 (define p (if (pair? maybe-binding) (car maybe-binding) serial-p)) 710 (define sym (if (pair? maybe-binding) (cdr maybe-binding) serial-sym)) 711 (let ([sub (add-submodule p)] 712 [fallback 713 (lambda () 714 ;; On failure, for backward compatibility, 715 ;; try module instead of submodule: 716 (dynamic-require p sym))]) 717 (if (module-declared? sub #t) 718 (dynamic-require sub sym fallback) 719 (fallback)))) 720 (namespace-variable-value (cdr path+name)))]) 721 ;; Register maker and struct type: 722 (vector-set! mod-map n des)) 723 (loop (add1 n) (cdr l)))) 724 (deserialize-with-map mod-map vers l module-path-index-join)))) 725 726 ;; ---------------------------------------- 727 728 (define (serialized=? l1 l2) 729 (let-values ([(vers1 l1) (extract-version l1)] 730 [(vers2 l2) (extract-version l2)]) 731 (let ([mod-map1 (make-vector (list-ref l1 0))] 732 [mod-map1-l (list-ref l1 1)] 733 [mod-map2 (make-vector (list-ref l2 0))] 734 [mod-map2-l (list-ref l2 1)] 735 [make-key (lambda (path+name) 736 (if (car path+name) 737 (let ([p (unprotect-path (car path+name))] 738 [sym (revive-symbol (cdr path+name))]) 739 (list p sym)) 740 (list #f (cdr path+name))))] 741 [mpi-key (gensym)]) 742 (let ([keys1 (map make-key mod-map1-l)] 743 [keys2 (map make-key mod-map2-l)] 744 [ht (make-hash)] 745 [mpij (lambda (a b) (vector mpi-key a b))]) 746 (for-each (lambda (key) 747 (unless (hash-ref ht key #f) 748 (hash-set! ht key (gensym)))) 749 (append keys1 keys2)) 750 (for-each (lambda (mod-map keys) 751 (let loop ([n 0][l keys]) 752 (unless (null? l) 753 (let ([sym (hash-ref ht (car l))]) 754 (vector-set! mod-map n 755 (make-deserialize-info 756 (lambda args 757 (vector sym (list->vector args))) 758 (lambda () 759 (let ([v (vector sym #f)]) 760 (values v 761 (lambda (vec) 762 (vector-set! v 1 (vector-ref vec 1))))))))) 763 (loop (add1 n) (cdr l))))) 764 (list mod-map1 mod-map2) 765 (list keys1 keys2)) 766 (let ([v1 (deserialize-with-map mod-map1 vers1 l1 mpij)] 767 [v2 (deserialize-with-map mod-map2 vers2 l2 mpij)]) 768 (equal? v1 v2))))))) 769