123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- (define-record-type stack-block :stack-block
- (stack-blocks-are-made-from-c)
- stack-block?
- (free? stack-block-free? set-stack-block-free?!)
- (unwind stack-block-unwind)
- (proc-name stack-block-proc-name)
- (placeholder stack-block-placeholder set-stack-block-placeholder!)
- (next stack-block-next))
- (define-exported-binding "s48-stack-block-type" :stack-block)
- (define (callback block proc . args)
- (let ((done? #f))
- (return-from-callback block
- (dynamic-wind
- (lambda ()
- (if done?
- (apply
- assertion-violation 'callback
- "attempt to throw into a callback"
- (cons proc args))))
- (lambda ()
- (let ((result (apply proc args)))
- (disable-interrupts!)
- (set! done? #t)
- result))
- (lambda ()
- (if (not done?)
- (begin
- (set! done? #t)
- (set-stack-block-free?! block #t)
- (clear-stack-top!))))))))
- (define-exported-binding "s48-callback" callback)
- (import-lambda-definition clear-stack-top! () "s48_clear_stack_top")
- (define (delay-callback-return block value)
- (let ((placeholder (make-placeholder)))
- (set-stack-block-placeholder! block placeholder)
- (enable-interrupts!)
- (placeholder-value placeholder)
- value))
- (define-exported-binding "s48-delay-callback-return" delay-callback-return)
- (define uncovered-return-handler
- (lambda (opcode reason . args)
- (define (blow-up con extract-message)
-
- (let ((rev (reverse args)))
- (raise
- (condition
- con
- (make-external-exception)
- (make-who-condition (cadr rev))
- (make-message-condition
- (os-string->string (byte-vector->os-string (extract-message (car rev)))))
- (make-irritants-condition (reverse (cddr rev)))))))
- (enum-case exception reason
- ((external-error)
- (blow-up (make-error) values))
- ((external-assertion-violation)
- (blow-up (make-assertion-violation) values))
- ((external-os-error)
- (blow-up (make-error) os-error-message))
- ((out-of-memory)
- (raise
- (condition
- (make-implementation-restriction-violation)
- (make-who-condition 'call-external-value)
- (make-message-condition "out of memory"))))
- ((callback-return-uncovered)
- (call-with-values
- (lambda ()
- (if (= 2 (length args))
- (values (car args)
- (cadr args)
- #f)
- (let ((args (reverse args)))
- (values (car args)
- (cadr args)
- (reverse (cddr args))))))
- (lambda (block return-value exception-args)
- (let ((placeholder (stack-block-placeholder block)))
- (set-stack-block-placeholder! block #f)
- (placeholder-set! placeholder #t)
- (if exception-args
- (apply signal-vm-exception opcode return-value exception-args)
- return-value)))))
- (else
- (apply signal-vm-exception opcode reason args)))))
- (define-condition-type &external-exception &serious
- make-external-exception external-exception?)
- (define (block-depth block)
- (if block
- (+ 1 (block-depth (stack-block-next block)))
- 0))
- (for-each (lambda (opcode)
- (define-vm-exception-handler opcode uncovered-return-handler))
- (list (enum op call-external-value)
- (enum op return-from-callback)))
- (define (call-imported-binding proc . args)
- (if (and (shared-binding? proc)
- (shared-binding-is-import? proc))
- (let ((value (shared-binding-ref proc)))
- (if (byte-vector? value)
- (apply call-external-value
- value
- (shared-binding-name proc)
- args)
- (apply assertion-violation 'call-imported-binding "bad procedure"
- proc args)))
- (apply assertion-violation 'call-imported-binding "procedure not defined"
- proc args)))
- (define (call-imported-binding-2 proc . args)
- (if (and (shared-binding? proc)
- (shared-binding-is-import? proc))
- (let ((value (shared-binding-ref proc)))
- (if (byte-vector? value)
- (apply call-external-value-2
- value
- (shared-binding-name proc)
- args)
- (apply assertion-violation 'call-imported-binding-2 "bad procedure"
- proc args)))
- (apply assertion-violation 'call-imported-binding-2 "procedure not defined"
- proc args)))
- (define-exported-binding "s48-the-record-type" :record-type)
|