* Ikarus now handles interrupts (e.g. ^C) by signalling an error

when an interrupt occurs.
This commit is contained in:
Abdulaziz Ghuloum 2006-12-24 11:24:53 +03:00
parent 7fed78fa9d
commit 599f68aa84
9 changed files with 51 additions and 18 deletions

Binary file not shown.

View File

@ -184,7 +184,7 @@ int main(int argc, char** argv){
#endif #endif
void handler(int signo, struct __siginfo* info, ucontext_t* uap){ void handler(int signo, struct __siginfo* info, ucontext_t* uap){
the_pcb->engine_counter = 1; the_pcb->engine_counter = -1;
the_pcb->interrupted = 1; the_pcb->interrupted = 1;
} }

View File

@ -759,13 +759,26 @@ ikrt_close_file(ikp fd, ikpcb* pcb){
ikp ikp
ikrt_read(ikp fd, ikp buff, ikpcb* pcb){ ikrt_read(ikp fd, ikp buff, ikpcb* pcb){
int bytes = read(unfix(fd), string_data(buff), unfix(ref(buff, off_string_length))); int bytes =
read(unfix(fd), string_data(buff), unfix(ref(buff, off_string_length)));
ikp fbytes = fix(bytes);
if (bytes == unfix(fbytes)){
return fbytes;
} else {
fprintf(stderr, "ERR: ikrt_read: too big\n");
exit(-1);
}
}
#if 0
if(bytes == -1){ if(bytes == -1){
fprintf(stderr, "ERR=%s (%d)\n", strerror(errno), errno);
return false_object; return false_object;
} else { } else {
return fix(bytes); return fix(bytes);
} }
} }
#endif
ikp ikp
ikrt_open_input_file(ikp fname, ikpcb* pcb){ ikrt_open_input_file(ikp fname, ikpcb* pcb){

Binary file not shown.

View File

@ -414,16 +414,18 @@
($string-ref ($port-input-buffer p) idx)) ($string-ref ($port-input-buffer p) idx))
(if open? (if open?
(let ([bytes (let ([bytes
(foreign-call "ikrt_read" fd (foreign-call "ikrt_read"
($port-input-buffer p))]) fd ($port-input-buffer p))])
;($do-event)
(cond (cond
[(not bytes) [($fx> bytes 0)
(error 'read-char "Cannot read from ~s" port-name)] ($set-port-input-size! p bytes)
($read-char p)]
[($fx= bytes 0) [($fx= bytes 0)
(eof-object)] (eof-object)]
[else [else
($set-port-input-size! p bytes) (error 'read-char "Cannot read from ~a"
($read-char p)])) port-name)]))
(error 'read-char "port ~s is closed" p))))] (error 'read-char "port ~s is closed" p))))]
[(peek-char p) [(peek-char p)
(unless (input-port? p) (unless (input-port? p)

View File

@ -176,6 +176,8 @@
[$arg-list 0 value] [$arg-list 0 value]
[$seal-frame-and-call 1 tail] [$seal-frame-and-call 1 tail]
[$frame->continuation 1 value] [$frame->continuation 1 value]
[$interrupted? 0 pred]
[$unset-interrupted! 0 effect]
;;; ;;;
;;; records ;;; records
;;; ;;;
@ -2390,7 +2392,7 @@
(make-seq (make-seq
(make-interrupt-call (make-interrupt-call
(make-primcall '$engine-check '()) (make-primcall '$engine-check '())
(make-funcall (make-primref '$engine-expired) '())) (make-funcall (make-primref '$do-event) '()))
x)) x))
(define (CaseExpr x) (define (CaseExpr x)
(record-case x (record-case x
@ -2964,6 +2966,7 @@
[(dirty-vector) (mem 28 pcr)] [(dirty-vector) (mem 28 pcr)]
[(arg-list) (mem 32 pcr)] [(arg-list) (mem 32 pcr)]
[(engine-counter) (mem 36 pcr)] [(engine-counter) (mem 36 pcr)]
[(interrupted) (mem 40 pcr)]
[else (error 'pcb-ref "invalid arg ~s" x)]))) [else (error 'pcb-ref "invalid arg ~s" x)])))
(define (primref-loc op) (define (primref-loc op)
@ -2994,7 +2997,10 @@
[else (obj x)])) [else (obj x)]))
(define (cond-branch op Lt Lf ac) (define (cond-branch op Lt Lf ac)
(define (opposite x) (define (opposite x)
(cadr (assq x '([je jne] [jl jge] [jle jg] [jg jle] [jge jl])))) (cond
[(assq x '([je jne] [jne je] [jl jge] [jle jg] [jg jle] [jge jl]))
=> cadr]
[else (error who "BUG: no opposite of ~s" x)]))
(unless (or Lt Lf) (unless (or Lt Lf)
(error 'cond-branch "no labels")) (error 'cond-branch "no labels"))
(cond (cond
@ -3211,6 +3217,10 @@
(subl (int wordsize) eax) (subl (int wordsize) eax)
(cmpl eax fpr) (cmpl eax fpr)
(cond-branch 'je Lt Lf ac))] (cond-branch 'je Lt Lf ac))]
[($interrupted?)
(list* (movl (pcb-ref 'interrupted) eax)
(cmpl (int 0) eax)
(cond-branch 'jne Lt Lf ac))]
[($fp-overflow) [($fp-overflow)
(list* (cmpl (pcb-ref 'frame-redline) fpr) (list* (cmpl (pcb-ref 'frame-redline) fpr)
(cond-branch 'jle Lt Lf ac))] (cond-branch 'jle Lt Lf ac))]
@ -4059,6 +4069,9 @@
(addl (pcb-ref 'dirty-vector) ebx) (addl (pcb-ref 'dirty-vector) ebx)
(movl (int dirty-word) (mem 0 ebx)) (movl (int dirty-word) (mem 0 ebx))
ac)] ac)]
[($unset-interrupted!)
(list* (movl (int 0) (pcb-ref 'interrupted))
ac)]
[(cons pair? void $fxadd1 $fxsub1 $record-ref $fx=) [(cons pair? void $fxadd1 $fxsub1 $record-ref $fx=)
(let f ([arg* arg*]) (let f ([arg* arg*])
(cond (cond

View File

@ -72,7 +72,12 @@
(lambda (x y) (lambda (x y)
(error 'fx+ "overflow"))) (error 'fx+ "overflow")))
(primitive-set! '$engine-expired (primitive-set! '$do-event
(lambda () (lambda ()
(display "Engine Expired\n" (console-output-port)))) (if ($interrupted?)
(begin
($unset-interrupted!)
(error #f "Interrupted"))
(display "Engine Expired\n" (console-output-port)))))

View File

@ -304,11 +304,11 @@
))] ))]
[else (syntax-error x)]))) [else (syntax-error x)])))
;;; ;;;
(primitive-set! 'interpret ;(primitive-set! 'interpret
(lambda (x) ; (lambda (x)
(let ([x (expand x)]) ; (let ([x (expand x)])
(let ([p (C x '())]) ; (let ([p (C x '())])
(p '()))))) ; (p '())))))
;;; ;;;
(primitive-set! 'current-eval (primitive-set! 'current-eval
(make-parameter (make-parameter

View File

@ -114,7 +114,7 @@
$set-tcbucket-dlink-prev! $set-tcbucket-dlink-next! call/cf $set-tcbucket-dlink-prev! $set-tcbucket-dlink-next! call/cf
trace-symbol! untrace-symbol! make-traced-procedure trace-symbol! untrace-symbol! make-traced-procedure
fixnum->string fixnum->string
$interrupted? $unset-interrupted! $do-event
;;; TODO: must open-code ;;; TODO: must open-code
$make-port/input $make-port/output $make-port/both $make-port/input $make-port/output $make-port/both