/collects/compiler/zo-parse.rkt

http://github.com/gmarceau/PLT · Racket · 1064 lines · 19 code · 11 blank · 1034 comment · 0 complexity · badbf3ca5f76164d6bc1e532cbc66842 MD5 · raw file

  1. #lang racket/base
  2. (require racket/function
  3. racket/match
  4. racket/list
  5. unstable/struct
  6. compiler/zo-structs
  7. racket/dict
  8. racket/set)
  9. (provide zo-parse)
  10. (provide (all-from-out compiler/zo-structs))
  11. #| Unresolved Issues
  12. The order of indirect-et-provides, indirect-syntax-provides, indirect-provides was changed, is that okay?
  13. orig-port of cport struct is never used, is it needed?
  14. Lines 628, 630 seem to be only for debugging and should probably throw errors
  15. vector and pair cases of decode-wraps seem to do different things from the corresponding C code
  16. Line 816: This should be an eqv placeholder (but they don't exist)
  17. Line 634: Export registry is always matched as false, but might not be
  18. What are the real differences between the module-binding cases?
  19. I think parse-module-path-index was only used for debugging, so it is short-circuited now
  20. |#
  21. ;; ----------------------------------------
  22. ;; Bytecode unmarshalers for various forms
  23. (define (read-toplevel v)
  24. (define SCHEME_TOPLEVEL_CONST #x01)
  25. (define SCHEME_TOPLEVEL_READY #x02)
  26. (match v
  27. [(cons depth (cons pos flags))
  28. (make-toplevel depth pos
  29. (positive? (bitwise-and flags SCHEME_TOPLEVEL_CONST))
  30. (positive? (bitwise-and flags SCHEME_TOPLEVEL_READY)))]
  31. [(cons depth pos)
  32. (make-toplevel depth pos #f #f)]))
  33. (define (read-topsyntax v)
  34. (match v
  35. [`(,depth ,pos . ,midpt)
  36. (make-topsyntax depth pos midpt)]))
  37. (define (read-variable v)
  38. (if (symbol? v)
  39. (make-global-bucket v)
  40. (error "expected a symbol")))
  41. (define (do-not-read-variable v)
  42. (error "should not get here"))
  43. (define (read-compilation-top v)
  44. (match v
  45. [`(,ld ,prefix . ,code)
  46. (unless (prefix? prefix)
  47. (error 'bad "not prefix ~a" prefix))
  48. (make-compilation-top ld prefix code)]))
  49. (define (read-resolve-prefix v)
  50. (let-values ([(v unsafe?) (if (integer? (car v))
  51. (values v #f)
  52. (values (cdr v) #t))])
  53. (match v
  54. [`(,i ,tv . ,sv)
  55. ; XXX Why not leave them as vectors and change the contract?
  56. (make-prefix i (vector->list tv) (vector->list sv))])))
  57. (define read-free-id-info
  58. (match-lambda
  59. [(vector mpi0 symbol0 mpi1 symbol1 num0 num1 num2 bool0) ; I have no idea what these mean
  60. (make-free-id-info mpi0 symbol0 mpi1 symbol1 num0 num1 num2 bool0)]))
  61. (define (read-unclosed-procedure v)
  62. (define CLOS_HAS_REST 1)
  63. (define CLOS_HAS_REF_ARGS 2)
  64. (define CLOS_PRESERVES_MARKS 4)
  65. (define CLOS_NEED_REST_CLEAR 8)
  66. (define CLOS_IS_METHOD 16)
  67. (define CLOS_SINGLE_RESULT 32)
  68. (define BITS_PER_MZSHORT 32)
  69. (match v
  70. [`(,flags ,num-params ,max-let-depth ,tl-map ,name ,v . ,rest)
  71. (let ([rest? (positive? (bitwise-and flags CLOS_HAS_REST))])
  72. (let*-values ([(closure-size closed-over body)
  73. (if (zero? (bitwise-and flags CLOS_HAS_REF_ARGS))
  74. (values (vector-length v) v rest)
  75. (values v (car rest) (cdr rest)))]
  76. [(check-bit) (lambda (i)
  77. (if (zero? (bitwise-and flags CLOS_HAS_REF_ARGS))
  78. 0
  79. (let ([byte (vector-ref closed-over
  80. (+ closure-size (quotient (* 2 i) BITS_PER_MZSHORT)))])
  81. (+ (if (bitwise-bit-set? byte (remainder (* 2 i) BITS_PER_MZSHORT))
  82. 1
  83. 0)
  84. (if (bitwise-bit-set? byte (add1 (remainder (* 2 i) BITS_PER_MZSHORT)))
  85. 2
  86. 0)))))]
  87. [(arg-types) (let ([num-params ((if rest? sub1 values) num-params)])
  88. (for/list ([i (in-range num-params)])
  89. (case (check-bit i)
  90. [(0) 'val]
  91. [(1) 'ref]
  92. [(2) 'flonum])))]
  93. [(closure-types) (for/list ([i (in-range closure-size)]
  94. [j (in-naturals num-params)])
  95. (case (check-bit j)
  96. [(0) 'val/ref]
  97. [(2) 'flonum]))])
  98. (make-lam name
  99. (append
  100. (if (zero? (bitwise-and flags flags CLOS_PRESERVES_MARKS)) null '(preserves-marks))
  101. (if (zero? (bitwise-and flags flags CLOS_IS_METHOD)) null '(is-method))
  102. (if (zero? (bitwise-and flags flags CLOS_SINGLE_RESULT)) null '(single-result))
  103. (if (zero? (bitwise-and flags flags CLOS_NEED_REST_CLEAR)) null '(sfs-clear-rest-args))
  104. (if (and rest? (zero? num-params)) '(only-rest-arg-not-used) null))
  105. (if (and rest? (num-params . > . 0))
  106. (sub1 num-params)
  107. num-params)
  108. arg-types
  109. rest?
  110. (if (= closure-size (vector-length closed-over))
  111. closed-over
  112. (let ([v2 (make-vector closure-size)])
  113. (vector-copy! v2 0 closed-over 0 closure-size)
  114. v2))
  115. closure-types
  116. (and tl-map
  117. (let* ([bits (if (exact-integer? tl-map)
  118. tl-map
  119. (for/fold ([i 0]) ([v (in-vector tl-map)]
  120. [s (in-naturals)])
  121. (bitwise-ior i (arithmetic-shift v (* s 16)))))]
  122. [len (integer-length bits)])
  123. (list->set
  124. (let loop ([bit 0])
  125. (cond
  126. [(bit . >= . len) null]
  127. [(bitwise-bit-set? bits bit)
  128. (cons bit (loop (add1 bit)))]
  129. [else (loop (add1 bit))])))))
  130. max-let-depth
  131. body)))]))
  132. (define (read-let-value v)
  133. (match v
  134. [`(,count ,pos ,boxes? ,rhs . ,body)
  135. (make-install-value count pos boxes? rhs body)]))
  136. (define (read-let-void v)
  137. (match v
  138. [`(,count ,boxes? . ,body)
  139. (make-let-void count boxes? body)]))
  140. (define (read-letrec v)
  141. (match v
  142. [`(,count ,body . ,procs)
  143. (make-let-rec procs body)]))
  144. (define (read-with-cont-mark v)
  145. (match v
  146. [`(,key ,val . ,body)
  147. (make-with-cont-mark key val body)]))
  148. (define (read-sequence v)
  149. (make-seq v))
  150. ; XXX Allocates unnessary list
  151. (define (read-define-values v)
  152. (make-def-values
  153. (cdr (vector->list v))
  154. (vector-ref v 0)))
  155. ; XXX Allocates unnessary list
  156. (define (read-define-syntaxes mk v)
  157. (mk (list-tail (vector->list v) 4)
  158. (vector-ref v 0)
  159. (vector-ref v 1)
  160. (vector-ref v 2)
  161. #;(vector-ref v 3)))
  162. (define (read-define-syntax v)
  163. (read-define-syntaxes make-def-syntaxes v))
  164. (define (read-define-for-syntax v)
  165. (read-define-syntaxes make-def-for-syntax v))
  166. (define (read-set! v)
  167. (make-assign (cadr v) (cddr v) (car v)))
  168. (define (read-case-lambda v)
  169. (make-case-lam (car v) (cdr v)))
  170. (define (read-begin0 v)
  171. (make-beg0 v))
  172. (define (read-boxenv v)
  173. (make-boxenv (car v) (cdr v)))
  174. (define (read-require v)
  175. (make-req (cdr v) (car v)))
  176. (define (read-#%variable-ref v)
  177. (make-varref (car v) (cdr v)))
  178. (define (read-apply-values v)
  179. (make-apply-values (car v) (cdr v)))
  180. (define (read-splice v)
  181. (make-splice v))
  182. (define (in-list* l n)
  183. (make-do-sequence
  184. (lambda ()
  185. (values (lambda (l) (apply values (take l n)))
  186. (lambda (l) (drop l n))
  187. l
  188. (lambda (l) (>= (length l) n))
  189. (lambda _ #t)
  190. (lambda _ #t)))))
  191. (define (read-module v)
  192. (match v
  193. [`(,name ,srcname ,self-modidx ,lang-info ,functional? ,et-functional?
  194. ,rename ,max-let-depth ,dummy
  195. ,prefix
  196. ,indirect-et-provides ,num-indirect-et-provides
  197. ,indirect-syntax-provides ,num-indirect-syntax-provides
  198. ,indirect-provides ,num-indirect-provides
  199. ,protects ,et-protects
  200. ,provide-phase-count . ,rest)
  201. (let ([phase-data (take rest (* 8 provide-phase-count))])
  202. (match (list-tail rest (* 8 provide-phase-count))
  203. [`(,syntax-body ,body
  204. ,requires ,syntax-requires ,template-requires ,label-requires
  205. ,more-requires-count . ,more-requires)
  206. (make-mod name srcname self-modidx
  207. prefix (let loop ([l phase-data])
  208. (if (null? l)
  209. null
  210. (let ([num-vars (list-ref l 6)]
  211. [ps (for/list ([name (in-vector (list-ref l 5))]
  212. [src (in-vector (list-ref l 4))]
  213. [src-name (in-vector (list-ref l 3))]
  214. [nom-src (or (list-ref l 2)
  215. (in-cycle (in-value #f)))]
  216. [src-phase (or (list-ref l 1)
  217. (in-cycle (in-value #f)))]
  218. [protected? (or (case (car l)
  219. [(0) protects]
  220. [(1) et-protects]
  221. [else #f])
  222. (in-cycle (in-value #f)))])
  223. (make-provided name src src-name
  224. (or nom-src src)
  225. (if src-phase 1 0)
  226. protected?))])
  227. (if (null? ps)
  228. (loop (list-tail l 8))
  229. (cons
  230. (list
  231. (car l)
  232. (take ps num-vars)
  233. (drop ps num-vars))
  234. (loop (list-tail l 8)))))))
  235. (list*
  236. (cons 0 requires)
  237. (cons 1 syntax-requires)
  238. (cons -1 template-requires)
  239. (cons #f label-requires)
  240. (for/list ([(phase reqs) (in-list* more-requires 2)])
  241. (cons phase reqs)))
  242. (vector->list body)
  243. (map (lambda (sb)
  244. (match sb
  245. [(? def-syntaxes?) sb]
  246. [(? def-for-syntax?) sb]
  247. [`#(,ids ,expr ,max-let-depth ,prefix ,for-stx?)
  248. ((if for-stx?
  249. make-def-for-syntax
  250. make-def-syntaxes)
  251. (if (list? ids) ids (list ids)) expr prefix max-let-depth)]))
  252. (vector->list syntax-body))
  253. (list (vector->list indirect-provides)
  254. (vector->list indirect-syntax-provides)
  255. (vector->list indirect-et-provides))
  256. max-let-depth
  257. dummy
  258. lang-info
  259. rename)]))]))
  260. (define (read-module-wrap v)
  261. v)
  262. ;; ----------------------------------------
  263. ;; Unmarshal dispatch for various types
  264. ;; Type mappings from "stypes.h":
  265. (define (int->type i)
  266. (case i
  267. [(0) 'toplevel-type]
  268. [(6) 'sequence-type]
  269. [(8) 'unclosed-procedure-type]
  270. [(9) 'let-value-type]
  271. [(10) 'let-void-type]
  272. [(11) 'letrec-type]
  273. [(13) 'with-cont-mark-type]
  274. [(14) 'quote-syntax-type]
  275. [(15) 'define-values-type]
  276. [(16) 'define-syntaxes-type]
  277. [(17) 'define-for-syntax-type]
  278. [(18) 'set-bang-type]
  279. [(19) 'boxenv-type]
  280. [(20) 'begin0-sequence-type]
  281. [(21) 'splice-sequence-type]
  282. [(22) 'require-form-type]
  283. [(23) 'varref-form-type]
  284. [(24) 'apply-values-type]
  285. [(25) 'case-lambda-sequence-type]
  286. [(26) 'module-type]
  287. [(34) 'variable-type]
  288. [(35) 'module-variable-type]
  289. [(112) 'resolve-prefix-type]
  290. [(161) 'free-id-info-type]
  291. [else (error 'int->type "unknown type: ~e" i)]))
  292. (define type-readers
  293. (make-immutable-hash
  294. (list
  295. (cons 'toplevel-type read-toplevel)
  296. (cons 'sequence-type read-sequence)
  297. (cons 'unclosed-procedure-type read-unclosed-procedure)
  298. (cons 'let-value-type read-let-value)
  299. (cons 'let-void-type read-let-void)
  300. (cons 'letrec-type read-letrec)
  301. (cons 'with-cont-mark-type read-with-cont-mark)
  302. (cons 'quote-syntax-type read-topsyntax)
  303. (cons 'variable-type read-variable)
  304. (cons 'module-variable-type do-not-read-variable)
  305. (cons 'compilation-top-type read-compilation-top)
  306. (cons 'case-lambda-sequence-type read-case-lambda)
  307. (cons 'begin0-sequence-type read-begin0)
  308. (cons 'module-type read-module)
  309. (cons 'resolve-prefix-type read-resolve-prefix)
  310. (cons 'free-id-info-type read-free-id-info)
  311. (cons 'define-values-type read-define-values)
  312. (cons 'define-syntaxes-type read-define-syntax)
  313. (cons 'define-for-syntax-type read-define-for-syntax)
  314. (cons 'set-bang-type read-set!)
  315. (cons 'boxenv-type read-boxenv)
  316. (cons 'require-form-type read-require)
  317. (cons 'varref-form-type read-#%variable-ref)
  318. (cons 'apply-values-type read-apply-values)
  319. (cons 'sequence-splice-type read-splice))))
  320. (define (get-reader type)
  321. (hash-ref type-readers type
  322. (λ ()
  323. (error 'read-marshalled "reader for ~a not implemented" type))))
  324. ;; ----------------------------------------
  325. ;; Lowest layer of bytecode parsing
  326. (define (split-so all-short so)
  327. (define n (if (zero? all-short) 4 2))
  328. (let loop ([so so])
  329. (if (zero? (bytes-length so))
  330. null
  331. (cons (integer-bytes->integer (subbytes so 0 n) #f #f)
  332. (loop (subbytes so n))))))
  333. (define (read-simple-number p)
  334. (integer-bytes->integer (read-bytes 4 p) #f #f))
  335. (define-struct cport ([pos #:mutable] shared-start orig-port size bytes-start symtab shared-offsets decoded rns mpis))
  336. (define (cport-get-bytes cp len)
  337. (define port (cport-orig-port cp))
  338. (define pos (cport-pos cp))
  339. (file-position port (+ (cport-bytes-start cp) pos))
  340. (read-bytes len port))
  341. (define (cport-get-byte cp pos)
  342. (define port (cport-orig-port cp))
  343. (file-position port (+ (cport-bytes-start cp) pos))
  344. (read-byte port))
  345. (define (cport-rpos cp)
  346. (+ (cport-pos cp) (cport-shared-start cp)))
  347. (define (cp-getc cp)
  348. (when ((cport-pos cp) . >= . (cport-size cp))
  349. (error "off the end"))
  350. (define r (cport-get-byte cp (cport-pos cp)))
  351. (set-cport-pos! cp (add1 (cport-pos cp)))
  352. r)
  353. (define small-list-max 65)
  354. (define cpt-table
  355. ;; The "schcpt.h" mapping
  356. `([0 escape]
  357. [1 symbol]
  358. [2 symref]
  359. [3 weird-symbol]
  360. [4 keyword]
  361. [5 byte-string]
  362. [6 string]
  363. [7 char]
  364. [8 int]
  365. [9 null]
  366. [10 true]
  367. [11 false]
  368. [12 void]
  369. [13 box]
  370. [14 pair]
  371. [15 list]
  372. [16 vector]
  373. [17 hash-table]
  374. [18 stx]
  375. [19 let-one-flonum]
  376. [20 marshalled]
  377. [21 quote]
  378. [22 reference]
  379. [23 local]
  380. [24 local-unbox]
  381. [25 svector]
  382. [26 application]
  383. [27 let-one]
  384. [28 branch]
  385. [29 module-index]
  386. [30 module-var]
  387. [31 path]
  388. [32 closure]
  389. [33 delayed]
  390. [34 prefab]
  391. [35 let-one-unused]
  392. [36 60 small-number]
  393. [60 80 small-symbol]
  394. [80 92 small-marshalled]
  395. [92 ,(+ 92 small-list-max) small-proper-list]
  396. [,(+ 92 small-list-max) 192 small-list]
  397. [192 207 small-local]
  398. [207 222 small-local-unbox]
  399. [222 247 small-svector]
  400. [248 small-application2]
  401. [249 small-application3]
  402. [247 255 small-application]))
  403. (define (cpt-table-lookup i)
  404. (for/or ([ent cpt-table])
  405. (match ent
  406. [(list k sym) (and (= k i) (cons k sym))]
  407. [(list k k* sym)
  408. (and (<= k i)
  409. (< i k*)
  410. (cons k sym))])))
  411. (define (read-compact-bytes port c)
  412. (begin0
  413. (cport-get-bytes port c)
  414. (set-cport-pos! port (+ c (cport-pos port)))))
  415. (define (read-compact-chars port c)
  416. (bytes->string/utf-8 (read-compact-bytes port c)))
  417. (define (read-compact-list c proper port)
  418. (cond [(= 0 c)
  419. (if proper null (read-compact port))]
  420. [else (cons (read-compact port) (read-compact-list (sub1 c) proper port))]))
  421. (define (read-compact-number port)
  422. (define flag (cp-getc port))
  423. (cond [(< flag 128)
  424. flag]
  425. [(zero? (bitwise-and flag #x40))
  426. (let ([a (cp-getc port)])
  427. (+ (a . << . 6) (bitwise-and flag 63)))]
  428. [(zero? (bitwise-and flag #x20))
  429. (- (bitwise-and flag #x1F))]
  430. [else
  431. (let ([a (cp-getc port)]
  432. [b (cp-getc port)]
  433. [c (cp-getc port)]
  434. [d (cp-getc port)])
  435. (let ([n (integer-bytes->integer (bytes a b c d) #f #f)])
  436. (if (zero? (bitwise-and flag #x10))
  437. (- n)
  438. n)))]))
  439. (define (read-compact-svector port n)
  440. (define v (make-vector n))
  441. (for ([i (in-range n)])
  442. (vector-set! v (sub1 (- n i)) (read-compact-number port)))
  443. v)
  444. (define (read-marshalled type port)
  445. (let* ([type (if (number? type) (int->type type) type)]
  446. [l (read-compact port)]
  447. [reader (get-reader type)])
  448. (reader l)))
  449. (define (make-local unbox? pos flags)
  450. (define SCHEME_LOCAL_CLEAR_ON_READ #x01)
  451. (define SCHEME_LOCAL_OTHER_CLEARS #x02)
  452. (define SCHEME_LOCAL_FLONUM #x03)
  453. (make-localref unbox? pos
  454. (= flags SCHEME_LOCAL_CLEAR_ON_READ)
  455. (= flags SCHEME_LOCAL_OTHER_CLEARS)
  456. (= flags SCHEME_LOCAL_FLONUM)))
  457. (define (a . << . b)
  458. (arithmetic-shift a b))
  459. (define-struct not-ready ())
  460. ;; ----------------------------------------
  461. ;; Syntax unmarshaling
  462. (define (make-memo) (make-weak-hash))
  463. (define (with-memo* mt arg thnk)
  464. (hash-ref! mt arg thnk))
  465. (define-syntax-rule (with-memo mt arg body ...)
  466. (with-memo* mt arg (λ () body ...)))
  467. (define (decode-mark-map alist)
  468. alist)
  469. (define stx-memo (make-memo))
  470. ; XXX More memo use
  471. (define (decode-stx cp v)
  472. (with-memo stx-memo v
  473. (if (integer? v)
  474. (unmarshal-stx-get/decode cp v decode-stx)
  475. (let loop ([v v])
  476. (let-values ([(tamper-status v encoded-wraps)
  477. (match v
  478. [`#((,datum . ,wraps)) (values 'tainted datum wraps)]
  479. [`#((,datum . ,wraps) #f) (values 'armed datum wraps)]
  480. [`(,datum . ,wraps) (values 'clean datum wraps)]
  481. [else (error 'decode-wraps "bad datum+wrap: ~.s" v)])])
  482. (let* ([wraps (decode-wraps cp encoded-wraps)]
  483. [wrapped-memo (make-memo)]
  484. [add-wrap (lambda (v) (with-memo wrapped-memo v (make-wrapped v wraps tamper-status)))])
  485. (cond
  486. [(pair? v)
  487. (if (eq? #t (car v))
  488. ;; Share decoded wraps with all nested parts.
  489. (let loop ([v (cdr v)])
  490. (cond
  491. [(pair? v)
  492. (let ploop ([v v])
  493. (cond
  494. [(null? v) null]
  495. [(pair? v) (add-wrap (cons (loop (car v)) (ploop (cdr v))))]
  496. [else (loop v)]))]
  497. [(box? v) (add-wrap (box (loop (unbox v))))]
  498. [(vector? v)
  499. (add-wrap (list->vector (map loop (vector->list v))))]
  500. [(prefab-struct-key v)
  501. => (lambda (k)
  502. (add-wrap
  503. (apply
  504. make-prefab-struct
  505. k
  506. (map loop (struct->list v)))))]
  507. [else (add-wrap v)]))
  508. ;; Decode sub-elements that have their own wraps:
  509. (let-values ([(v counter) (if (exact-integer? (car v))
  510. (values (cdr v) (car v))
  511. (values v -1))])
  512. (add-wrap
  513. (let ploop ([v v][counter counter])
  514. (cond
  515. [(null? v) null]
  516. [(or (not (pair? v)) (zero? counter)) (loop v)]
  517. [(pair? v) (cons (loop (car v))
  518. (ploop (cdr v) (sub1 counter)))])))))]
  519. [(box? v) (add-wrap (box (loop (unbox v))))]
  520. [(vector? v)
  521. (add-wrap (list->vector (map loop (vector->list v))))]
  522. [(prefab-struct-key v)
  523. => (lambda (k)
  524. (add-wrap
  525. (apply
  526. make-prefab-struct
  527. k
  528. (map loop (struct->list v)))))]
  529. [else (add-wrap v)])))))))
  530. (define wrape-memo (make-memo))
  531. (define (decode-wrape cp a)
  532. (define (aloop a) (decode-wrape cp a))
  533. (with-memo wrape-memo a
  534. ; A wrap-elem is either
  535. (cond
  536. ; A reference
  537. [(integer? a)
  538. (unmarshal-stx-get/decode cp a (lambda (cp v) (aloop v)))]
  539. ; A mark (not actually a number as the C says, but a (list <num>)
  540. [(and (pair? a) (number? (car a)))
  541. (make-wrap-mark (car a))]
  542. [(vector? a)
  543. (make-lexical-rename (vector-ref a 0) (vector-ref a 1)
  544. (let ([top (+ (/ (- (vector-length a) 2) 2) 2)])
  545. (let loop ([i 2])
  546. (if (= i top)
  547. null
  548. (cons (cons (vector-ref a i)
  549. (vector-ref a (+ (- top 2) i)))
  550. (loop (+ i 1)))))))]
  551. [(pair? a)
  552. (let-values ([(plus-kern? a) (if (eq? (car a) #t)
  553. (values #t (cdr a))
  554. (values #f a))])
  555. (match a
  556. [`(,phase ,kind ,set-id ,maybe-unmarshals . ,renames)
  557. (let-values ([(unmarshals renames mark-renames)
  558. (if (vector? maybe-unmarshals)
  559. (values null maybe-unmarshals renames)
  560. (values maybe-unmarshals
  561. (car renames)
  562. (cdr renames)))])
  563. (make-module-rename phase
  564. (if kind 'marked 'normal)
  565. set-id
  566. (map (curry decode-all-from-module cp) unmarshals)
  567. (decode-renames renames)
  568. mark-renames
  569. (and plus-kern? 'plus-kern)))]
  570. [else (error "bad module rename: ~e" a)]))]
  571. [(boolean? a)
  572. (make-top-level-rename a)]
  573. [(symbol? a)
  574. (make-mark-barrier a)]
  575. [(box? a)
  576. (match (unbox a)
  577. [(list (? symbol?) ...) (make-prune (unbox a))]
  578. [`#(,amt ,src ,dest #f #f)
  579. (make-phase-shift amt
  580. (parse-module-path-index cp src)
  581. (parse-module-path-index cp dest))]
  582. [else (error 'parse "bad phase shift: ~e" a)])]
  583. [else (error 'decode-wraps "bad wrap element: ~e" a)])))
  584. (define all-from-module-memo (make-memo))
  585. (define (decode-all-from-module cp afm)
  586. (define (phase? v)
  587. (or (number? v) (not v)))
  588. (with-memo all-from-module-memo afm
  589. (match afm
  590. [(list* path (? phase? phase) (? phase? src-phase)
  591. (list exn ...) prefix)
  592. (make-all-from-module
  593. (parse-module-path-index cp path)
  594. phase src-phase exn (vector prefix))]
  595. [(list* path (? phase? phase) (list exn ...) (? phase? src-phase))
  596. (make-all-from-module
  597. (parse-module-path-index cp path)
  598. phase src-phase exn #f)]
  599. [(list* path (? phase? phase) (? phase? src-phase))
  600. (make-all-from-module
  601. (parse-module-path-index cp path)
  602. phase src-phase #f #f)])))
  603. (define wraps-memo (make-memo))
  604. (define (decode-wraps cp w)
  605. (with-memo wraps-memo w
  606. ; A wraps is either a indirect reference or a list of wrap-elems (from stxobj.c:252)
  607. (if (integer? w)
  608. (unmarshal-stx-get/decode cp w decode-wraps)
  609. (map (curry decode-wrape cp) w))))
  610. (define (in-vector* v n)
  611. (make-do-sequence
  612. (λ ()
  613. (values (λ (i) (vector->values v i (+ i n)))
  614. (λ (i) (+ i n))
  615. 0
  616. (λ (i) (>= (vector-length v) (+ i n)))
  617. (λ _ #t)
  618. (λ _ #t)))))
  619. (define nominal-path-memo (make-memo))
  620. (define (decode-nominal-path np)
  621. (with-memo nominal-path-memo np
  622. (match np
  623. [(cons nominal-path (cons import-phase nominal-phase))
  624. (make-phased-nominal-path nominal-path import-phase nominal-phase)]
  625. [(cons nominal-path import-phase)
  626. (make-imported-nominal-path nominal-path import-phase)]
  627. [nominal-path
  628. (make-simple-nominal-path nominal-path)])))
  629. ; XXX Weird test copied from C code. Matthew?
  630. (define (nom_mod_p p)
  631. (and (pair? p) (not (pair? (cdr p))) (not (symbol? (cdr p)))))
  632. (define rename-v-memo (make-memo))
  633. (define (decode-rename-v v)
  634. (with-memo rename-v-memo v
  635. (match v
  636. [(list-rest path phase export-name nominal-path nominal-export-name)
  637. (make-phased-module-binding path
  638. phase
  639. export-name
  640. (decode-nominal-path nominal-path)
  641. nominal-export-name)]
  642. [(list-rest path export-name nominal-path nominal-export-name)
  643. (make-exported-nominal-module-binding path
  644. export-name
  645. (decode-nominal-path nominal-path)
  646. nominal-export-name)]
  647. [(cons module-path-index (? nom_mod_p nominal-path))
  648. (make-nominal-module-binding module-path-index (decode-nominal-path nominal-path))]
  649. [(cons module-path-index export-name)
  650. (make-exported-module-binding module-path-index export-name)]
  651. [module-path-index
  652. (make-simple-module-binding module-path-index)])))
  653. (define renames-memo (make-memo))
  654. (define (decode-renames renames)
  655. (with-memo renames-memo renames
  656. (for/list ([(k v) (in-vector* renames 2)])
  657. (cons k (decode-rename-v v)))))
  658. (define (parse-module-path-index cp s)
  659. s)
  660. ;; ----------------------------------------
  661. ;; Main parsing loop
  662. (define (read-compact cp)
  663. (let loop ([need-car 0] [proper #f])
  664. (define ch (cp-getc cp))
  665. (define-values (cpt-start cpt-tag)
  666. (let ([x (cpt-table-lookup ch)])
  667. (unless x
  668. (error 'read-compact "unknown code : ~a" ch))
  669. (values (car x) (cdr x))))
  670. (define v
  671. (case cpt-tag
  672. [(delayed)
  673. (let ([pos (read-compact-number cp)])
  674. (read-sym cp pos))]
  675. [(escape)
  676. (let* ([len (read-compact-number cp)]
  677. [s (cport-get-bytes cp len)])
  678. (set-cport-pos! cp (+ (cport-pos cp) len))
  679. (parameterize ([read-accept-compiled #t]
  680. [read-accept-bar-quote #t]
  681. [read-accept-box #t]
  682. [read-accept-graph #t]
  683. [read-case-sensitive #t]
  684. [read-square-bracket-as-paren #t]
  685. [read-curly-brace-as-paren #t]
  686. [read-decimal-as-inexact #t]
  687. [read-accept-dot #t]
  688. [read-accept-infix-dot #t]
  689. [read-accept-quasiquote #t]
  690. [current-readtable
  691. (make-readtable
  692. #f
  693. #\^
  694. 'dispatch-macro
  695. (lambda (char port src line col pos)
  696. (let ([b (read port)])
  697. (unless (bytes? b)
  698. (error 'read-escaped-path
  699. "expected a byte string after #^"))
  700. (let ([p (bytes->path b)])
  701. (if (and (relative-path? p)
  702. (current-load-relative-directory))
  703. (build-path (current-load-relative-directory) p)
  704. p)))))])
  705. (read/recursive (open-input-bytes s))))]
  706. [(reference)
  707. (make-primval (read-compact-number cp))]
  708. [(small-list small-proper-list)
  709. (let* ([l (- ch cpt-start)]
  710. [ppr (eq? cpt-tag 'small-proper-list)])
  711. (if (positive? need-car)
  712. (if (= l 1)
  713. (cons (read-compact cp)
  714. (if ppr null (read-compact cp)))
  715. (read-compact-list l ppr cp))
  716. (loop l ppr)))]
  717. [(let-one let-one-flonum let-one-unused)
  718. (make-let-one (read-compact cp) (read-compact cp)
  719. (eq? cpt-tag 'let-one-flonum)
  720. (eq? cpt-tag 'let-one-unused))]
  721. [(branch)
  722. (make-branch (read-compact cp) (read-compact cp) (read-compact cp))]
  723. [(module-index) (module-path-index-join (read-compact cp) (read-compact cp))]
  724. [(module-var)
  725. (let ([mod (read-compact cp)]
  726. [var (read-compact cp)]
  727. [pos (read-compact-number cp)])
  728. (let-values ([(mod-phase pos)
  729. (if (= pos -2)
  730. (values 1 (read-compact-number cp))
  731. (values 0 pos))])
  732. (make-module-variable mod var pos mod-phase)))]
  733. [(local-unbox)
  734. (let* ([p* (read-compact-number cp)]
  735. [p (if (< p* 0) (- (add1 p*)) p*)]
  736. [flags (if (< p* 0) (read-compact-number cp) 0)])
  737. (make-local #t p flags))]
  738. [(path)
  739. (let* ([p (bytes->path (read-compact-bytes cp (read-compact-number cp)))])
  740. (if (relative-path? p)
  741. (path->complete-path p (or (current-load-relative-directory)
  742. (current-directory)))
  743. p))]
  744. [(small-number)
  745. (let ([l (- ch cpt-start)])
  746. l)]
  747. [(int)
  748. (read-compact-number cp)]
  749. [(false) #f]
  750. [(true) #t]
  751. [(null) null]
  752. [(void) (void)]
  753. [(vector)
  754. ; XXX We should provide build-immutable-vector and write this as:
  755. #;(build-immutable-vector (read-compact-number cp)
  756. (lambda (i) (read-compact cp)))
  757. ; XXX Now it allocates an unnessary list AND vector
  758. (let* ([n (read-compact-number cp)]
  759. [lst (for/list ([i (in-range n)]) (read-compact cp))])
  760. (vector->immutable-vector (list->vector lst)))]
  761. [(pair)
  762. (let* ([a (read-compact cp)]
  763. [d (read-compact cp)])
  764. (cons a d))]
  765. [(list)
  766. (let ([len (read-compact-number cp)])
  767. (let loop ([i len])
  768. (if (zero? i)
  769. (read-compact cp)
  770. (list* (read-compact cp)
  771. (loop (sub1 i))))))]
  772. [(prefab)
  773. (let ([v (read-compact cp)])
  774. ; XXX This is faster than apply+->list, but can we avoid allocating the vector?
  775. (call-with-values (lambda () (vector->values v))
  776. make-prefab-struct))]
  777. [(hash-table)
  778. ; XXX Allocates an unnessary list (maybe use for/hash(eq))
  779. (let ([eq (read-compact-number cp)]
  780. [len (read-compact-number cp)])
  781. ((case eq
  782. [(0) make-hasheq-placeholder]
  783. [(1) make-hash-placeholder]
  784. [(2) make-hasheqv-placeholder])
  785. (for/list ([i (in-range len)])
  786. (cons (read-compact cp)
  787. (read-compact cp)))))]
  788. [(marshalled) (read-marshalled (read-compact-number cp) cp)]
  789. [(stx)
  790. (let ([v (make-reader-graph (read-compact cp))])
  791. (make-stx (decode-stx cp v)))]
  792. [(local local-unbox)
  793. (let ([c (read-compact-number cp)]
  794. [unbox? (eq? cpt-tag 'local-unbox)])
  795. (if (negative? c)
  796. (make-local unbox? (- (add1 c)) (read-compact-number cp))
  797. (make-local unbox? c 0)))]
  798. [(small-local)
  799. (make-local #f (- ch cpt-start) 0)]
  800. [(small-local-unbox)
  801. (make-local #t (- ch cpt-start) 0)]
  802. [(small-symbol)
  803. (let ([l (- ch cpt-start)])
  804. (string->symbol (read-compact-chars cp l)))]
  805. [(symbol)
  806. (let ([l (read-compact-number cp)])
  807. (string->symbol (read-compact-chars cp l)))]
  808. [(keyword)
  809. (let ([l (read-compact-number cp)])
  810. (string->keyword (read-compact-chars cp l)))]
  811. [(byte-string)
  812. (let ([l (read-compact-number cp)])
  813. (read-compact-bytes cp l))]
  814. [(string)
  815. (let ([l (read-compact-number cp)]
  816. [cl (read-compact-number cp)])
  817. (read-compact-chars cp l))]
  818. [(char)
  819. (integer->char (read-compact-number cp))]
  820. [(box)
  821. (box (read-compact cp))]
  822. [(quote)
  823. (make-reader-graph
  824. ;; Nested escapes need to share graph references. So get inside the
  825. ;; read where `read/recursive' can be used:
  826. (let ([rt (current-readtable)])
  827. (parameterize ([current-readtable (make-readtable
  828. #f
  829. #\x 'terminating-macro
  830. (lambda args
  831. (parameterize ([current-readtable rt])
  832. (read-compact cp))))])
  833. (read (open-input-bytes #"x")))))]
  834. [(symref)
  835. (let* ([l (read-compact-number cp)])
  836. (read-sym cp l))]
  837. [(weird-symbol)
  838. (let ([uninterned (read-compact-number cp)]
  839. [str (read-compact-chars cp (read-compact-number cp))])
  840. (if (= 1 uninterned)
  841. ; uninterned is equivalent to weird in the C implementation
  842. (string->uninterned-symbol str)
  843. ; unreadable is equivalent to parallel in the C implementation
  844. (string->unreadable-symbol str)))]
  845. [(small-marshalled)
  846. (read-marshalled (- ch cpt-start) cp)]
  847. [(small-application2)
  848. (make-application (read-compact cp)
  849. (list (read-compact cp)))]
  850. [(small-application3)
  851. (make-application (read-compact cp)
  852. (list (read-compact cp)
  853. (read-compact cp)))]
  854. [(small-application)
  855. (let ([c (add1 (- ch cpt-start))])
  856. (make-application (read-compact cp)
  857. (for/list ([i (in-range (sub1 c))])
  858. (read-compact cp))))]
  859. [(application)
  860. (let ([c (read-compact-number cp)])
  861. (make-application (read-compact cp)
  862. (for/list ([i (in-range c)])
  863. (read-compact cp))))]
  864. [(closure)
  865. (read-compact-number cp) ; symbol table pos. our marshaler will generate this
  866. (let ([v (read-compact cp)])
  867. (make-closure
  868. v
  869. (gensym
  870. (let ([s (lam-name v)])
  871. (cond
  872. [(symbol? s) s]
  873. [(vector? s) (vector-ref s 0)]
  874. [else 'closure])))))]
  875. [(svector)
  876. (read-compact-svector cp (read-compact-number cp))]
  877. [(small-svector)
  878. (read-compact-svector cp (- ch cpt-start))]
  879. [else (error 'read-compact "unknown tag ~a" cpt-tag)]))
  880. (cond
  881. [(zero? need-car) v]
  882. [(and proper (= need-car 1))
  883. (cons v null)]
  884. [else
  885. (cons v (loop (sub1 need-car) proper))])))
  886. (define (unmarshal-stx-get/decode cp pos decode-stx)
  887. (define v2 (read-sym cp pos))
  888. (define decoded? (vector-ref (cport-decoded cp) pos))
  889. (if decoded?
  890. v2
  891. (let ([dv2 (decode-stx cp v2)])
  892. (symtab-write! cp pos dv2)
  893. (vector-set! (cport-decoded cp) pos #t)
  894. dv2)))
  895. (define (symtab-write! cp i v)
  896. (placeholder-set! (vector-ref (cport-symtab cp) i) v))
  897. (define (symtab-lookup cp i)
  898. (vector-ref (cport-symtab cp) i))
  899. (require unstable/markparam)
  900. (define read-sym-mark (mark-parameter))
  901. (define (read-sym cp i)
  902. (define ph (symtab-lookup cp i))
  903. ; We are reading this already, so return the placeholder
  904. (if (memq i (mark-parameter-all read-sym-mark))
  905. ph
  906. ; Otherwise, try to read it and return the real thing
  907. (let ([vv (placeholder-get ph)])
  908. (when (not-ready? vv)
  909. (let ([save-pos (cport-pos cp)])
  910. (set-cport-pos! cp (vector-ref (cport-shared-offsets cp) (sub1 i)))
  911. (mark-parameterize
  912. ([read-sym-mark i])
  913. (let ([v (read-compact cp)])
  914. (placeholder-set! ph v)))
  915. (set-cport-pos! cp save-pos)))
  916. (placeholder-get ph))))
  917. ;; path -> bytes
  918. ;; implementes read.c:read_compiled
  919. (define (zo-parse [port (current-input-port)])
  920. ;; skip the "#~"
  921. (unless (equal? #"#~" (read-bytes 2 port))
  922. (error 'zo-parse "not a bytecode stream"))
  923. (define version (read-bytes (min 63 (read-byte port)) port))
  924. ;; Skip module hash code
  925. (read-bytes 20 port)
  926. (define symtabsize (read-simple-number port))
  927. (define all-short (read-byte port))
  928. (define cnt (* (if (not (zero? all-short)) 2 4)
  929. (sub1 symtabsize)))
  930. (define so (read-bytes cnt port))
  931. (define so* (list->vector (split-so all-short so)))
  932. (define shared-size (read-simple-number port))
  933. (define size* (read-simple-number port))
  934. (when (shared-size . >= . size*)
  935. (error 'zo-parse "Non-shared data segment start is not after shared data segment (according to offsets)"))
  936. (define rst-start (file-position port))
  937. (file-position port (+ rst-start size*))
  938. (unless (eof-object? (read-byte port))
  939. (error 'zo-parse "File too big"))
  940. (define nr (make-not-ready))
  941. (define symtab
  942. (build-vector symtabsize (λ (i) (make-placeholder nr))))
  943. (define cp
  944. (make-cport 0 shared-size port size* rst-start symtab so*
  945. (make-vector symtabsize #f) (make-hash) (make-hash)))
  946. (for ([i (in-range 1 symtabsize)])
  947. (read-sym cp i))
  948. #;(printf "Parsed table:\n")
  949. #;(for ([(i v) (in-dict (cport-symtab cp))])
  950. (printf "~a = ~a\n" i (placeholder-get v)))
  951. (set-cport-pos! cp shared-size)
  952. (make-reader-graph (read-marshalled 'compilation-top-type cp)))
  953. ;; ----------------------------------------
  954. #;
  955. (begin
  956. (define (compile/write sexp)
  957. (define s (open-output-bytes))
  958. (write (parameterize ([current-namespace (make-base-namespace)])
  959. (eval '(require (for-syntax scheme/base)))
  960. (compile sexp))
  961. s)
  962. (get-output-bytes s))
  963. (define (compile/parse sexp)
  964. (let* ([bs (compile/write sexp)]
  965. [p (open-input-bytes bs)])
  966. (zo-parse p)))
  967. #;(compile/parse #s(foo 10 13))
  968. (zo-parse (open-input-file "/home/mflatt/proj/plt/collects/scheme/private/compiled/more-scheme_ss.zo"))
  969. )