utils.scm 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. ;;; Copyright (C) 2023 Igalia, S.L.
  2. ;;;
  3. ;;; Licensed under the Apache License, Version 2.0 (the "License");
  4. ;;; you may not use this file except in compliance with the License.
  5. ;;; You may obtain a copy of the License at
  6. ;;;
  7. ;;; http://www.apache.org/licenses/LICENSE-2.0
  8. ;;;
  9. ;;; Unless required by applicable law or agreed to in writing, software
  10. ;;; distributed under the License is distributed on an "AS IS" BASIS,
  11. ;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. ;;; See the License for the specific language governing permissions and
  13. ;;; limitations under the License.
  14. ;;; Commentary:
  15. ;;;
  16. ;;; Test utilities.
  17. ;;;
  18. ;;; Code:
  19. (define-module (test utils)
  20. #:use-module (wasm assemble)
  21. #:use-module (wasm parse)
  22. #:use-module (hoot compile)
  23. #:use-module (hoot reflect)
  24. #:use-module (ice-9 binary-ports)
  25. #:use-module (ice-9 match)
  26. #:use-module (ice-9 popen)
  27. #:use-module (ice-9 textual-ports)
  28. #:use-module (srfi srfi-64)
  29. #:export (d8
  30. srcdir
  31. use-d8?
  32. use-hoot-vm?
  33. scope-file
  34. call-with-compiled-wasm-file
  35. test-compilation
  36. test-call
  37. test-end*))
  38. (define d8 (or (getenv "D8") "d8"))
  39. (define srcdir (or (getenv "SRCDIR") (getcwd)))
  40. (define test-hosts (string-split (or (getenv "WASM_HOST") "d8,hoot") #\,))
  41. (define use-d8? (member "d8" test-hosts))
  42. (define use-hoot-vm? (member "hoot" test-hosts))
  43. (define (scope-file file-name)
  44. (string-append srcdir "/" file-name))
  45. (define (unwind-protect body unwind)
  46. (call-with-values
  47. (lambda ()
  48. (with-exception-handler
  49. (lambda (exn)
  50. (unwind)
  51. (raise-exception exn))
  52. body))
  53. (lambda vals
  54. (unwind)
  55. (apply values vals))))
  56. (define (call-with-compiled-wasm-file wasm f)
  57. (let* ((wasm-port (mkstemp "/tmp/tmp-wasm-XXXXXX"))
  58. (wasm-file-name (port-filename wasm-port)))
  59. (put-bytevector wasm-port (assemble-wasm wasm))
  60. (close-port wasm-port)
  61. (unwind-protect
  62. (lambda () (f wasm-file-name))
  63. (lambda () (delete-file wasm-file-name)))))
  64. (define (run-d8 . args)
  65. (let* ((args (cons* "--experimental-wasm-stringref" args))
  66. (port (apply open-pipe* OPEN_READ d8 args))
  67. (output (get-string-all port)))
  68. (close-port port)
  69. (string-trim-both output)))
  70. (define (compile-value/d8 wasm)
  71. (call-with-compiled-wasm-file
  72. wasm
  73. (lambda (wasm-file-name)
  74. (run-d8 (scope-file "test/load-wasm-and-print.js") "--" srcdir wasm-file-name))))
  75. (define (compile-call/d8 proc . args)
  76. (let lp ((modules (cons proc args)) (files '()) (first? #t))
  77. (match modules
  78. (()
  79. (apply run-d8 (scope-file "test/test-call.js") "--" srcdir (reverse files)))
  80. ((module . rest)
  81. (call-with-compiled-wasm-file
  82. module
  83. (lambda (file)
  84. (lp rest (cons file files) #f)))))))
  85. (define (call-with-printed-values thunk)
  86. (string-trim-both
  87. (with-output-to-string
  88. (lambda ()
  89. (call-with-values thunk
  90. (lambda vals
  91. (for-each (lambda (x)
  92. ((@@ (hoot reflect) %hoot-print) x (current-output-port))
  93. (newline))
  94. vals)))))))
  95. (define (compile-value/hoot wasm)
  96. (call-with-printed-values
  97. (lambda ()
  98. (hoot-load (hoot-instantiate wasm)))))
  99. (define (compile-call/hoot proc . args)
  100. (call-with-printed-values
  101. (lambda ()
  102. (let* ((proc-module (hoot-instantiate proc))
  103. (proc* (hoot-load proc-module))
  104. (reflector (hoot-module-reflector proc-module))
  105. (args* (map (lambda (arg)
  106. (hoot-load
  107. (hoot-instantiate arg '() reflector)))
  108. args)))
  109. (apply proc* args*)))))
  110. (define (compare-results hoot-result d8-result)
  111. (cond
  112. ((and use-hoot-vm? use-d8?)
  113. (unless (equal? hoot-result d8-result)
  114. (error "our result differs from d8" hoot-result d8-result))
  115. hoot-result)
  116. (use-d8? d8-result)
  117. (else hoot-result)))
  118. (define cache (make-hash-table))
  119. (define (compile/cache expr . args)
  120. (cond
  121. ((hash-ref cache (cons expr args)))
  122. (else
  123. (let ((result (apply compile expr args)))
  124. (hash-set! cache (cons expr args) result)
  125. result))))
  126. (define (compile-value* expr)
  127. (let ((wasm (compile/cache expr)))
  128. (compare-results (and use-hoot-vm? (compile-value/hoot wasm))
  129. (and use-d8? (compile-value/d8 wasm)))))
  130. (define (compile-call* proc . args)
  131. (let ((proc* (compile/cache proc))
  132. (args* (map (lambda (exp)
  133. (compile/cache exp #:import-abi? #t #:export-abi? #f))
  134. args)))
  135. (compare-results (and use-hoot-vm? (apply compile-call/hoot proc* args*))
  136. (and use-d8? (apply compile-call/d8 proc* args*)))))
  137. (define-syntax-rule (test-compilation expr repr)
  138. (test-equal repr repr (compile-value* 'expr)))
  139. (define-syntax-rule (test-call repr proc arg ...)
  140. (test-equal repr repr (compile-call* 'proc 'arg ...)))
  141. (define-syntax-rule (test-end* name)
  142. (begin
  143. (when (and (batch-mode?)
  144. (or (not (zero? (test-runner-fail-count (test-runner-get))))
  145. (not (zero? (test-runner-xpass-count (test-runner-get))))))
  146. (force-output)
  147. (exit 1))
  148. (test-end name)))