jar-assem.scm 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. ; -*- Mode: Scheme; Syntax: Scheme; Package: Scheme; -*-
  2. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  3. ; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber
  4. ; This is file assem.scm.
  5. ;;;; Assembler
  6. ; Courtesy John Ramsdell.
  7. ; LAP syntax is much like that of the output of the disassembler except
  8. ; that global and set-global! take a symbol as an argument,
  9. ; statements may be labeled, and jump, jump-if-false, and make-cont
  10. ; may make a forward reference to a label to give an offset.
  11. ;
  12. ; Example: a translation of (define (dog) (if x 0 1)).
  13. ; (define dog
  14. ; (lap dog
  15. ; (check-nargs= 0)
  16. ; (global x)
  17. ; (jump-if-false 8)
  18. ; (literal '0)
  19. ; 8 (jump out)
  20. ; (literal '1)
  21. ; out (return)))
  22. (define-compilator '(lap syntax)
  23. (let ((op/closure (enum op closure)))
  24. (lambda (node cenv depth cont)
  25. (let ((exp (node-form node)))
  26. (deliver-value
  27. (instruction-with-template op/closure
  28. (compile-lap (cddr exp) cenv)
  29. (cadr exp))
  30. cont)))))
  31. ; Assembler label environments are simply a-lists.
  32. (define assembler-empty-env '())
  33. (define (assembler-extend sym val env) (cons (cons sym val) env))
  34. (define (assembler-lookup sym env)
  35. (let ((val (assv sym env)))
  36. (if (pair? val) (cdr val) #f)))
  37. (define (compile-lap instruction-list cenv)
  38. (assemble instruction-list
  39. assembler-empty-env
  40. cenv))
  41. ; ASSEMBLE returns a segment.
  42. (define (assemble instruction-list lenv cenv)
  43. (if (null? instruction-list)
  44. (sequentially)
  45. (let ((instr (car instruction-list))
  46. (instruction-list (cdr instruction-list)))
  47. (cond ((pair? instr) ; Instruction
  48. (sequentially
  49. (assemble-instruction instr lenv cenv)
  50. (assemble instruction-list
  51. lenv
  52. cenv)))
  53. ((or (symbol? instr) ; Label
  54. (number? instr))
  55. (let ((label (make-label)))
  56. (attach-label
  57. label
  58. (assemble instruction-list
  59. (assembler-extend instr label lenv)
  60. cenv))))
  61. (else (assertion-violation 'assemble "invalid instruction" instr))))))
  62. ; ASSEMBLE-INSTRUCTION returns a segment.
  63. (define (assemble-instruction instr lenv cenv)
  64. (let* ((opcode (name->enumerand (car instr) op))
  65. (arg-specs (vector-ref opcode-arg-specs opcode)))
  66. (cond ((or (not (pair? arg-specs))
  67. (not (pair? (cdr instr))))
  68. (instruction opcode))
  69. ((eq? (car arg-specs) 'index)
  70. (assemble-instruction-with-index opcode arg-specs (cdr instr) cenv))
  71. ((eq? (car arg-specs) 'offset)
  72. (let ((operand (cadr instr)))
  73. (apply instruction-using-label
  74. opcode
  75. (let ((probe (assembler-lookup operand lenv)))
  76. (if probe
  77. probe
  78. (begin
  79. (assertion-violation 'assemble-instruction
  80. "can't find forward label reference"
  81. operand)
  82. empty-segment)))
  83. (assemble-operands (cddr instr) arg-specs))))
  84. (else
  85. (apply instruction
  86. opcode
  87. (assemble-operands (cdr instr) arg-specs))))))
  88. ; <index> ::= (quote <datum>) | (lap <name> <instr>) | <name>
  89. (define (assemble-instruction-with-index opcode arg-specs operands cenv)
  90. (let ((operand (car operands)))
  91. (if (pair? operand)
  92. (case (car operand)
  93. ((quote)
  94. (instruction-with-literal opcode
  95. (cadr operand)))
  96. ((lap)
  97. (instruction-with-template opcode
  98. (compile-lap (cddr operand))
  99. (cadr operand)))
  100. (else
  101. (assertion-violation 'assemble-instruction-with-index
  102. "invalid index operand" operand)
  103. empty-segment))
  104. ;; Top-level variable reference
  105. (instruction-with-location
  106. opcode
  107. (get-location (lookup cenv operand)
  108. cenv
  109. operand
  110. value-type)))))
  111. (define (assemble-operands operands arg-specs)
  112. (map (lambda (operand arg-spec)
  113. (case arg-spec
  114. ((stob) (or (name->enumerand operand stob)
  115. (assertion-violation 'assemble-operands
  116. "unknown stored object type" operand)))
  117. ((byte nargs) operand)
  118. (else (assertion-violation 'assemble-operands "unknown operand type"
  119. operand arg-spec))))
  120. operands
  121. arg-specs))