test-ffi.scm 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. ;;; Copyright (C) 2023, 2024 David Thompson <dave@spritely.institute>
  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. ;;; FFI tests.
  17. ;;;
  18. ;;; Code:
  19. (use-modules (ice-9 binary-ports)
  20. (ice-9 exceptions)
  21. (ice-9 popen)
  22. (ice-9 textual-ports)
  23. (srfi srfi-64)
  24. (test utils)
  25. (hoot compile)
  26. (hoot reflect)
  27. (wasm parse))
  28. (test-begin "test-ffi")
  29. (define-syntax-rule (test-ffi name expected source imports)
  30. (test-equal name
  31. expected
  32. (compile-value 'source
  33. #:imports (cons '(hoot ffi) %default-program-imports)
  34. #:wasm-imports imports)))
  35. (test-ffi
  36. "i32 param and result"
  37. 16
  38. (let ()
  39. (define-foreign fsquare
  40. "math" "square"
  41. i32 -> i32)
  42. (square 4))
  43. `(("math" . (("square" . ,(lambda (x) (* x x)))))))
  44. (test-ffi
  45. "i64 param and result"
  46. 16
  47. (let ()
  48. (define-foreign fsquare
  49. "math" "square"
  50. i64 -> i64)
  51. (square 4))
  52. `(("math" . (("square" . ,(lambda (x) (* x x)))))))
  53. (test-ffi
  54. "f32 param and result"
  55. 16.0
  56. (let ()
  57. (define-foreign fsquare
  58. "math" "fsquare"
  59. f32 -> f32)
  60. (fsquare 4.0))
  61. `(("math" . (("fsquare" . ,(lambda (x) (* x x)))))))
  62. (test-ffi
  63. "f64 param and result"
  64. 16.0
  65. (let ()
  66. (define-foreign fsquare
  67. "math" "fsquare"
  68. f64 -> f64)
  69. (fsquare 4.0))
  70. `(("math" . (("fsquare" . ,(lambda (x) (* x x)))))))
  71. (test-ffi
  72. "string param and result"
  73. "Hello, owl!"
  74. (let ()
  75. (define-foreign hello
  76. "host" "hello"
  77. (ref string) -> (ref string))
  78. (hello "owl"))
  79. `(("host" .
  80. (("hello" . ,(lambda (name) (string-append "Hello, " name "!")))))))
  81. (test-ffi
  82. "eq param and result"
  83. "hello"
  84. (let ()
  85. (define-foreign echo
  86. "host" "echo"
  87. (ref eq) -> (ref eq))
  88. (echo "hello"))
  89. `(("host" .
  90. (("echo" . ,(lambda (x) x))))))
  91. (test-ffi
  92. "external?"
  93. #t
  94. (let ()
  95. (define-foreign get-extern
  96. "host" "getExtern"
  97. -> (ref null extern))
  98. (external? (get-extern)))
  99. `(("host" . (("getExtern" . ,(lambda () '(external value)))))))
  100. (test-ffi
  101. "external-null?"
  102. #t
  103. (let ()
  104. (define-foreign get-null
  105. "host" "getNull"
  106. -> (ref null extern))
  107. (external-null? (get-null)))
  108. `(("host" . (("getNull" . ,(lambda () #f))))))
  109. (test-ffi
  110. "external-non-null?"
  111. #t
  112. (let ()
  113. (define-foreign get-non-null
  114. "host" "getNonNull"
  115. -> (ref extern))
  116. (external-non-null? (get-non-null)))
  117. `(("host" . (("getNonNull" . ,(lambda () #t))))))
  118. (test-ffi
  119. "procedure->extern"
  120. 1
  121. (let ((counter 0))
  122. (define-foreign callback
  123. "host" "callback"
  124. (ref null extern) -> none)
  125. (callback
  126. (procedure->external
  127. (lambda () (set! counter (+ counter 1)))))
  128. counter)
  129. `(("host" .
  130. (("callback" . ,(lambda (f) (f) *unspecified*))))))
  131. (test-end* "test-ffi")