procedures.scm 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. ;;; Procedures on procedures
  2. ;;; Copyright (C) 2023, 2024 Igalia, S.L.
  3. ;;; Copyright (C) 2023 Robin Templeton <robin@spritely.institute>
  4. ;;;
  5. ;;; Licensed under the Apache License, Version 2.0 (the "License");
  6. ;;; you may not use this file except in compliance with the License.
  7. ;;; You may obtain a copy of the License at
  8. ;;;
  9. ;;; http://www.apache.org/licenses/LICENSE-2.0
  10. ;;;
  11. ;;; Unless required by applicable law or agreed to in writing, software
  12. ;;; distributed under the License is distributed on an "AS IS" BASIS,
  13. ;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. ;;; See the License for the specific language governing permissions and
  15. ;;; limitations under the License.
  16. ;;; Commentary:
  17. ;;;
  18. ;;; procedure?
  19. ;;;
  20. ;;; Code:
  21. (library (hoot procedures)
  22. (export procedure? procedure-name)
  23. (import (only (hoot primitives)
  24. %eq?
  25. %procedure?
  26. %struct?
  27. %struct-vtable
  28. %vector-length
  29. %vector-ref)
  30. (hoot cond-expand)
  31. (hoot errors)
  32. (hoot inline-wasm)
  33. (hoot syntax))
  34. (define (procedure? x)
  35. (or (%procedure? x)
  36. ;; Can't call applicable-struct? here as it would create a
  37. ;; module cycle.
  38. (and (%struct? x)
  39. (let ((parents (%inline-wasm
  40. '(func (param $vtable (ref $vtable))
  41. (result (ref eq))
  42. (call $vtable-parents (local.get $vtable)))
  43. (%struct-vtable x))))
  44. (if (%eq? (%vector-length parents) 0)
  45. #f
  46. (%eq? (%inline-wasm
  47. '(func (result (ref eq))
  48. (global.get $applicable-struct-vtable)))
  49. (%vector-ref parents 0)))))))
  50. (cond-expand
  51. (guile-vm
  52. (define (procedure-name proc)
  53. (check-type proc procedure? 'procedure-name)
  54. #f))
  55. (hoot
  56. (define (procedure-name proc)
  57. (check-type proc procedure? 'procedure-name)
  58. (%inline-wasm
  59. '(func (param $proc (ref $proc)) (result (ref eq))
  60. (local $maybe-string (ref null string))
  61. (call $code-name (struct.get $proc $func (local.get $proc)))
  62. (local.set $maybe-string)
  63. (if (ref eq)
  64. (ref.is_null (local.get $maybe-string))
  65. (then (ref.i31 (i32.const 1)))
  66. (else (struct.new $string (i32.const 0)
  67. (ref.as_non_null (local.get $maybe-string))))))
  68. proc)))))