mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-19 03:00:25 +02:00
*** empty log message ***
This commit is contained in:
parent
8710eba09b
commit
41f248a84a
14 changed files with 168 additions and 184 deletions
|
@ -26,23 +26,6 @@
|
||||||
:use-module (ice-9 and-let-star)
|
:use-module (ice-9 and-let-star)
|
||||||
:export (gscheme))
|
:export (gscheme))
|
||||||
|
|
||||||
|
|
||||||
;;;
|
|
||||||
;;; Macro expander
|
|
||||||
;;;
|
|
||||||
|
|
||||||
(define (expand x)
|
|
||||||
(expand-macro x (current-module)))
|
|
||||||
|
|
||||||
(define (expand-macro x m)
|
|
||||||
(if (pair? x)
|
|
||||||
(let* ((s (car x))
|
|
||||||
(v (and (symbol? s) (module-defined? m s) (module-ref m s))))
|
|
||||||
(if (defmacro? v)
|
|
||||||
(expand-macro (apply (defmacro-transformer v) (cdr x)) m)
|
|
||||||
(cons (expand-macro (car x) m) (expand-macro (cdr x) m))))
|
|
||||||
x))
|
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Translator
|
;;; Translator
|
||||||
|
@ -111,10 +94,22 @@
|
||||||
(_loop ,@(map translate update)))))))
|
(_loop ,@(map translate update)))))))
|
||||||
(_loop ,@(map translate init))))))
|
(_loop ,@(map translate init))))))
|
||||||
(else
|
(else
|
||||||
|
(let ((e (expand x)))
|
||||||
|
(if (eq? e x)
|
||||||
(let ((prim (and (symbol? head) (symbol-append '@ head))))
|
(let ((prim (and (symbol? head) (symbol-append '@ head))))
|
||||||
(if (and prim (ghil-primitive? prim))
|
(if (and prim (ghil-primitive? prim))
|
||||||
(cons prim (map translate rest))
|
(cons prim (map translate rest))
|
||||||
(cons (translate head) (map translate rest))))))))
|
(cons (translate head) (map translate rest))))
|
||||||
|
(translate e)))))))
|
||||||
|
|
||||||
|
(define (expand x)
|
||||||
|
(if (and (symbol? (car x))
|
||||||
|
(module-defined? (current-module) (car x)))
|
||||||
|
(let ((v (module-ref (current-module) (car x))))
|
||||||
|
(if (defmacro? v)
|
||||||
|
(apply (defmacro-transformer v) (cdr x))
|
||||||
|
x))
|
||||||
|
x))
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
|
@ -125,7 +120,6 @@
|
||||||
:title "Guile Scheme"
|
:title "Guile Scheme"
|
||||||
:version "0.4"
|
:version "0.4"
|
||||||
:reader read
|
:reader read
|
||||||
:expander expand
|
|
||||||
:translator translate
|
:translator translate
|
||||||
:printer write
|
:printer write
|
||||||
)
|
)
|
||||||
|
|
|
@ -136,14 +136,14 @@
|
||||||
;; TEST
|
;; TEST
|
||||||
;; (br-if-not L1)
|
;; (br-if-not L1)
|
||||||
;; THEN
|
;; THEN
|
||||||
;; (jump L2)
|
;; (br L2)
|
||||||
;; L1: ELSE
|
;; L1: ELSE
|
||||||
;; L2:
|
;; L2:
|
||||||
(let ((L1 (make-label)) (L2 (make-label)))
|
(let ((L1 (make-label)) (L2 (make-label)))
|
||||||
(comp-push test)
|
(comp-push test)
|
||||||
(push-code! (make-<glil-branch> 'br-if-not L1))
|
(push-code! (make-<glil-branch> 'br-if-not L1))
|
||||||
(comp-tail then)
|
(comp-tail then)
|
||||||
(if (not tail) (push-code! (make-<glil-branch> 'jump L2)))
|
(if (not tail) (push-code! (make-<glil-branch> 'br L2)))
|
||||||
(push-code! (make-<glil-label> L1))
|
(push-code! (make-<glil-label> L1))
|
||||||
(comp-tail else)
|
(comp-tail else)
|
||||||
(if (not tail) (push-code! (make-<glil-label> L2)))))
|
(if (not tail) (push-code! (make-<glil-label> L2)))))
|
||||||
|
|
|
@ -156,7 +156,7 @@
|
||||||
(($ <glil-module> op module name)
|
(($ <glil-module> op module name)
|
||||||
`(,(symbol-append 'module- op) ,module ,name))
|
`(,(symbol-append 'module- op) ,module ,name))
|
||||||
;; controls
|
;; controls
|
||||||
(($ <glil-label> label) `(label ,label))
|
(($ <glil-label> label) label)
|
||||||
(($ <glil-branch> inst label) `(,inst ,label))
|
(($ <glil-branch> inst label) `(,inst ,label))
|
||||||
(($ <glil-call> inst nargs) `(,inst ,nargs))))
|
(($ <glil-call> inst nargs) `(,inst ,nargs))))
|
||||||
|
|
||||||
|
@ -168,8 +168,7 @@
|
||||||
(define (pprint-glil glil)
|
(define (pprint-glil glil)
|
||||||
(let print ((code (unparse glil)) (column 0))
|
(let print ((code (unparse glil)) (column 0))
|
||||||
(display (make-string column #\space))
|
(display (make-string column #\space))
|
||||||
(case (car code)
|
(cond ((and (pair? code) (eq? (car code) '@asm))
|
||||||
((@asm)
|
|
||||||
(format #t "(@asm ~A\n" (cadr code))
|
(format #t "(@asm ~A\n" (cadr code))
|
||||||
(let ((col (+ column 2)))
|
(let ((col (+ column 2)))
|
||||||
(let loop ((l (cddr code)))
|
(let loop ((l (cddr code)))
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
(define-structure (venv parent nexts closure?))
|
(define-structure (venv parent nexts closure?))
|
||||||
(define-structure (vmod id))
|
(define-structure (vmod id))
|
||||||
(define-structure (vlink module name))
|
(define-structure (vlink module name))
|
||||||
(define-structure (bytespec nargs nrest nlocs nexts bytes objs))
|
(define-structure (bytespec nargs nrest nlocs nexts bytes objs closure?))
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
|
@ -74,33 +74,17 @@
|
||||||
(label-alist '())
|
(label-alist '())
|
||||||
(object-alist '()))
|
(object-alist '()))
|
||||||
(define (push-code! code)
|
(define (push-code! code)
|
||||||
(set! stack (optimizing-push code stack)))
|
(set! stack (cons (code->bytes code) stack)))
|
||||||
(define (push-object! x)
|
(define (push-object! x)
|
||||||
(cond ((object->code x) => push-code!)
|
(cond ((object->code x) => push-code!)
|
||||||
(toplevel
|
(toplevel (dump-object! push-code! x))
|
||||||
;; top-level object-dump
|
|
||||||
(cond ((object-assoc x object-alist) =>
|
|
||||||
(lambda (obj+index)
|
|
||||||
(cond ((not (cdr obj+index))
|
|
||||||
(set-cdr! obj+index nlocs)
|
|
||||||
(set! nlocs (+ nlocs 1))))
|
|
||||||
(push-code! `(local-ref ,(cdr obj+index)))))
|
|
||||||
(else
|
(else
|
||||||
(set! object-alist (acons x #f object-alist))
|
|
||||||
(push-code! `(object-dump ,x)))))
|
|
||||||
(else
|
|
||||||
;; local object-ref
|
|
||||||
(let ((i (cond ((object-assoc x object-alist) => cdr)
|
(let ((i (cond ((object-assoc x object-alist) => cdr)
|
||||||
(else
|
(else
|
||||||
(let ((i (length object-alist)))
|
(let ((i (length object-alist)))
|
||||||
(set! object-alist (acons x i object-alist))
|
(set! object-alist (acons x i object-alist))
|
||||||
i)))))
|
i)))))
|
||||||
(push-code! `(object-ref ,i))))))
|
(push-code! `(object-ref ,i))))))
|
||||||
(define (label-ref key)
|
|
||||||
(assq-ref label-alist key))
|
|
||||||
(define (label-set key)
|
|
||||||
(let ((addr (apply + (map length stack))))
|
|
||||||
(set! label-alist (assq-set! label-alist key addr))))
|
|
||||||
(define (generate-code x)
|
(define (generate-code x)
|
||||||
(match x
|
(match x
|
||||||
(($ <vm-asm> venv)
|
(($ <vm-asm> venv)
|
||||||
|
@ -108,7 +92,7 @@
|
||||||
(if (venv-closure? venv) (push-code! `(make-closure))))
|
(if (venv-closure? venv) (push-code! `(make-closure))))
|
||||||
|
|
||||||
(($ <glil-void>)
|
(($ <glil-void>)
|
||||||
(push-code! `(void)))
|
(push-code! '(void)))
|
||||||
|
|
||||||
(($ <glil-const> x)
|
(($ <glil-const> x)
|
||||||
(push-object! x))
|
(push-object! x))
|
||||||
|
@ -139,11 +123,14 @@
|
||||||
(push-code! '(variable-set))))
|
(push-code! '(variable-set))))
|
||||||
|
|
||||||
(($ <glil-label> label)
|
(($ <glil-label> label)
|
||||||
(label-set label))
|
(define (byte-length x)
|
||||||
|
(cond ((string? x) (string-length x))
|
||||||
|
(else 3)))
|
||||||
|
(let ((addr (apply + (map byte-length stack))))
|
||||||
|
(set! label-alist (assq-set! label-alist label addr))))
|
||||||
|
|
||||||
(($ <glil-branch> inst label)
|
(($ <glil-branch> inst label)
|
||||||
(let ((setter (lambda (addr) (- (label-ref label) addr))))
|
(set! stack (cons (list inst label) stack)))
|
||||||
(push-code! (list inst setter))))
|
|
||||||
|
|
||||||
(($ <glil-call> inst nargs)
|
(($ <glil-call> inst nargs)
|
||||||
(if (instruction? inst)
|
(if (instruction? inst)
|
||||||
|
@ -158,73 +145,31 @@
|
||||||
;;
|
;;
|
||||||
;; main
|
;; main
|
||||||
(for-each generate-code body)
|
(for-each generate-code body)
|
||||||
|
(let ((bytes (stack->bytes (reverse! stack) label-alist)))
|
||||||
(if toplevel
|
(if toplevel
|
||||||
;; top-level
|
(make-dumpcode nlocs nexts bytes)
|
||||||
(let ((new '()))
|
(let ((objs (map car (reverse! object-alist))))
|
||||||
(define (push-code! x)
|
(make-bytespec nargs nrest nlocs nexts bytes objs
|
||||||
(set! new (cons x new)))
|
(venv-closure? venv)))))))))
|
||||||
(do ((stack (reverse! stack) (cdr stack)))
|
|
||||||
((null? stack)
|
|
||||||
(make-dumpcode nlocs nexts (stack->bytes (reverse! new))))
|
|
||||||
(if (eq? (caar stack) 'object-dump)
|
|
||||||
(let ((x (cadar stack)))
|
|
||||||
(dump-object! push-code! x)
|
|
||||||
(cond ((object-assoc x object-alist) =>
|
|
||||||
(lambda (obj+index)
|
|
||||||
(cond ((cdr obj+index) =>
|
|
||||||
(lambda (n)
|
|
||||||
(push-code! '(dup))
|
|
||||||
(push-code! `(local-set ,n)))))))))
|
|
||||||
(push-code! (car stack)))))
|
|
||||||
;; closures
|
|
||||||
(let ((bytes (stack->bytes (reverse! stack)))
|
|
||||||
(objs (map car (reverse! object-alist))))
|
|
||||||
(make-bytespec nargs nrest nlocs nexts bytes objs)))))))
|
|
||||||
|
|
||||||
(define (object-assoc x alist)
|
(define (object-assoc x alist)
|
||||||
(if (vlink? x) (assoc x alist) (assq x alist)))
|
(if (vlink? x) (assoc x alist) (assq x alist)))
|
||||||
|
|
||||||
(define (stack->bytes stack)
|
(define (stack->bytes stack label-alist)
|
||||||
(let loop ((result '()) (stack stack) (addr 0))
|
(let loop ((result '()) (stack stack) (addr 0))
|
||||||
(if (null? stack)
|
(if (null? stack)
|
||||||
(apply string-append (reverse! result))
|
(apply string-append (reverse! result))
|
||||||
(let* ((orig (car stack))
|
(let ((bytes (car stack)))
|
||||||
(addr (+ addr (length orig)))
|
(if (pair? bytes)
|
||||||
(code (if (and (pair? (cdr orig)) (procedure? (cadr orig)))
|
(let* ((offset (- (assq-ref label-alist (cadr bytes))
|
||||||
`(,(car orig) ,((cadr orig) addr))
|
(+ addr 3)))
|
||||||
orig)))
|
(n (if (< offset 0) (+ offset 65536) offset)))
|
||||||
(loop (cons (code->bytes code) result) (cdr stack) addr)))))
|
(set! bytes (code->bytes (list (car bytes)
|
||||||
|
(quotient n 256)
|
||||||
|
(modulo n 256))))))
|
||||||
;;;
|
(loop (cons bytes result)
|
||||||
;;; Bytecode optimization
|
(cdr stack)
|
||||||
;;;
|
(+ addr (string-length bytes)))))))
|
||||||
|
|
||||||
(define *optimization-table*
|
|
||||||
'((not (not . not-not)
|
|
||||||
(eq? . not-eq?)
|
|
||||||
(null? . not-null?)
|
|
||||||
(not-not . not)
|
|
||||||
(not-eq? . eq?)
|
|
||||||
(not-null? . null?))
|
|
||||||
(br-if (not . br-if-not)
|
|
||||||
(eq? . br-if-eq)
|
|
||||||
(null? . br-if-null)
|
|
||||||
(not-not . br-if)
|
|
||||||
(not-eq? . br-if-not-eq)
|
|
||||||
(not-null? . br-if-not-null))
|
|
||||||
(br-if-not (not . br-if)
|
|
||||||
(eq? . br-if-not-eq)
|
|
||||||
(null? . br-if-not-null)
|
|
||||||
(not-not . br-if-not)
|
|
||||||
(not-eq? . br-if-eq)
|
|
||||||
(not-null? . br-if-null))))
|
|
||||||
|
|
||||||
(define (optimizing-push code stack)
|
|
||||||
(let ((alist (assq-ref *optimization-table* (car code))))
|
|
||||||
(cond ((and alist (pair? stack) (assq-ref alist (caar stack))) =>
|
|
||||||
(lambda (inst) (cons (cons inst (cdr code)) (cdr stack))))
|
|
||||||
(else (cons (code-pack code) stack)))))
|
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
|
@ -239,7 +184,7 @@
|
||||||
((object->code x) => push-code!)
|
((object->code x) => push-code!)
|
||||||
((bytespec? x)
|
((bytespec? x)
|
||||||
(match x
|
(match x
|
||||||
(($ bytespec nargs nrest nlocs nexts bytes objs)
|
(($ bytespec nargs nrest nlocs nexts bytes objs closure?)
|
||||||
;; dump parameters
|
;; dump parameters
|
||||||
(cond
|
(cond
|
||||||
((and (< nargs 4) (< nlocs 8) (< nexts 4))
|
((and (< nargs 4) (< nlocs 8) (< nexts 4))
|
||||||
|
@ -264,7 +209,7 @@
|
||||||
;; dump bytecode
|
;; dump bytecode
|
||||||
(push-code! `(load-program ,bytes)))))
|
(push-code! `(load-program ,bytes)))))
|
||||||
((vlink? x)
|
((vlink? x)
|
||||||
(dump! (vlink-module x))
|
;;; (dump! (vlink-module x)) ;; FIXME: no module support now
|
||||||
(dump! (vlink-name x))
|
(dump! (vlink-name x))
|
||||||
(push-code! `(link)))
|
(push-code! `(link)))
|
||||||
((vmod? x)
|
((vmod? x)
|
||||||
|
|
|
@ -36,11 +36,6 @@
|
||||||
(cond ((< n 10)
|
(cond ((< n 10)
|
||||||
(let ((abbrev (string->symbol (format #f "~A:~A" inst n))))
|
(let ((abbrev (string->symbol (format #f "~A:~A" inst n))))
|
||||||
(if (instruction? abbrev) (list abbrev) code)))
|
(if (instruction? abbrev) (list abbrev) code)))
|
||||||
((> n 255)
|
|
||||||
(let ((double (string->symbol (format #f "~A*2" inst))))
|
|
||||||
(if (instruction? double)
|
|
||||||
(list double (quotient n 256) (modulo n 256))
|
|
||||||
(apply error "Index out of range:" code))))
|
|
||||||
(else code)))
|
(else code)))
|
||||||
(else code)))
|
(else code)))
|
||||||
|
|
||||||
|
@ -91,7 +86,8 @@
|
||||||
(else #f)))
|
(else #f)))
|
||||||
|
|
||||||
(define (code->bytes code)
|
(define (code->bytes code)
|
||||||
(let* ((inst (car code))
|
(let* ((code (code-pack code))
|
||||||
|
(inst (car code))
|
||||||
(rest (cdr code))
|
(rest (cdr code))
|
||||||
(head (make-string 1 (integer->char (instruction->opcode inst))))
|
(head (make-string 1 (integer->char (instruction->opcode inst))))
|
||||||
(len (instruction-length inst)))
|
(len (instruction-length inst)))
|
||||||
|
|
|
@ -44,7 +44,8 @@
|
||||||
(nlocs (caddr arity))
|
(nlocs (caddr arity))
|
||||||
(nexts (cadddr arity))
|
(nexts (cadddr arity))
|
||||||
(bytes (program-bytecode prog))
|
(bytes (program-bytecode prog))
|
||||||
(objs (program-objects prog)))
|
(objs (program-objects prog))
|
||||||
|
(exts (program-external prog)))
|
||||||
;; Disassemble this bytecode
|
;; Disassemble this bytecode
|
||||||
(format #t "Disassembly of ~A:\n\n" prog)
|
(format #t "Disassembly of ~A:\n\n" prog)
|
||||||
(format #t "nargs = ~A nrest = ~A nlocs = ~A nexts = ~A\n\n"
|
(format #t "nargs = ~A nrest = ~A nlocs = ~A nexts = ~A\n\n"
|
||||||
|
@ -53,6 +54,8 @@
|
||||||
(disassemble-bytecode bytes objs)
|
(disassemble-bytecode bytes objs)
|
||||||
(if (> (vector-length objs) 0)
|
(if (> (vector-length objs) 0)
|
||||||
(disassemble-objects objs))
|
(disassemble-objects objs))
|
||||||
|
(if (pair? exts)
|
||||||
|
(disassemble-externals exts))
|
||||||
;; Disassemble other bytecode in it
|
;; Disassemble other bytecode in it
|
||||||
(for-each
|
(for-each
|
||||||
(lambda (x)
|
(lambda (x)
|
||||||
|
@ -89,6 +92,15 @@
|
||||||
(let ((info (object->string (vector-ref objs n))))
|
(let ((info (object->string (vector-ref objs n))))
|
||||||
(print-info n info #f)))))
|
(print-info n info #f)))))
|
||||||
|
|
||||||
|
(define (disassemble-externals exts)
|
||||||
|
(display "Externals:\n\n")
|
||||||
|
(let ((len (length exts)))
|
||||||
|
(do ((n 0 (1+ n))
|
||||||
|
(l exts (cdr l)))
|
||||||
|
((null? l) (newline))
|
||||||
|
(let ((info (object->string (car l))))
|
||||||
|
(print-info n info #f)))))
|
||||||
|
|
||||||
(define (disassemble-meta meta)
|
(define (disassemble-meta meta)
|
||||||
(display "Meta info:\n\n")
|
(display "Meta info:\n\n")
|
||||||
(for-each (lambda (data)
|
(for-each (lambda (data)
|
||||||
|
@ -98,11 +110,12 @@
|
||||||
|
|
||||||
(define (original-value addr code objs)
|
(define (original-value addr code objs)
|
||||||
(define (branch-code? code)
|
(define (branch-code? code)
|
||||||
(string-match "^(br|jump)" (symbol->string (car code))))
|
(string-match "^br" (symbol->string (car code))))
|
||||||
(let ((code (code-unpack code)))
|
(let ((code (code-unpack code)))
|
||||||
(cond ((code->object code) => object->string)
|
(cond ((code->object code) => object->string)
|
||||||
((branch-code? code)
|
((branch-code? code)
|
||||||
(format #f "-> ~A" (+ addr (cadr code) 2)))
|
(let ((offset (+ (* (cadr code) 256) (caddr code))))
|
||||||
|
(format #f "-> ~A" (+ addr offset 3))))
|
||||||
(else
|
(else
|
||||||
(let ((inst (car code)) (args (cdr code)))
|
(let ((inst (car code)) (args (cdr code)))
|
||||||
(case inst
|
(case inst
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(define-module (system vm load)
|
(define-module (system vm load)
|
||||||
:use-module (system vm core)
|
|
||||||
:autoload (system base language) (compile-file-in lookup-language)
|
:autoload (system base language) (compile-file-in lookup-language)
|
||||||
|
:use-module (system vm core)
|
||||||
:use-module (ice-9 regex)
|
:use-module (ice-9 regex)
|
||||||
:export (load/compile))
|
:export (load/compile))
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(define-module (system vm trace)
|
(define-module (system vm trace)
|
||||||
|
:use-syntax (system base syntax)
|
||||||
:use-module (system vm core)
|
:use-module (system vm core)
|
||||||
:use-module (system vm frame)
|
:use-module (system vm frame)
|
||||||
:use-module (ice-9 format)
|
:use-module (ice-9 format)
|
||||||
|
@ -49,7 +50,7 @@
|
||||||
(case (car opts)
|
(case (car opts)
|
||||||
((:s) (format #t "~20S" (vm-fetch-stack vm)))
|
((:s) (format #t "~20S" (vm-fetch-stack vm)))
|
||||||
((:v) (format #t "~20S" (frame-variables frame)))
|
((:v) (format #t "~20S" (frame-variables frame)))
|
||||||
((:e) (format #t "~20S" (program-external (frame-program frame))))))))
|
((:e) (format #t "~20A" (object->string (frame-external-link frame))))))))
|
||||||
|
|
||||||
(define (trace-apply vm)
|
(define (trace-apply vm)
|
||||||
(if (vm-option vm 'trace-first)
|
(if (vm-option vm 'trace-first)
|
||||||
|
|
27
src/vm.c
27
src/vm.c
|
@ -68,6 +68,7 @@ make_vm_heap_frame (SCM *fp)
|
||||||
p->program = SCM_UNDEFINED;
|
p->program = SCM_UNDEFINED;
|
||||||
p->variables = SCM_UNDEFINED;
|
p->variables = SCM_UNDEFINED;
|
||||||
p->dynamic_link = SCM_UNDEFINED;
|
p->dynamic_link = SCM_UNDEFINED;
|
||||||
|
p->external_link = SCM_UNDEFINED;
|
||||||
SCM_RETURN_NEWSMOB (scm_tc16_vm_heap_frame, p);
|
SCM_RETURN_NEWSMOB (scm_tc16_vm_heap_frame, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +78,8 @@ vm_heap_frame_mark (SCM obj)
|
||||||
struct scm_vm_heap_frame *p = SCM_VM_HEAP_FRAME_DATA (obj);
|
struct scm_vm_heap_frame *p = SCM_VM_HEAP_FRAME_DATA (obj);
|
||||||
scm_gc_mark (p->program);
|
scm_gc_mark (p->program);
|
||||||
scm_gc_mark (p->variables);
|
scm_gc_mark (p->variables);
|
||||||
return p->dynamic_link;
|
scm_gc_mark (p->dynamic_link);
|
||||||
|
return p->external_link;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scheme interface */
|
/* Scheme interface */
|
||||||
|
@ -146,6 +148,23 @@ SCM_DEFINE (scm_frame_dynamic_link, "frame-dynamic-link", 1, 0, 0,
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
SCM_DEFINE (scm_frame_external_link, "frame-external-link", 1, 0, 0,
|
||||||
|
(SCM frame),
|
||||||
|
"")
|
||||||
|
#define FUNC_NAME s_scm_frame_external_link
|
||||||
|
{
|
||||||
|
struct scm_vm_heap_frame *p;
|
||||||
|
|
||||||
|
SCM_VALIDATE_VM_HEAP_FRAME (1, frame);
|
||||||
|
p = SCM_VM_HEAP_FRAME_DATA (frame);
|
||||||
|
|
||||||
|
if (SCM_UNBNDP (p->external_link))
|
||||||
|
p->external_link = SCM_VM_FRAME_EXTERNAL_LINK (p->fp);
|
||||||
|
|
||||||
|
return p->external_link;
|
||||||
|
}
|
||||||
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VM Continuation
|
* VM Continuation
|
||||||
|
@ -213,7 +232,7 @@ vm_cont_free (SCM obj)
|
||||||
* VM Internal functions
|
* VM Internal functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SCM_SYMBOL (sym_vm_engine, "vm-engine");
|
SCM_SYMBOL (sym_vm_run, "vm-run");
|
||||||
SCM_SYMBOL (sym_vm_error, "vm-error");
|
SCM_SYMBOL (sym_vm_error, "vm-error");
|
||||||
|
|
||||||
static scm_byte_t *
|
static scm_byte_t *
|
||||||
|
@ -307,7 +326,7 @@ vm_mark (SCM obj)
|
||||||
for (; sp >= upper; sp--)
|
for (; sp >= upper; sp--)
|
||||||
if (SCM_NIMP (*sp))
|
if (SCM_NIMP (*sp))
|
||||||
scm_gc_mark (*sp);
|
scm_gc_mark (*sp);
|
||||||
fp = SCM_VM_STACK_ADDRESS (*sp); /* dynamic link */
|
fp = SCM_VM_STACK_ADDRESS (sp[-1]); /* dynamic link */
|
||||||
/* Mark frame variables + program */
|
/* Mark frame variables + program */
|
||||||
for (sp -= 2; sp >= lower; sp--)
|
for (sp -= 2; sp >= lower; sp--)
|
||||||
if (SCM_NIMP (*sp))
|
if (SCM_NIMP (*sp))
|
||||||
|
@ -337,7 +356,7 @@ scm_vm_apply (SCM vm, SCM program, SCM args)
|
||||||
#define FUNC_NAME "scm_vm_apply"
|
#define FUNC_NAME "scm_vm_apply"
|
||||||
{
|
{
|
||||||
SCM_VALIDATE_PROGRAM (1, program);
|
SCM_VALIDATE_PROGRAM (1, program);
|
||||||
return vm_engine (vm, program, args);
|
return vm_run (vm, program, args);
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
|
14
src/vm.h
14
src/vm.h
|
@ -61,10 +61,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
| | <- fp + bp->nargs + bp->nlocs + 2
|
| | <- fp + bp->nargs + bp->nlocs + 3
|
||||||
+------------------+ = SCM_VM_FRAME_UPPER_ADDRESS (fp)
|
+------------------+ = SCM_VM_FRAME_UPPER_ADDRESS (fp)
|
||||||
|
| Return address |
|
||||||
| Dynamic link |
|
| Dynamic link |
|
||||||
| Return address | <- fp + bp->nargs + bp->nlocs
|
| External link | <- fp + bp->nargs + bp->nlocs
|
||||||
| Local varialbe 1 | = SCM_VM_FRAME_DATA_ADDRESS (fp)
|
| Local varialbe 1 | = SCM_VM_FRAME_DATA_ADDRESS (fp)
|
||||||
| Local variable 0 | <- fp + bp->nargs
|
| Local variable 0 | <- fp + bp->nargs
|
||||||
| Argument 1 |
|
| Argument 1 |
|
||||||
|
@ -74,15 +75,16 @@
|
||||||
| |
|
| |
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SCM_VM_FRAME_LOWER_ADDRESS(fp) (fp - 1)
|
|
||||||
#define SCM_VM_FRAME_DATA_ADDRESS(fp) \
|
#define SCM_VM_FRAME_DATA_ADDRESS(fp) \
|
||||||
(fp + SCM_PROGRAM_NARGS (SCM_VM_FRAME_PROGRAM (fp)) \
|
(fp + SCM_PROGRAM_NARGS (SCM_VM_FRAME_PROGRAM (fp)) \
|
||||||
+ SCM_PROGRAM_NLOCS (SCM_VM_FRAME_PROGRAM (fp)))
|
+ SCM_PROGRAM_NLOCS (SCM_VM_FRAME_PROGRAM (fp)))
|
||||||
#define SCM_VM_FRAME_UPPER_ADDRESS(fp) \
|
#define SCM_VM_FRAME_UPPER_ADDRESS(fp) \
|
||||||
(SCM_VM_FRAME_DATA_ADDRESS (fp) + 2)
|
(SCM_VM_FRAME_DATA_ADDRESS (fp) + 3)
|
||||||
|
#define SCM_VM_FRAME_LOWER_ADDRESS(fp) (fp - 1)
|
||||||
|
|
||||||
|
#define SCM_VM_FRAME_RETURN_ADDRESS(fp) SCM_VM_FRAME_DATA_ADDRESS (fp)[2]
|
||||||
#define SCM_VM_FRAME_DYNAMIC_LINK(fp) SCM_VM_FRAME_DATA_ADDRESS (fp)[1]
|
#define SCM_VM_FRAME_DYNAMIC_LINK(fp) SCM_VM_FRAME_DATA_ADDRESS (fp)[1]
|
||||||
#define SCM_VM_FRAME_RETURN_ADDRESS(fp) SCM_VM_FRAME_DATA_ADDRESS (fp)[0]
|
#define SCM_VM_FRAME_EXTERNAL_LINK(fp) SCM_VM_FRAME_DATA_ADDRESS (fp)[0]
|
||||||
#define SCM_VM_FRAME_VARIABLE(fp,i) fp[i]
|
#define SCM_VM_FRAME_VARIABLE(fp,i) fp[i]
|
||||||
#define SCM_VM_FRAME_PROGRAM(fp) fp[-1]
|
#define SCM_VM_FRAME_PROGRAM(fp) fp[-1]
|
||||||
|
|
||||||
|
@ -95,6 +97,7 @@ struct scm_vm_heap_frame {
|
||||||
SCM program;
|
SCM program;
|
||||||
SCM variables;
|
SCM variables;
|
||||||
SCM dynamic_link;
|
SCM dynamic_link;
|
||||||
|
SCM external_link;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern scm_bits_t scm_tc16_vm_heap_frame;
|
extern scm_bits_t scm_tc16_vm_heap_frame;
|
||||||
|
@ -106,6 +109,7 @@ extern scm_bits_t scm_tc16_vm_heap_frame;
|
||||||
#define SCM_VM_HEAP_FRAME_PROGRAM(f) SCM_VM_HEAP_FRAME_DATA (f)->program
|
#define SCM_VM_HEAP_FRAME_PROGRAM(f) SCM_VM_HEAP_FRAME_DATA (f)->program
|
||||||
#define SCM_VM_HEAP_FRAME_VARIABLES(f) SCM_VM_HEAP_FRAME_DATA (f)->variables
|
#define SCM_VM_HEAP_FRAME_VARIABLES(f) SCM_VM_HEAP_FRAME_DATA (f)->variables
|
||||||
#define SCM_VM_HEAP_FRAME_DYNAMIC_LINK(f) SCM_VM_HEAP_FRAME_DATA (f)->dynamic_link
|
#define SCM_VM_HEAP_FRAME_DYNAMIC_LINK(f) SCM_VM_HEAP_FRAME_DATA (f)->dynamic_link
|
||||||
|
#define SCM_VM_HEAP_FRAME_EXTERNAL_LINK(f) SCM_VM_HEAP_FRAME_DATA (f)->external_link
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VM
|
* VM
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
#include "vm_engine.h"
|
#include "vm_engine.h"
|
||||||
|
|
||||||
static SCM
|
static SCM
|
||||||
vm_engine (SCM vm, SCM program, SCM args)
|
vm_run (SCM vm, SCM program, SCM args)
|
||||||
#define FUNC_NAME "vm-engine"
|
#define FUNC_NAME "vm-engine"
|
||||||
{
|
{
|
||||||
/* VM registers */
|
/* VM registers */
|
||||||
|
@ -55,7 +55,7 @@ vm_engine (SCM vm, SCM program, SCM args)
|
||||||
/* Cache variables */
|
/* Cache variables */
|
||||||
struct scm_vm *vp = SCM_VM_DATA (vm); /* VM data pointer */
|
struct scm_vm *vp = SCM_VM_DATA (vm); /* VM data pointer */
|
||||||
struct scm_program *bp = NULL; /* program base pointer */
|
struct scm_program *bp = NULL; /* program base pointer */
|
||||||
SCM external; /* external environment */
|
SCM external = SCM_EOL; /* external environment */
|
||||||
SCM *objects = NULL; /* constant objects */
|
SCM *objects = NULL; /* constant objects */
|
||||||
SCM *stack_base = vp->stack_base; /* stack base address */
|
SCM *stack_base = vp->stack_base; /* stack base address */
|
||||||
SCM *stack_limit = vp->stack_limit; /* stack limit address */
|
SCM *stack_limit = vp->stack_limit; /* stack limit address */
|
||||||
|
@ -161,7 +161,7 @@ vm_engine (SCM vm, SCM program, SCM args)
|
||||||
vm_error:
|
vm_error:
|
||||||
SYNC_ALL ();
|
SYNC_ALL ();
|
||||||
scm_ithrow (sym_vm_error,
|
scm_ithrow (sym_vm_error,
|
||||||
SCM_LIST4 (sym_vm_engine, err_msg, err_args,
|
SCM_LIST4 (sym_vm_run, err_msg, err_args,
|
||||||
scm_vm_current_frame (vm)),
|
scm_vm_current_frame (vm)),
|
||||||
1);
|
1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,16 @@
|
||||||
{ \
|
{ \
|
||||||
bp = SCM_PROGRAM_DATA (program); \
|
bp = SCM_PROGRAM_DATA (program); \
|
||||||
objects = SCM_VELTS (bp->objs); \
|
objects = SCM_VELTS (bp->objs); \
|
||||||
external = bp->external; \
|
}
|
||||||
|
|
||||||
|
#define CACHE_EXTERNAL() \
|
||||||
|
{ \
|
||||||
|
external = fp[bp->nargs + bp->nlocs]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SYNC_EXTERNAL() \
|
||||||
|
{ \
|
||||||
|
fp[bp->nargs + bp->nlocs] = external; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SYNC_BEFORE_GC() \
|
#define SYNC_BEFORE_GC() \
|
||||||
|
@ -280,17 +289,18 @@ do { \
|
||||||
SCM dl = SCM_VM_MAKE_STACK_ADDRESS (fp); \
|
SCM dl = SCM_VM_MAKE_STACK_ADDRESS (fp); \
|
||||||
ip = bp->base; \
|
ip = bp->base; \
|
||||||
fp = sp - bp->nargs + 1; \
|
fp = sp - bp->nargs + 1; \
|
||||||
sp = sp + bp->nlocs + 2; \
|
sp = sp + bp->nlocs + 3; \
|
||||||
CHECK_OVERFLOW (); \
|
CHECK_OVERFLOW (); \
|
||||||
sp[0] = dl; \
|
sp[0] = ra; \
|
||||||
sp[-1] = ra; \
|
sp[-1] = dl; \
|
||||||
|
sp[-2] = bp->external; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FREE_FRAME() \
|
#define FREE_FRAME() \
|
||||||
{ \
|
{ \
|
||||||
SCM *new_sp = fp - 2; \
|
SCM *new_sp = fp - 2; \
|
||||||
sp = fp + bp->nargs + bp->nlocs; \
|
sp = fp + bp->nargs + bp->nlocs; \
|
||||||
ip = SCM_VM_BYTE_ADDRESS (sp[0]); \
|
ip = SCM_VM_BYTE_ADDRESS (sp[2]); \
|
||||||
fp = SCM_VM_STACK_ADDRESS (sp[1]); \
|
fp = SCM_VM_STACK_ADDRESS (sp[1]); \
|
||||||
sp = new_sp; \
|
sp = new_sp; \
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,15 +159,12 @@ VM_DEFINE_LOADER (load_program, "load-program")
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
VM_DEFINE_INSTRUCTION (link, "link", 0, 2, 1)
|
VM_DEFINE_INSTRUCTION (link, "link", 0, 1, 1)
|
||||||
{
|
{
|
||||||
if (!SCM_FALSEP (sp[-1]))
|
#if 0
|
||||||
{
|
|
||||||
sp[-1] = scm_c_env_vcell (sp[-1], sp[0], 1);
|
sp[-1] = scm_c_env_vcell (sp[-1], sp[0], 1);
|
||||||
sp--;
|
sp--;
|
||||||
}
|
#endif
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Temporary hack that supports the current module system */
|
/* Temporary hack that supports the current module system */
|
||||||
SCM mod = scm_current_module ();
|
SCM mod = scm_current_module ();
|
||||||
SCM var = scm_eval_closure_lookup (scm_standard_eval_closure (mod),
|
SCM var = scm_eval_closure_lookup (scm_standard_eval_closure (mod),
|
||||||
|
@ -176,8 +173,7 @@ VM_DEFINE_INSTRUCTION (link, "link", 0, 2, 1)
|
||||||
/* Create a new variable if not defined yet */
|
/* Create a new variable if not defined yet */
|
||||||
var = scm_eval_closure_lookup (scm_standard_eval_closure (mod),
|
var = scm_eval_closure_lookup (scm_standard_eval_closure (mod),
|
||||||
*sp, SCM_BOOL_T);
|
*sp, SCM_BOOL_T);
|
||||||
*--sp = SCM_VARVCELL (var);
|
*sp = SCM_VARVCELL (var);
|
||||||
}
|
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -223,49 +223,53 @@ VM_DEFINE_INSTRUCTION (variable_set, "variable-set", 0, 1, 0)
|
||||||
|
|
||||||
#define BR(p) \
|
#define BR(p) \
|
||||||
{ \
|
{ \
|
||||||
signed char offset = FETCH (); \
|
int h = FETCH (); \
|
||||||
|
int l = FETCH (); \
|
||||||
|
signed short offset = (h << 8) + l; \
|
||||||
if (p) \
|
if (p) \
|
||||||
ip += offset; \
|
ip += offset; \
|
||||||
DROP (); \
|
DROP (); \
|
||||||
NEXT; \
|
NEXT; \
|
||||||
}
|
}
|
||||||
|
|
||||||
VM_DEFINE_INSTRUCTION (br_if, "br-if", 1, 0, 0)
|
VM_DEFINE_INSTRUCTION (br, "br", 2, 0, 0)
|
||||||
|
{
|
||||||
|
int h = FETCH ();
|
||||||
|
int l = FETCH ();
|
||||||
|
ip += (signed short) (h << 8) + l;
|
||||||
|
NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
VM_DEFINE_INSTRUCTION (br_if, "br-if", 2, 0, 0)
|
||||||
{
|
{
|
||||||
BR (!SCM_FALSEP (*sp));
|
BR (!SCM_FALSEP (*sp));
|
||||||
}
|
}
|
||||||
|
|
||||||
VM_DEFINE_INSTRUCTION (br_if_not, "br-if-not", 1, 0, 0)
|
VM_DEFINE_INSTRUCTION (br_if_not, "br-if-not", 2, 0, 0)
|
||||||
{
|
{
|
||||||
BR (SCM_FALSEP (*sp));
|
BR (SCM_FALSEP (*sp));
|
||||||
}
|
}
|
||||||
|
|
||||||
VM_DEFINE_INSTRUCTION (br_if_eq, "br-if-eq", 1, 0, 0)
|
VM_DEFINE_INSTRUCTION (br_if_eq, "br-if-eq", 2, 0, 0)
|
||||||
{
|
{
|
||||||
BR (SCM_EQ_P (sp[0], sp--[1]));
|
BR (SCM_EQ_P (sp[0], sp--[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
VM_DEFINE_INSTRUCTION (br_if_not_eq, "br-if-not-eq", 1, 0, 0)
|
VM_DEFINE_INSTRUCTION (br_if_not_eq, "br-if-not-eq", 2, 0, 0)
|
||||||
{
|
{
|
||||||
BR (!SCM_EQ_P (sp[0], sp--[1]));
|
BR (!SCM_EQ_P (sp[0], sp--[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
VM_DEFINE_INSTRUCTION (br_if_null, "br-if-null", 1, 0, 0)
|
VM_DEFINE_INSTRUCTION (br_if_null, "br-if-null", 2, 0, 0)
|
||||||
{
|
{
|
||||||
BR (SCM_NULLP (*sp));
|
BR (SCM_NULLP (*sp));
|
||||||
}
|
}
|
||||||
|
|
||||||
VM_DEFINE_INSTRUCTION (br_if_not_null, "br-if-not-null", 1, 0, 0)
|
VM_DEFINE_INSTRUCTION (br_if_not_null, "br-if-not-null", 2, 0, 0)
|
||||||
{
|
{
|
||||||
BR (!SCM_NULLP (*sp));
|
BR (!SCM_NULLP (*sp));
|
||||||
}
|
}
|
||||||
|
|
||||||
VM_DEFINE_INSTRUCTION (jump, "jump", 1, 0, 0)
|
|
||||||
{
|
|
||||||
ip += (signed char) FETCH ();
|
|
||||||
NEXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Subprogram call
|
* Subprogram call
|
||||||
|
@ -305,8 +309,10 @@ VM_DEFINE_INSTRUCTION (call, "call", 1, -1, 1)
|
||||||
LOCAL_SET (i, SCM_UNDEFINED);
|
LOCAL_SET (i, SCM_UNDEFINED);
|
||||||
|
|
||||||
/* Create external variables */
|
/* Create external variables */
|
||||||
|
CACHE_EXTERNAL ();
|
||||||
for (i = 0; i < bp->nexts; i++)
|
for (i = 0; i < bp->nexts; i++)
|
||||||
CONS (external, SCM_UNDEFINED, external);
|
CONS (external, SCM_UNDEFINED, external);
|
||||||
|
SYNC_EXTERNAL ();
|
||||||
|
|
||||||
ENTER_HOOK ();
|
ENTER_HOOK ();
|
||||||
APPLY_HOOK ();
|
APPLY_HOOK ();
|
||||||
|
@ -454,6 +460,7 @@ VM_DEFINE_INSTRUCTION (return, "return", 0, 0, 1)
|
||||||
/* Restore the last program */
|
/* Restore the last program */
|
||||||
program = SCM_VM_FRAME_PROGRAM (fp);
|
program = SCM_VM_FRAME_PROGRAM (fp);
|
||||||
CACHE_PROGRAM ();
|
CACHE_PROGRAM ();
|
||||||
|
CACHE_EXTERNAL ();
|
||||||
PUSH (ret);
|
PUSH (ret);
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue