/src/racket/src/gen-jit-ts.rkt

http://github.com/gmarceau/PLT · Racket · 216 lines · 200 code · 16 blank · 0 comment · 23 complexity · 657d541974e339cdd387196ed796785d MD5 · raw file

  1. #lang at-exp scheme/base
  2. (require scheme/string)
  3. (define (char->type c)
  4. (case c
  5. [(#\s) "Scheme_Object*"]
  6. [(#\t) "const Scheme_Object*"]
  7. [(#\S) "Scheme_Object**"]
  8. [(#\b) "Scheme_Bucket*"]
  9. [(#\n) "Scheme_Native_Closure_Data*"]
  10. [(#\m) "MZ_MARK_STACK_TYPE"]
  11. [(#\p) "void*"]
  12. [(#\i) "int"]
  13. [(#\l) "intptr_t"]
  14. [(#\z) "size_t"]
  15. [(#\v) "void"]
  16. [else (error 'char->type "unknown: ~e" c)]))
  17. (define (is-pointer-type? c)
  18. (case c
  19. [(#\s) #t]
  20. [(#\t) #t]
  21. [(#\S) #t]
  22. [(#\b) #t]
  23. [(#\n) #t]
  24. [(#\m) #f]
  25. [(#\p) #t]
  26. [(#\i) #f]
  27. [(#\l) #f]
  28. [(#\z) #f]
  29. [(#\v) #f]
  30. [else (error 'char->type "unknown: ~e" c)]))
  31. (define (type->arg-string t)
  32. (let* ([t (symbol->string t)])
  33. (substring t 0 (- (string-length t) 2))))
  34. (define (parse-type t)
  35. (let* ([s (symbol->string t)])
  36. (values
  37. (for/list ([c (in-string (type->arg-string t))])
  38. (char->type c))
  39. (char->type (string-ref s (sub1 (string-length s)))))))
  40. (define (make-arg-list arg-types arg-names)
  41. (string-join (map (lambda (t a)
  42. (string-append t " " a))
  43. arg-types arg-names)
  44. ", "))
  45. (define (gen-definer t)
  46. (define-values (arg-types result-type) (parse-type t))
  47. (define arg-names (map symbol->string (map (lambda (v) (gensym)) arg-types)))
  48. (define return (if (equal? result-type "void") "" "return"))
  49. (define args (make-arg-list arg-types arg-names))
  50. (define ts (symbol->string t))
  51. (for-each display
  52. @list{#define define_ts_@|ts|(id, src_type) \
  53. static @|result-type| ts_ ## id(@|args|) \
  54. XFORM_SKIP_PROC \
  55. { \
  56. if (scheme_use_rtcall) \
  57. @|return| scheme_rtcall_@|t|("[" #id "]", src_type, id, @(string-join arg-names ", ")); \
  58. else \
  59. @|return| id(@(string-join arg-names ", ")); \
  60. }})
  61. (newline))
  62. (define (gen-future-side t)
  63. (define-values (arg-types result-type) (parse-type t))
  64. (define arg-names (map symbol->string (map (lambda (v) (gensym)) arg-types)))
  65. (define return (if (equal? result-type "void") "" "return"))
  66. (define args (make-arg-list arg-types arg-names))
  67. (define ts (symbol->string t))
  68. (define fretval @string-append{future->retval_@|(substring ts (sub1 (string-length ts)))|})
  69. (for-each
  70. display
  71. @list{
  72. @|result-type| scheme_rtcall_@|ts|(const char *who, int src_type, prim_@|ts| f@|(if (null? arg-types) "" ",")| @|args|)
  73. XFORM_SKIP_PROC
  74. {
  75. Scheme_Future_Thread_State *fts = scheme_future_thread_state;
  76. future_t *future;
  77. double tm;
  78. @(if (string=? result-type "void") "" @string-append{@|result-type| retval;})
  79. future = fts->thread->current_ft;
  80. future->prim_protocol = SIG_@|ts|;
  81. future->prim_func = f;
  82. tm = get_future_timestamp();
  83. future->time_of_request = tm;
  84. future->source_of_request = who;
  85. future->source_type = src_type;
  86. @(string-join
  87. (for/list ([t (in-string (type->arg-string t))]
  88. [a arg-names]
  89. [i (in-naturals)])
  90. @string-append{ future->arg_@|(string t)|@|(number->string i)| = @|a|;})
  91. "\n")
  92. @(if (equal? arg-types '("Scheme_Object*")) @string-append{send_special_result(future, @(car arg-names));} "")
  93. future_do_runtimecall(fts, (void*)f, 0, 1);
  94. future = fts->thread->current_ft;
  95. @(if (string=? result-type "void") "" @string-append{retval = @|fretval|;})
  96. @(if (string=? result-type "void") "" @string-append{@|fretval| = 0;})
  97. @(if (string=? result-type "Scheme_Object*") @string-append{receive_special_result(future, retval, 1);} "")
  98. @(if (string=? result-type "void") "" "return retval;")
  99. }
  100. })
  101. (newline))
  102. (define (gen-runtime-side t)
  103. (define-values (arg-types result-type) (parse-type t))
  104. (define arg-names (map symbol->string (map (lambda (v) (gensym)) arg-types)))
  105. (define return (if (equal? result-type "void") "" "return"))
  106. (define args (make-arg-list arg-types arg-names))
  107. (define ts (symbol->string t))
  108. (for-each
  109. display
  110. @list{
  111. case SIG_@|ts|:
  112. {
  113. prim_@|ts| f = (prim_@|ts|)future->prim_func;
  114. @(if (string=? result-type "void") "" @string-append{GC_CAN_IGNORE @|result-type| retval;})
  115. @(string-join
  116. (for/list ([t (in-string (type->arg-string t))]
  117. [i (in-naturals)])
  118. @string-append{JIT_TS_LOCALIZE(@(char->type t), arg_@|(string t)|@|(number->string i)|);})
  119. " ")
  120. @(if (equal? arg-types '("Scheme_Object*")) @string-append{receive_special_result(future, future->arg_s0, 1);} "")
  121. @(string-join
  122. (for/list ([t (in-string (type->arg-string t))]
  123. [i (in-naturals)]
  124. #:when (is-pointer-type? t))
  125. @string-append{future->arg_@|(string t)|@|(number->string i)| = NULL;})
  126. " ")
  127. @(string-join
  128. (for/list ([t (in-string (type->arg-string t))]
  129. [i (in-naturals)]
  130. #:when (eq? t #\S))
  131. @string-append{ADJUST_RS_ARG(future, arg_@|(string t)|@|(number->string i)|);})
  132. " ")
  133. @(if (string=? result-type "void") "" "retval = ")
  134. f(@(string-join
  135. (for/list ([t (in-string (type->arg-string t))]
  136. [i (in-naturals)])
  137. @string-append{arg_@|(string t)|@|(number->string i)|})
  138. ", "));
  139. @(if (string=? result-type "void") "" @string-append{future->retval_@(substring ts (sub1 (string-length ts))) = retval;})
  140. @(if (string=? result-type "Scheme_Object*") @string-append{send_special_result(future, retval);} "")
  141. break;
  142. }
  143. })
  144. (newline))
  145. (define proto-counter 10)
  146. (define (gen-protos t)
  147. (define-values (arg-types result-type) (parse-type t))
  148. (define arg-names (map symbol->string (map (lambda (v) (gensym)) arg-types)))
  149. (define return (if (equal? result-type "void") "" "return"))
  150. (define args (make-arg-list arg-types arg-names))
  151. (define ts (symbol->string t))
  152. (printf "#define SIG_~a ~a\n" t proto-counter)
  153. (set! proto-counter (add1 proto-counter))
  154. (display
  155. @string-append{typedef @|result-type| (*prim_@|ts|)(@(string-join arg-types ", "));})
  156. (newline)
  157. (display @string-append{@|result-type| scheme_rtcall_@|ts|(const char *who, int src_type, prim_@|ts| f@(if (null? arg-types) "" ",") @|args|);})
  158. (newline))
  159. (define types
  160. '(siS_s
  161. iSs_s
  162. s_s
  163. n_s
  164. _s
  165. ss_s
  166. ssi_s
  167. tt_s
  168. ss_m
  169. Sl_s
  170. l_s
  171. bsi_v
  172. iiS_v
  173. ss_v
  174. b_v
  175. sl_s
  176. iS_s
  177. S_s
  178. s_v
  179. iSi_s
  180. siS_v
  181. z_p
  182. si_s
  183. sis_v
  184. ss_i))
  185. (with-output-to-file "jit_ts_def.c"
  186. #:exists 'replace
  187. (lambda ()
  188. (for-each gen-definer types)))
  189. (with-output-to-file "jit_ts_future_glue.c"
  190. #:exists 'replace
  191. (lambda ()
  192. (for-each gen-future-side types)))
  193. (with-output-to-file "jit_ts_runtime_glue.c"
  194. #:exists 'replace
  195. (lambda ()
  196. (for-each gen-runtime-side types)))
  197. (with-output-to-file "jit_ts_protos.h"
  198. #:exists 'replace
  199. (lambda ()
  200. (for-each gen-protos types)))