svn: r12845
This commit is contained in:
Stevie Strickland 2008-12-14 20:04:29 +00:00
commit ac9a437c10
39 changed files with 2029 additions and 1617 deletions

View File

@ -57,7 +57,8 @@
(values (append
(map (lambda (tl)
(match tl
[(? symbol?) '#%linkage]
[#f '#%linkage]
[(? symbol?) (string->symbol (format "_~a" tl))]
[(struct global-bucket (name))
(string->symbol (format "_~a" name))]
[(struct module-variable (modidx sym pos phase))

View File

@ -85,15 +85,10 @@
(define (read-variable v)
(if (symbol? v)
(make-global-bucket v)
(let-values ([(phase modname varname)
(match v
[(list* phase modname varname)
(values phase modname varname)]
[(list* modname varname)
(values 0 modname varname)])])
(if (and (zero? phase) (eq? modname '#%kernel))
(error 'bucket "var ~a" varname)
(make-module-variable modname varname -1 phase)))))
(error "expected a symbol")))
(define (do-not-read-variable v)
(error "should not get here"))
(define (read-compilation-top v)
(match v
@ -198,6 +193,7 @@
,rename ,max-let-depth ,dummy
,prefix ,kernel-exclusion ,reprovide-kernel?
,indirect-provides ,num-indirect-provides
,indirect-syntax-provides ,num-indirect-syntax-provides
,indirect-et-provides ,num-indirect-et-provides
,protects ,et-protects
,provide-phase-count . ,rest)
@ -282,7 +278,7 @@
(cons 'with-cont-mark-type read-with-cont-mark)
(cons 'quote-syntax-type read-topsyntax)
(cons 'variable-type read-variable)
(cons 'module-variable-type read-variable)
(cons 'module-variable-type do-not-read-variable)
(cons 'compilation-top-type read-compilation-top)
(cons 'case-lambda-sequence-type read-case-lambda)
(cons 'begin0-sequence-type read-sequence)
@ -719,7 +715,11 @@
(let ([mod (read-compact cp)]
[var (read-compact cp)]
[pos (read-compact-number cp)])
(make-module-variable mod var pos 0))]
(let-values ([(mod-phase pos)
(if (= pos -2)
(values 1 (read-compact-number cp))
(values 0 pos))])
(make-module-variable mod var pos mod-phase)))]
[(local-unbox)
(let* ([p* (read-compact-number cp)]
[p (if (< p* 0)

View File

@ -198,7 +198,8 @@ Removes @scheme[card] from the table.}
@defmethod[(move-cards [cards (listof (is-a?/c card<%>))]
[x real?]
[y real?]
[offset-proc (exact-nonnegative-integer? . -> . (values real? real?))
[offset-proc (exact-nonnegative-integer?
. -> . (values real? real?))
(lambda (i) (values 0 0))])
void?]{

View File

@ -653,7 +653,7 @@
(and (procedure? proc) (procedure-arity-includes? proc arity)))
(define (get-namespace evaluator)
(call-in-sandbox-context evaluator (lambda () (current-namespace))))
(call-in-sandbox-context evaluator current-namespace))
;; checks that ids are defined, either as variables or syntaxes
(provide !defined)

View File

@ -8,6 +8,7 @@
(sandbox-error-output #f)
;; no limits -- the handin server uses per-session limits
(sandbox-memory-limit #f)
(sandbox-eval-limits #f)
;; share these with evaluators

View File

@ -2,12 +2,14 @@
#lang scheme/base
(require scheme/match
scheme/list
syntax/stx
"deriv-c.ss"
"deriv-util.ss")
(provide find-derivs
find-deriv
find-derivs/syntax
extract-all-fresh-names
compute-shift-table
flatten-identifiers)
;; Utilities for finding subderivations
@ -126,8 +128,12 @@
(lambda _ #f)
d))
;; extract-all-fresh-names : Derivation -> syntaxlike
;; extract-all-fresh-names : Derivation -> (listof identifier)
(define (extract-all-fresh-names d)
(define ht (make-hasheq))
(define (add stxish)
(for-each (lambda (id) (hash-set! ht id #t))
(flatten-identifiers stxish)))
(define (renaming-node? x)
(or (p:lambda? x)
;;(p:case-lambda? x)
@ -142,69 +148,83 @@
(define (extract-fresh-names d)
(match d
[(Wrap p:lambda (e1 e2 rs ?1 renames body))
(if renames
(with-syntax ([(?formals . ?body) renames])
#'?formals)
null)]
(when renames
(with-syntax ([(?formals . ?body) renames])
(add #'?formals)))]
[(Wrap clc (_ renames _))
(if renames
(with-syntax ([(?formals . ?body) renames])
#'?formals)
null)]
(when renames
(with-syntax ([(?formals . ?body) renames])
(add #'?formals)))]
[(Wrap p:let-values (e1 e2 rs ?1 renames rhss body))
(if renames
(with-syntax ([(((?vars ?rhs) ...) . ?body) renames])
#'(?vars ...))
null)]
(when renames
(with-syntax ([(((?vars ?rhs) ...) . ?body) renames])
(add #'(?vars ...))))]
[(Wrap p:letrec-values (e1 e2 rs ?1 renames rhss body))
(if renames
(with-syntax ([(((?vars ?rhs) ...) . ?body) renames])
#'(?vars ...))
null)]
[(Wrap p:letrec-syntaxes+values (e1 e2 rs ?1 srenames srhss vrenames vrhss body _))
(cons
(if srenames
(with-syntax ([(((?svars ?srhs) ...) ((?vvars ?vrhs) ...) . ?body)
srenames])
#'(?svars ... ?vvars ...))
null)
(if vrenames
(with-syntax ([(((?vvars ?vrhs) ...) . ?body) vrenames])
#'(?vvars ...))
null))]
(when renames
(with-syntax ([(((?vars ?rhs) ...) . ?body) renames])
(add #'(?vars ...))))]
[(Wrap p:letrec-syntaxes+values (e1 e2 rs ?1 srenames srhss vrenames _ _ _))
(when srenames
(with-syntax ([(((?svars ?srhs) ...) ((?vvars ?vrhs) ...) . ?body)
srenames])
(add #'(?svars ... ?vvars ...))))
(when vrenames
(with-syntax ([(((?vvars ?vrhs) ...) . ?body) vrenames])
(add #'(?vvars ...))))]
[(Wrap b:defvals (rename head ?1 rename2 ?2))
(let ([head-e2 (wderiv-e2 head)])
(if head-e2
(with-syntax ([(?dv ?vars ?rhs) head-e2])
#'?vars)
null))]
(when head-e2
(with-syntax ([(?dv ?vars ?rhs) head-e2])
(add #'?vars))))]
[(Wrap b:defstx (rename head ?1 rename2 ?2 rhs))
(let ([head-e2 (wderiv-e2 head)])
(if head-e2
(with-syntax ([(?ds ?svars ?rhs) head-e2])
#'?svars)
null))]
(when head-e2
(with-syntax ([(?ds ?svars ?rhs) head-e2])
(add #'?svars))))]
[(Wrap p:define-values (e1 e2 rs ?1 rhs))
(if rhs
(with-syntax ([(?dv ?vars ?rhs) e1])
#'?vars)
null)]
(when rhs
(with-syntax ([(?dv ?vars ?rhs) e1])
(add #'?vars)))]
[(Wrap p:define-syntaxes (e1 e2 rs ?1 rhs _))
(if rhs
(with-syntax ([(?ds ?svars ?srhs) e1])
#'?svars)
null)]
[_ null]))
(when rhs
(with-syntax ([(?ds ?svars ?srhs) e1])
(add #'?svars)))]
[_ (void)]))
(define renaming-forms
(find-deriv/unit+join+zero renaming-node?
(lambda (d) #f)
d
list
append
null))
(for ([rf renaming-forms])
(extract-fresh-names rf))
(hash-map ht (lambda (k v) k)))
(let ([all-renaming-forms
(find-deriv/unit+join+zero
renaming-node?
(lambda (d) #f)
d
list
append
null)])
(flatten-identifiers (map extract-fresh-names all-renaming-forms))))
;; compute-shift-table : deriv -> hash[id => (listof id)]
(define (compute-shift-table d)
(define ht (make-hasheq))
(define module-forms
(find-derivs p:module? (lambda _ #f) d))
(define module-shift-renamers
(for/list ([mf module-forms])
(let ([shift (p:module-shift mf)]
[body (p:module-body mf)])
(and shift body
(with-syntax ([(_module _name _lang shifted-body) shift])
(add-rename-mapping ht (wderiv-e2 body) #'shifted-body))))))
ht)
(define (add-rename-mapping ht from to)
(define (loop from to)
(cond [(and (stx-pair? from) (stx-pair? to))
(loop (stx-car from) (stx-car to))
(loop (stx-cdr from) (stx-cdr to))]
[(and (identifier? from) (identifier? to))
(hash-set! ht from (cons to (hash-ref ht from null)))]
[else (void)]))
(loop from to)
(void))
;; flatten-identifiers : syntaxlike -> (list-of identifier)
(define (flatten-identifiers stx)

View File

@ -75,22 +75,32 @@
;; get-range : -> range<%>
(define/public (get-range) range)
;; highlight-syntaxes : (list-of syntax) string -> void
(define/public (highlight-syntaxes stxs hi-color)
(let ([style-delta (highlight-style-delta hi-color #f)])
(for-each (lambda (stx) (hash-set! extra-styles stx style-delta))
stxs))
(for ([stx stxs])
(add-extra-styles stx (list style-delta))))
(refresh))
;; underline-syntaxes : (listof syntax) -> void
(define/public (underline-syntaxes stxs)
(for ([stx stxs])
(add-extra-styles stx (list underline-style-delta)))
(refresh))
(define/public (add-extra-styles stx styles)
(hash-set! extra-styles stx
(append (hash-ref extra-styles stx null)
styles)))
;; apply-extra-styles : -> void
;; Applies externally-added styles (such as highlighting)
(define/private (apply-extra-styles)
(hash-for-each
extra-styles
(lambda (hi-stx style-delta)
(let ([rs (send range get-ranges hi-stx)])
(for-each (lambda (r) (restyle-range r style-delta)) rs)))))
(for ([(stx style-deltas) extra-styles])
(for ([r (send range get-ranges stx)])
(for ([style-delta style-deltas])
(restyle-range r style-delta)))))
;; apply-secondary-partition-styles : selected-syntax -> void
;; If the selected syntax is an identifier, then styles all identifiers
@ -243,6 +253,11 @@
(send sd set-weight-off 'bold))
sd))
(define underline-style-delta
(let ([sd (new style-delta%)])
(send sd set-underlined-on #t)
sd))
(define selection-color "yellow")
(define subselection-color "yellow")

View File

@ -5,7 +5,8 @@
"interfaces.ss"
"../util/notify.ss"
"../util/misc.ss")
(provide syntax-prefs-base%
(provide prefs-base%
syntax-prefs-base%
syntax-prefs%
syntax-prefs/readonly%)
@ -19,7 +20,7 @@
(pref:get/set pref:props-percentage SyntaxBrowser:PropertiesPanelPercentage)
(pref:get/set pref:props-shown? SyntaxBrowser:PropertiesPanelShown)
(define syntax-prefs-base%
(define prefs-base%
(class object%
;; columns : number
(field/notify columns (new notify-box% (value 60)))
@ -41,6 +42,10 @@
"indigo" "purple"
"orange" "salmon" "darkgoldenrod" "olive"))))
(super-new)))
(define syntax-prefs-base%
(class prefs-base%
;; width, height : number
(notify-methods width)
(notify-methods height)

View File

@ -1,363 +1,359 @@
(module syntax-snip mzscheme
(require mzlib/class
mred
framework
mzlib/match
mzlib/list
mzlib/string
"../util/notify.ss"
"interfaces.ss"
"display.ss"
"controller.ss"
"keymap.ss"
"properties.ss"
"partition.ss"
"prefs.ss")
#lang scheme/base
(require scheme/class
scheme/match
scheme/list
mzlib/string
mred
framework
"../util/notify.ss"
"interfaces.ss"
"display.ss"
"controller.ss"
"keymap.ss"
"properties.ss"
"partition.ss"
"prefs.ss")
(provide syntax-snip%
syntax-value-snip%)
(provide syntax-snip%
syntax-value-snip%)
(define syntax-snip-config-base%
(class object%
(notify-methods props-shown?)
(super-new)))
(define syntax-snip-config%
(class syntax-snip-config-base%
(define/override (init-props-shown?) (new notify-box% (value #f)))
(super-new)))
(define syntax-snip-config-base%
(class prefs-base%
(notify-methods props-shown?)
(super-new)))
(define dumb-host%
(class object%
(define controller (new controller%))
(define config (new syntax-snip-config%))
(super-new)
(define/public (get-controller) controller)
(define/public (get-config) config)
(define/public (add-keymap text snip)
(send text set-keymap
(new syntax-keymap%
(controller controller)
(editor text)
(config config))))))
(define syntax-snip-config%
(class syntax-snip-config-base%
(define/override (init-props-shown?) (new notify-box% (value #f)))
(super-new)))
;; syntax-value-snip%
(define syntax-value-snip%
(class* editor-snip% (readable-snip<%>)
(init-field ((stx syntax)))
(init-field (host (new dumb-host%)))
(inherit set-margin
set-inset)
;; syntax-value-snip%
(define syntax-value-snip%
(class* editor-snip% (readable-snip<%>)
(init-field ((stx syntax)))
(init-field (controller (new controller%)))
(init-field (config (new syntax-snip-config%)))
(define text (new text:standard-style-list%))
(super-new (editor text) (with-border? #f))
(inherit set-margin
set-inset)
(set-margin 0 0 0 0)
;;(set-inset 2 2 2 2)
;;(set-margin 2 2 2 2)
(set-inset 0 0 0 0)
(define text (new text:standard-style-list%))
(super-new (editor text) (with-border? #f))
(send text begin-edit-sequence)
(send text change-style (make-object style-delta% 'change-alignment 'top))
(define display
(print-syntax-to-editor stx text
(send host get-controller)
(send host get-config)))
(send text lock #t)
(send text end-edit-sequence)
(send text hide-caret #t)
(set-margin 0 0 0 0)
;;(set-inset 2 2 2 2)
;;(set-margin 2 2 2 2)
(set-inset 0 0 0 0)
(send host add-keymap text this)
(send text begin-edit-sequence)
(send text change-style (make-object style-delta% 'change-alignment 'top))
(define display
(print-syntax-to-editor stx text controller config))
(send text lock #t)
(send text end-edit-sequence)
(send text hide-caret #t)
;; snip% Methods
(define/override (copy)
(new syntax-value-snip% (host host) (syntax stx)))
(setup-keymap text)
;; read-special : any number/#f number/#f number/#f -> syntax
;; Produces 3D syntax to preserve eq-ness of syntax
;; #'#'stx would be lose identity when wrapped
(define/public (read-special src line col pos)
(with-syntax ([p (lambda () stx)])
#'(p)))
))
(define/public (setup-keymap text)
(new syntax-keymap%
(controller controller)
(config config)
(editor text)))
(define top-aligned
(make-object style-delta% 'change-alignment 'top))
;; snip% Methods
(define/override (copy)
(new syntax-value-snip%
(config config)
(controller controller)
(syntax stx)))
(define-struct styled (contents style clickback))
;; read-special : any number/#f number/#f number/#f -> syntax
;; Produces 3D syntax to preserve eq-ness of syntax
;; #'#'stx would be lose identity when wrapped
(define/public (read-special src line col pos)
(with-syntax ([p (lambda () stx)])
#'(p)))
))
;; clicky-snip%
(define clicky-snip%
(class* editor-snip% ()
(define top-aligned
(make-object style-delta% 'change-alignment 'top))
(init-field [open-style '(border)]
[closed-style '(tight-text-fit)])
(define-struct styled (contents style clickback))
(inherit set-margin
set-inset
set-snipclass
set-tight-text-fit
show-border
get-admin)
;; clicky-snip%
(define clicky-snip%
(class* editor-snip% ()
(define -outer (new text%))
(super-new (editor -outer) (with-border? #f))
(set-margin 2 2 2 2)
(set-inset 2 2 2 2)
;;(set-margin 3 0 0 0)
;;(set-inset 1 0 0 0)
;;(set-margin 0 0 0 0)
;;(set-inset 0 0 0 0)
(init-field [open-style '(border)]
[closed-style '(tight-text-fit)])
(define/public (closed-contents) null)
(define/public (open-contents) null)
(inherit set-margin
set-inset
set-snipclass
set-tight-text-fit
show-border
get-admin)
(define open? #f)
(define -outer (new text%))
(super-new (editor -outer) (with-border? #f))
(set-margin 2 2 2 2)
(set-inset 2 2 2 2)
;;(set-margin 3 0 0 0)
;;(set-inset 1 0 0 0)
;;(set-margin 0 0 0 0)
;;(set-inset 0 0 0 0)
(define/public (refresh-contents)
(send* -outer
(begin-edit-sequence)
(lock #f)
(erase))
(do-style (if open? open-style closed-style))
(outer:insert (if open? (hide-icon) (show-icon))
style:hyper
(if open?
(lambda _
(set! open? #f)
(refresh-contents))
(lambda _
(set! open? #t)
(refresh-contents))))
(for-each (lambda (s) (outer:insert s))
(if open? (open-contents) (closed-contents)))
(send* -outer
(change-style top-aligned 0 (send -outer last-position))
(lock #t)
(end-edit-sequence)))
(define/public (closed-contents) null)
(define/public (open-contents) null)
(define/private (do-style style)
(show-border (memq 'border style))
(set-tight-text-fit (memq 'tight-text-fit style)))
(define open? #f)
(define/private outer:insert
(case-lambda
[(obj)
(if (styled? obj)
(outer:insert (styled-contents obj)
(styled-style obj)
(styled-clickback obj))
(outer:insert obj style:normal))]
[(text style)
(outer:insert text style #f)]
[(text style clickback)
(let ([start (send -outer last-position)])
(send -outer insert text)
(let ([end (send -outer last-position)])
(send -outer change-style style start end #f)
(when clickback
(send -outer set-clickback start end clickback))))]))
(define/public (refresh-contents)
(send* -outer
(begin-edit-sequence)
(lock #f)
(erase))
(do-style (if open? open-style closed-style))
(outer:insert (if open? (hide-icon) (show-icon))
style:hyper
(if open?
(lambda _
(set! open? #f)
(refresh-contents))
(lambda _
(set! open? #t)
(refresh-contents))))
(for-each (lambda (s) (outer:insert s))
(if open? (open-contents) (closed-contents)))
(send* -outer
(change-style top-aligned 0 (send -outer last-position))
(lock #t)
(end-edit-sequence)))
(send -outer hide-caret #t)
(send -outer lock #t)
(refresh-contents)
))
(define/private (do-style style)
(show-border (memq 'border style))
(set-tight-text-fit (memq 'tight-text-fit style)))
;; syntax-snip%
(define syntax-snip%
(class* clicky-snip% (readable-snip<%>)
(init-field ((stx syntax)))
(init-field (host (new dumb-host%)))
(define config (send host get-config))
(inherit set-snipclass
refresh-contents)
(define/private outer:insert
(case-lambda
[(obj)
(if (styled? obj)
(outer:insert (styled-contents obj)
(styled-style obj)
(styled-clickback obj))
(outer:insert obj style:normal))]
[(text style)
(outer:insert text style #f)]
[(text style clickback)
(let ([start (send -outer last-position)])
(send -outer insert text)
(let ([end (send -outer last-position)])
(send -outer change-style style start end #f)
(when clickback
(send -outer set-clickback start end clickback))))]))
(define the-syntax-snip
(new syntax-value-snip%
(syntax stx)
(host host)))
(define the-summary
(let* ([t (new text%)]
[es (new editor-snip% (editor t) (with-border? #f))])
(send es set-margin 0 0 0 0)
(send es set-inset 0 0 0 0)
(send t insert (format "~s" stx))
es))
(send -outer hide-caret #t)
(send -outer lock #t)
(refresh-contents)
))
(define properties-snip
(new properties-container-snip%
(controller (send host get-controller))))
;; syntax-snip%
(define syntax-snip%
(class* clicky-snip% (readable-snip<%>)
(init-field ((stx syntax)))
(init-field [controller (new controller%)])
(init-field [config (new syntax-snip-config%)])
(define/override (closed-contents)
(list the-summary))
(inherit set-snipclass
refresh-contents)
(define/override (open-contents)
(list " "
the-syntax-snip
" "
properties-snip))
(define the-syntax-snip
(new syntax-value-snip%
(syntax stx)
(controller controller)
(config config)))
(define the-summary
(let* ([t (new text%)]
[es (new editor-snip% (editor t) (with-border? #f))])
(send es set-margin 0 0 0 0)
(send es set-inset 0 0 0 0)
(send t insert (format "~s" stx))
es))
;; Snip methods
(define/override (copy)
(new syntax-snip% (syntax stx)))
(define/override (write stream)
(send stream put
(string->bytes/utf-8
(format "~s" (marshall-syntax stx)))))
(define/public (read-special src line col pos)
(send the-syntax-snip read-special src line col pos))
(define properties-snip
(new properties-container-snip%
(controller controller)))
(send config listen-props-shown?
(lambda (?) (refresh-contents)))
(define/override (closed-contents)
(list the-summary))
(super-new)
(set-snipclass snip-class)))
(define/override (open-contents)
(list " "
the-syntax-snip
" "
properties-snip))
;; Snip methods
(define/override (copy)
(new syntax-snip% (syntax stx)))
(define/override (write stream)
(send stream put
(string->bytes/utf-8
(format "~s" (marshall-syntax stx)))))
(define/public (read-special src line col pos)
(send the-syntax-snip read-special src line col pos))
(define properties-container-snip%
(class clicky-snip%
(init controller)
(send config listen-props-shown?
(lambda (?) (refresh-contents)))
(define properties-snip
(new properties-snip% (controller controller)))
(super-new)
(set-snipclass snip-class)
))
(define/override (open-contents)
(list #;(show-properties-icon)
properties-snip))
(define properties-container-snip%
(class clicky-snip%
(init controller)
(define/override (closed-contents)
(list (show-properties-icon)))
(define properties-snip
(new properties-snip% (controller controller)))
(super-new (open-style '())
(closed-style '()))))
(define/override (open-contents)
(list #;(show-properties-icon)
properties-snip))
(define style:normal (make-object style-delta% 'change-normal))
(define style:hyper
(let ([s (make-object style-delta% 'change-normal)])
(send s set-delta 'change-toggle-underline)
(send s set-delta-foreground "blue")
s))
(define style:green
(let ([s (make-object style-delta% 'change-normal)])
(send s set-delta-foreground "darkgreen")
s))
(define style:bold
(let ([s (make-object style-delta% 'change-normal)])
(send s set-delta 'change-bold)
s))
(define/override (closed-contents)
(list (show-properties-icon)))
(define (show-icon)
(make-object image-snip%
(build-path (collection-path "icons") "turn-up.png")))
(define (hide-icon)
(make-object image-snip%
(build-path (collection-path "icons") "turn-down.png")))
(super-new (open-style '())
(closed-style '()))))
(define (show-properties-icon)
(make-object image-snip%
(build-path (collection-path "icons") "syncheck.png")))
(define style:normal (make-object style-delta% 'change-normal))
(define style:hyper
(let ([s (make-object style-delta% 'change-normal)])
(send s set-delta 'change-toggle-underline)
(send s set-delta-foreground "blue")
s))
(define style:green
(let ([s (make-object style-delta% 'change-normal)])
(send s set-delta-foreground "darkgreen")
s))
(define style:bold
(let ([s (make-object style-delta% 'change-normal)])
(send s set-delta 'change-bold)
s))
;; marshall-syntax : syntax -> printable
(define (marshall-syntax stx)
(unless (syntax? stx)
(error 'marshall-syntax "not syntax: ~s\n" stx))
`(syntax
(source ,(marshall-object (syntax-source stx)))
(source-module ,(marshall-object (syntax-source-module stx)))
(position ,(syntax-position stx))
(line ,(syntax-line stx))
(column ,(syntax-column stx))
(span ,(syntax-span stx))
(original? ,(syntax-original? stx))
(properties
,@(map (λ (x) `(,x ,(marshall-object (syntax-property stx x))))
(syntax-property-symbol-keys stx)))
(contents
,(marshall-object (syntax-e stx)))))
(define (show-icon)
(make-object image-snip%
(build-path (collection-path "icons") "turn-up.png")))
(define (hide-icon)
(make-object image-snip%
(build-path (collection-path "icons") "turn-down.png")))
;; marshall-object : any -> printable
;; really only intended for use with marshall-syntax
(define (marshall-object obj)
(cond
[(syntax? obj) (marshall-syntax obj)]
[(pair? obj)
`(pair ,(cons (marshall-object (car obj))
(marshall-object (cdr obj))))]
[(or (symbol? obj)
(char? obj)
(number? obj)
(string? obj)
(boolean? obj)
(null? obj))
`(other ,obj)]
[else (string->symbol (format "unknown-object: ~s" obj))]))
(define (show-properties-icon)
(make-object image-snip%
(build-path (collection-path "icons") "syncheck.png")))
;; COPIED AND MODIFIED from mrlib/syntax-browser.ss
(define syntax-snipclass%
(class snip-class%
(define/override (read stream)
(make-object syntax-snip%
(unmarshall-syntax (read-from-string (send stream get-bytes)))))
(super-instantiate ())))
;; marshall-syntax : syntax -> printable
(define (marshall-syntax stx)
(unless (syntax? stx)
(error 'marshall-syntax "not syntax: ~s\n" stx))
`(syntax
(source ,(marshall-object (syntax-source stx)))
(source-module ,(marshall-object (syntax-source-module stx)))
(position ,(syntax-position stx))
(line ,(syntax-line stx))
(column ,(syntax-column stx))
(span ,(syntax-span stx))
(original? ,(syntax-original? stx))
(properties
,@(map (λ (x) `(,x ,(marshall-object (syntax-property stx x))))
(syntax-property-symbol-keys stx)))
(contents
,(marshall-object (syntax-e stx)))))
(define snip-class (make-object syntax-snipclass%))
(send snip-class set-version 2)
(send snip-class set-classname
(format "~s" '(lib "implementation.ss" "macro-debugger" "syntax-browser")))
(send (get-the-snip-class-list) add snip-class)
;; marshall-object : any -> printable
;; really only intended for use with marshall-syntax
(define (marshall-object obj)
(cond
[(syntax? obj) (marshall-syntax obj)]
[(pair? obj)
`(pair ,(cons (marshall-object (car obj))
(marshall-object (cdr obj))))]
[(or (symbol? obj)
(char? obj)
(number? obj)
(string? obj)
(boolean? obj)
(null? obj))
`(other ,obj)]
[else (string->symbol (format "unknown-object: ~s" obj))]))
(define (unmarshall-syntax stx)
(match stx
[`(syntax
(source ,src)
(source-module ,source-module) ;; marshalling
(position ,pos)
(line ,line)
(column ,col)
(span ,span)
(original? ,original?)
(properties ,@(properties ...))
(contents ,contents))
(foldl
add-properties
(datum->syntax-object
#'here ;; ack
(unmarshall-object contents)
(list (unmarshall-object src)
line
col
pos
span))
properties)]
[else #'unknown-syntax-object]))
;; add-properties : syntax any -> syntax
(define (add-properties prop-spec stx)
(match prop-spec
[`(,(and sym (? symbol?))
,prop)
(syntax-property stx sym (unmarshall-object prop))]
[else stx]))
(define (unmarshall-object obj)
(let ([unknown (lambda () (string->symbol (format "unknown: ~s" obj)))])
(if (and (pair? obj)
(symbol? (car obj)))
(case (car obj)
[(pair)
(if (pair? (cdr obj))
(let ([raw-obj (cadr obj)])
(if (pair? raw-obj)
(cons (unmarshall-object (car raw-obj))
(unmarshall-object (cdr raw-obj)))
(unknown)))
(unknown))]
[(other)
(if (pair? (cdr obj))
(cadr obj)
(unknown))]
[(syntax) (unmarshall-syntax obj)]
[else (unknown)])
(unknown))))
;; COPIED AND MODIFIED from mrlib/syntax-browser.ss
(define syntax-snipclass%
(class snip-class%
(define/override (read stream)
(make-object syntax-snip%
(unmarshall-syntax (read-from-string (send stream get-bytes)))))
(super-instantiate ())))
)
(define snip-class (make-object syntax-snipclass%))
(send snip-class set-version 2)
(send snip-class set-classname
(format "~s" '(lib "implementation.ss" "macro-debugger" "syntax-browser")))
(send (get-the-snip-class-list) add snip-class)
(define (unmarshall-syntax stx)
(match stx
[`(syntax
(source ,src)
(source-module ,source-module) ;; marshalling
(position ,pos)
(line ,line)
(column ,col)
(span ,span)
(original? ,original?)
(properties . ,properties)
(contents ,contents))
(foldl
add-properties
(datum->syntax
#'here ;; ack
(unmarshall-object contents)
(list (unmarshall-object src)
line
col
pos
span))
properties)]
[else #'unknown-syntax-object]))
;; add-properties : syntax any -> syntax
(define (add-properties prop-spec stx)
(match prop-spec
[`(,(and sym (? symbol?))
,prop)
(syntax-property stx sym (unmarshall-object prop))]
[else stx]))
(define (unmarshall-object obj)
(let ([unknown (lambda () (string->symbol (format "unknown: ~s" obj)))])
(if (and (pair? obj)
(symbol? (car obj)))
(case (car obj)
[(pair)
(if (pair? (cdr obj))
(let ([raw-obj (cadr obj)])
(if (pair? raw-obj)
(cons (unmarshall-object (car raw-obj))
(unmarshall-object (cdr raw-obj)))
(unknown)))
(unknown))]
[(other)
(if (pair? (cdr obj))
(cadr obj)
(unknown))]
[(syntax) (unmarshall-syntax obj)]
[else (unknown)])
(unknown))))

View File

@ -1,11 +1,10 @@
#lang mzscheme
#lang scheme/base
(require scheme/class
mred
framework/framework
scheme/list
scheme/match
mzlib/kw
syntax/boundmap
"interfaces.ss"
"controller.ss"
@ -14,7 +13,8 @@
"hrule-snip.ss"
"properties.ss"
"text.ss"
"util.ss")
"util.ss"
"../util/mpi.ss")
(provide widget%)
;; widget%
@ -104,63 +104,73 @@
(send -text set-clickback a b handler)
(send -text change-style clickback-style a b)))))
(define/public add-syntax
(lambda/kw (stx #:key [hi-stxs null] hi-color alpha-table [definites null]
hi2-color [hi2-stxs null])
(define (get-binder id)
(define/public (add-syntax stx
#:binder-table [alpha-table #f]
#:shift-table [shift-table #f]
#:definites [definites null]
#:hi-colors [hi-colors null]
#:hi-stxss [hi-stxss null])
(define (get-binders id)
(define binder
(module-identifier-mapping-get alpha-table id (lambda () #f)))
(when (and (pair? hi-stxs) (not hi-color))
(error 'syntax-widget%::add-syntax "no highlight color specified"))
(let ([display (internal-add-syntax stx)]
[definite-table (make-hash-table)])
(when (and hi2-color (pair? hi2-stxs))
(send display highlight-syntaxes hi2-stxs hi2-color))
(when (and hi-color (pair? hi-stxs))
(send display highlight-syntaxes hi-stxs hi-color))
(for-each (lambda (x) (hash-table-put! definite-table x #t)) definites)
(when alpha-table
(let ([range (send display get-range)]
[start (send display get-start-position)])
(define (adjust n) (+ start n))
(for-each
(lambda (id)
#; ;; DISABLED
(match (identifier-binding id)
[(list src-mod src-name nom-mod nom-name _)
(for-each (lambda (id-r)
(send -text add-billboard
(adjust (car id-r))
(adjust (cdr id-r))
(string-append "from "
(mpi->string src-mod))
(if (hash-table-get definite-table id #f)
"blue"
"purple")))
(send range get-ranges id))]
[_ (void)])
(if shift-table
(cons binder (hash-ref shift-table binder null))
(list binder)))
(let ([display (internal-add-syntax stx)]
[definite-table (make-hasheq)])
(for-each (lambda (hi-stxs hi-color)
(send display highlight-syntaxes hi-stxs hi-color))
hi-stxss
hi-colors)
(for ([definite definites])
(hash-set! definite-table definite #t)
(when shift-table
(for ([shifted-definite (hash-ref shift-table definite null)])
(hash-set! definite-table shifted-definite #t))))
(when alpha-table
(let ([range (send display get-range)]
[start (send display get-start-position)])
(let* ([binders0
(module-identifier-mapping-map alpha-table (lambda (k v) k))]
[binders
(apply append (map get-binders binders0))])
(send display underline-syntaxes binders))
(for ([id (send range get-identifier-list)])
(define definite? (hash-ref definite-table id #f))
(when #f ;; DISABLED
(add-binding-billboard start range id definite?))
(for ([binder (get-binders id)])
(for ([binder-r (send range get-ranges binder)])
(for ([id-r (send range get-ranges id)])
(add-binding-arrow start binder-r id-r definite?)))))))
display))
(let ([binder (get-binder id)])
(when binder
(for-each
(lambda (binder-r)
(for-each (lambda (id-r)
(if (hash-table-get definite-table id #f)
(send -text add-arrow
(adjust (car binder-r))
(adjust (cdr binder-r))
(adjust (car id-r))
(adjust (cdr id-r))
"blue")
(send -text add-question-arrow
(adjust (car binder-r))
(adjust (cdr binder-r))
(adjust (car id-r))
(adjust (cdr id-r))
"purple")))
(send range get-ranges id)))
(send range get-ranges binder)))))
(send range get-identifier-list))))
display)))
(define/private (add-binding-arrow start binder-r id-r definite?)
(if definite?
(send -text add-arrow
(+ start (car binder-r))
(+ start (cdr binder-r))
(+ start (car id-r))
(+ start (cdr id-r))
"blue")
(send -text add-question-arrow
(+ start (car binder-r))
(+ start (cdr binder-r))
(+ start (car id-r))
(+ start (cdr id-r))
"purple")))
(define/private (add-binding-billboard start range id definite?)
(match (identifier-binding id)
[(list-rest src-mod src-name nom-mod nom-name _)
(for-each (lambda (id-r)
(send -text add-billboard
(+ start (car id-r))
(+ start (cdr id-r))
(string-append "from " (mpi->string src-mod))
(if definite? "blue" "purple")))
(send range get-ranges id))]
[_ (void)]))
(define/public (add-separator)
(with-unlock -text

View File

@ -0,0 +1,261 @@
#lang scheme/base
(require scheme/class
scheme/unit
scheme/list
scheme/match
scheme/gui
framework/framework
syntax/boundmap
"interfaces.ss"
"prefs.ss"
"extensions.ss"
"warning.ss"
"hiding-panel.ss"
"../model/deriv.ss"
"../model/deriv-util.ss"
"../model/deriv-find.ss"
"../model/deriv-parser.ss"
"../model/trace.ss"
"../model/reductions-config.ss"
"../model/reductions.ss"
"../model/steps.ss"
"../util/notify.ss"
"cursor.ss"
"debug-format.ss")
#;
(provide step-display%
step-display<%>)
(provide (all-defined-out))
;; Struct for one-by-one stepping
(define-struct (prestep protostep) ())
(define-struct (poststep protostep) ())
(define (prestep-term1 s) (state-term (protostep-s1 s)))
(define (poststep-term2 s) (state-term (protostep-s1 s)))
(define step-display<%>
(interface ()
;; add-syntax
add-syntax
;; add-step
add-step
;; add-error
add-error
;; add-final
add-final
;; add-internal-error
add-internal-error))
(define step-display%
(class* object% (step-display<%>)
(init-field config)
(init-field ((sbview syntax-widget)))
(super-new)
(define/public (add-internal-error part exn stx events)
(send sbview add-text
(if part
(format "Macro stepper error (~a)" part)
"Macro stepper error"))
(when (exn? exn)
(send sbview add-text " ")
(send sbview add-clickback "[details]"
(lambda _ (show-internal-error-details exn events))))
(send sbview add-text ". ")
(when stx (send sbview add-text "Original syntax:"))
(send sbview add-text "\n")
(when stx (send sbview add-syntax stx)))
(define/private (show-internal-error-details exn events)
(case (message-box/custom "Macro stepper internal error"
(format "Internal error:\n~a" (exn-message exn))
"Show error"
"Dump debugging file"
"Cancel")
((1) (queue-callback
(lambda ()
(raise exn))))
((2) (queue-callback
(lambda ()
(let ([file (put-file)])
(when file
(write-debug-file file exn events))))))
((3 #f) (void))))
(define/public (add-error exn)
(send sbview add-error-text (exn-message exn))
(send sbview add-text "\n"))
(define/public (add-step step
#:binders binders
#:shift-table [shift-table #f])
(cond [(step? step)
(show-step step binders shift-table)]
[(misstep? step)
(show-misstep step binders shift-table)]
[(prestep? step)
(show-prestep step binders shift-table)]
[(poststep? step)
(show-poststep step binders shift-table)]))
(define/public (add-syntax stx
#:binders binders
#:shift-table [shift-table #f]
#:definites definites)
(send sbview add-syntax stx
#:binder-table binders
#:shift-table shift-table
#:definites (or definites null)))
(define/public (add-final stx error
#:binders binders
#:shift-table [shift-table #f]
#:definites definites)
(when stx
(send sbview add-text "Expansion finished\n")
(send sbview add-syntax stx
#:binder-table binders
#:shift-table shift-table
#:definites (or definites null)))
(when error
(add-error error)))
;; show-lctx : Step -> void
(define/private (show-lctx step binders shift-table)
(define state (protostep-s1 step))
(define lctx (state-lctx state))
(when (pair? lctx)
(send sbview add-text "\n")
(for-each (lambda (bf)
(send sbview add-text
"while executing macro transformer in:\n")
(insert-syntax/redex (bigframe-term bf)
(bigframe-foci bf)
binders
shift-table
(state-uses state)
(state-frontier state)))
(reverse lctx))))
;; separator : Step -> void
(define/private (separator step)
(insert-step-separator (step-type->string (protostep-type step))))
;; separator/small : Step -> void
(define/private (separator/small step)
(insert-step-separator/small
(step-type->string (protostep-type step))))
;; show-step : Step -> void
(define/private (show-step step binders shift-table)
(show-state/redex (protostep-s1 step) binders shift-table)
(separator step)
(show-state/contractum (step-s2 step) binders shift-table)
(show-lctx step binders shift-table))
(define/private (show-state/redex state binders shift-table)
(insert-syntax/redex (state-term state)
(state-foci state)
binders
shift-table
(state-uses state)
(state-frontier state)))
(define/private (show-state/contractum state binders shift-table)
(insert-syntax/contractum (state-term state)
(state-foci state)
binders
shift-table
(state-uses state)
(state-frontier state)))
;; show-prestep : Step -> void
(define/private (show-prestep step binders shift-table)
(separator/small step)
(show-state/redex (protostep-s1 step) binders shift-table)
(show-lctx step binders shift-table))
;; show-poststep : Step -> void
(define/private (show-poststep step binders shift-table)
(separator/small step)
(show-state/contractum (protostep-s1 step) binders shift-table)
(show-lctx step binders shift-table))
;; show-misstep : Step -> void
(define/private (show-misstep step binders shift-table)
(define state (protostep-s1 step))
(show-state/redex state binders shift-table)
(separator step)
(send sbview add-error-text (exn-message (misstep-exn step)))
(send sbview add-text "\n")
(when (exn:fail:syntax? (misstep-exn step))
(for-each (lambda (e)
(send sbview add-syntax e
#:binder-table binders
#:shift-table shift-table
#:definites (or (state-uses state) null)))
(exn:fail:syntax-exprs (misstep-exn step))))
(show-lctx step binders shift-table))
;; insert-syntax/color
(define/private (insert-syntax/color stx foci binders shift-table
definites frontier hi-color)
(define highlight-foci? (send config get-highlight-foci?))
(define highlight-frontier? (send config get-highlight-frontier?))
(send sbview add-syntax stx
#:definites (or definites null)
#:binder-table binders
#:shift-table shift-table
#:hi-colors (list hi-color
"WhiteSmoke")
#:hi-stxss (list (if highlight-foci? foci null)
(if highlight-frontier? frontier null))))
;; insert-syntax/redex
(define/private (insert-syntax/redex stx foci binders shift-table
definites frontier)
(insert-syntax/color stx foci binders shift-table
definites frontier "MistyRose"))
;; insert-syntax/contractum
(define/private (insert-syntax/contractum stx foci binders shift-table
definites frontier)
(insert-syntax/color stx foci binders shift-table
definites frontier "LightCyan"))
;; insert-step-separator : string -> void
(define/private (insert-step-separator text)
(send sbview add-text "\n ")
(send sbview add-text
(make-object image-snip%
(build-path (collection-path "icons")
"red-arrow.bmp")))
(send sbview add-text " ")
(send sbview add-text text)
(send sbview add-text "\n\n"))
;; insert-as-separator : string -> void
(define/private (insert-as-separator text)
(send sbview add-text "\n ")
(send sbview add-text text)
(send sbview add-text "\n\n"))
;; insert-step-separator/small : string -> void
(define/private (insert-step-separator/small text)
(send sbview add-text " ")
(send sbview add-text
(make-object image-snip%
(build-path (collection-path "icons")
"red-arrow.bmp")))
(send sbview add-text " ")
(send sbview add-text text)
(send sbview add-text "\n\n"))
))

View File

@ -13,6 +13,7 @@
"warning.ss"
"hiding-panel.ss"
"term-record.ss"
"step-display.ss"
"../model/deriv.ss"
"../model/deriv-util.ss"
"../model/deriv-find.ss"
@ -95,6 +96,7 @@
(define/public (get-config) config)
(define/public (get-controller) sbc)
(define/public (get-view) sbview)
(define/public (get-step-displayer) step-displayer)
(define/public (get-warnings-area) warnings-area)
(define/public (get-macro-hiding-prefs) macro-hiding-prefs)
@ -127,6 +129,9 @@
(define sbview (new stepper-syntax-widget%
(parent area)
(macro-stepper this)))
(define step-displayer (new step-display%
(config config)
(syntax-widget sbview)))
(define sbc (send sbview get-controller))
(define control-pane
(new vertical-panel% (parent area) (stretchable-height #f)))

View File

@ -12,6 +12,7 @@
"extensions.ss"
"warning.ss"
"hiding-panel.ss"
"step-display.ss"
"../model/deriv.ss"
"../model/deriv-util.ss"
"../model/deriv-find.ss"
@ -26,23 +27,18 @@
(provide term-record%)
;; Struct for one-by-one stepping
(define-struct (prestep protostep) ())
(define-struct (poststep protostep) ())
(define (prestep-term1 s) (state-term (protostep-s1 s)))
(define (poststep-term2 s) (state-term (protostep-s1 s)))
;; TermRecords
(define term-record%
(class object%
(init-field stepper)
(init-field [events #f])
(define config (send stepper get-config))
(define sbview (send stepper get-view))
(define displayer (send stepper get-step-displayer))
;; Data
(init-field [events #f])
(init-field [raw-deriv #f])
(define raw-deriv-oops #f)
@ -50,15 +46,18 @@
(define deriv #f)
(define deriv-hidden? #f)
(define binders #f)
(define shift-table #f)
(define raw-steps #f)
(define raw-steps-estx #f)
(define definites #f)
(define error #f)
(define raw-steps-estx #f) ;; #f if raw-steps-exn is exn
(define raw-steps-exn #f) ;; #f if raw-steps-estx is syntax
(define raw-steps-definites #f)
(define raw-steps-oops #f)
(define steps #f)
;; --
(define steps-position #f)
(super-new)
@ -74,10 +73,11 @@
(define-guarded-getters (recache-deriv!)
[get-deriv deriv]
[get-deriv-hidden? deriv-hidden?]
[get-binders binders])
[get-binders binders]
[get-shift-table shift-table])
(define-guarded-getters (recache-raw-steps!)
[get-definites definites]
[get-error error]
[get-raw-steps-definites raw-steps-definites]
[get-raw-steps-exn raw-steps-exn]
[get-raw-steps-oops raw-steps-oops])
(define-guarded-getters (recache-steps!)
[get-steps steps])
@ -92,8 +92,8 @@
(invalidate-steps!)
(set! raw-steps #f)
(set! raw-steps-estx #f)
(set! definites #f)
(set! error #f)
(set! raw-steps-exn #f)
(set! raw-steps-definites #f)
(set! raw-steps-oops #f))
;; invalidate-synth! : -> void
@ -106,7 +106,8 @@
(invalidate-synth!)
(set! deriv #f)
(set! deriv-hidden? #f)
(set! binders #f))
(set! binders #f)
(set! shift-table #f))
;; recache! : -> void
(define/public (recache!)
@ -132,12 +133,14 @@
(when (not d)
(set! deriv-hidden? #t))
(when d
(let ([alpha-table (make-module-identifier-mapping)])
(let ([alpha-table (make-module-identifier-mapping)]
[binder-ids (extract-all-fresh-names d)])
(for-each (lambda (id)
(module-identifier-mapping-put! alpha-table id id))
(extract-all-fresh-names d))
binder-ids)
(set! deriv d)
(set! binders alpha-table))))))))
(set! binders alpha-table)
(set! shift-table (compute-shift-table d)))))))))
;; recache-synth! : -> void
(define/private (recache-synth!)
@ -158,8 +161,8 @@
(reductions+ deriv))])
(set! raw-steps raw-steps*)
(set! raw-steps-estx estx*)
(set! error error*)
(set! definites definites*)))))))
(set! raw-steps-exn error*)
(set! raw-steps-definites definites*)))))))
;; recache-steps! : -> void
(define/private (recache-steps!)
@ -271,20 +274,19 @@
;; display-initial-term : -> void
(define/public (display-initial-term)
(add-syntax (wderiv-e1 deriv) #f null))
(send displayer add-syntax (wderiv-e1 deriv) #f null))
;; display-final-term : -> void
(define/public (display-final-term)
(recache-steps!)
(cond [(syntax? raw-steps-estx)
(add-syntax raw-steps-estx binders definites)]
[(exn? error)
(add-error error)]
[raw-steps-oops
(add-internal-error "steps" raw-steps-oops #f)]
[else
(error 'term-record::display-final-term
"internal error")]))
(send displayer add-syntax raw-steps-estx
#:binders binders
#:shift-table shift-table
#:definites raw-steps-definites)]
[(exn? raw-steps-exn)
(send displayer add-error raw-steps-exn)]
[else (display-oops #f)]))
;; display-step : -> void
(define/public (display-step)
@ -292,191 +294,25 @@
(cond [steps
(let ([step (cursor:next steps)])
(if step
(add-step step binders)
(add-final raw-steps-estx error binders definites)))]
[raw-steps-oops
(add-internal-error "steps" raw-steps-oops (wderiv-e1 deriv))]
(send displayer add-step step
#:binders binders
#:shift-table shift-table)
(send displayer add-final raw-steps-estx raw-steps-exn
#:binders binders
#:shift-table shift-table
#:definites raw-steps-definites)))]
[else (display-oops #t)]))
;; display-oops : boolean -> void
(define/private (display-oops show-syntax?)
(cond [raw-steps-oops
(send displayer add-internal-error
"steps" raw-steps-oops
(and show-syntax? (wderiv-e1 deriv))
events)]
[raw-deriv-oops
(add-internal-error "derivation" raw-deriv-oops #f)]
(send displayer add-internal-error
"derivation" raw-deriv-oops #f events)]
[else
(add-internal-error "derivation" #f)]))
(define/public (add-internal-error part exn stx)
(send sbview add-text
(if part
(format "Macro stepper error (~a)" part)
"Macro stepper error"))
(when (exn? exn)
(send sbview add-text " ")
(send sbview add-clickback "[details]"
(lambda _ (show-internal-error-details exn))))
(send sbview add-text ". ")
(when stx (send sbview add-text "Original syntax:"))
(send sbview add-text "\n")
(when stx (send sbview add-syntax stx)))
(define/private (show-internal-error-details exn)
(case (message-box/custom "Macro stepper internal error"
(format "Internal error:\n~a" (exn-message exn))
"Show error"
"Dump debugging file"
"Cancel")
((1) (queue-callback
(lambda ()
(raise exn))))
((2) (queue-callback
(lambda ()
(let ([file (put-file)])
(when file
(write-debug-file file exn events))))))
((3 #f) (void))))
(define/public (add-error exn)
(send sbview add-error-text (exn-message exn))
(send sbview add-text "\n"))
(define/public (add-step step binders)
(cond [(step? step)
(show-step step binders)]
[(misstep? step)
(show-misstep step binders)]
[(prestep? step)
(show-prestep step binders)]
[(poststep? step)
(show-poststep step binders)]))
(define/public (add-syntax stx binders definites)
(send sbview add-syntax stx
'#:alpha-table binders
'#:definites (or definites null)))
(define/private (add-final stx error binders definites)
(when stx
(send sbview add-text "Expansion finished\n")
(send sbview add-syntax stx
'#:alpha-table binders
'#:definites (or definites null)))
(when error
(add-error error)))
;; show-lctx : Step -> void
(define/private (show-lctx step binders)
(define state (protostep-s1 step))
(define lctx (state-lctx state))
(when (pair? lctx)
(send sbview add-text "\n")
(for-each (lambda (bf)
(send sbview add-text
"while executing macro transformer in:\n")
(insert-syntax/redex (bigframe-term bf)
(bigframe-foci bf)
binders
(state-uses state)
(state-frontier state)))
(reverse lctx))))
;; separator : Step -> void
(define/private (separator step)
(insert-step-separator (step-type->string (protostep-type step))))
;; separator/small : Step -> void
(define/private (separator/small step)
(insert-step-separator/small
(step-type->string (protostep-type step))))
;; show-step : Step -> void
(define/private (show-step step binders)
(show-state/redex (protostep-s1 step) binders)
(separator step)
(show-state/contractum (step-s2 step) binders)
(show-lctx step binders))
(define/private (show-state/redex state binders)
(insert-syntax/contractum (state-term state)
(state-foci state)
binders
(state-uses state)
(state-frontier state)))
(define/private (show-state/contractum state binders)
(insert-syntax/contractum (state-term state)
(state-foci state)
binders
(state-uses state)
(state-frontier state)))
;; show-prestep : Step -> void
(define/private (show-prestep step binders)
(separator/small step)
(show-state/redex (protostep-s1 step) binders)
(show-lctx step binders))
;; show-poststep : Step -> void
(define/private (show-poststep step binders)
(separator/small step)
(show-state/contractum (protostep-s1 step) binders)
(show-lctx step binders))
;; show-misstep : Step -> void
(define/private (show-misstep step binders)
(define state (protostep-s1 step))
(show-state/redex state binders)
(separator step)
(send sbview add-error-text (exn-message (misstep-exn step)))
(send sbview add-text "\n")
(when (exn:fail:syntax? (misstep-exn step))
(for-each (lambda (e)
(send sbview add-syntax e
'#:alpha-table binders
'#:definites (or (state-uses state) null)))
(exn:fail:syntax-exprs (misstep-exn step))))
(show-lctx step binders))
;; insert-syntax/color : syntax syntaxes identifiers syntaxes string -> void
(define/private (insert-syntax/color stx foci binders definites frontier hi-color)
(send sbview add-syntax stx
'#:definites (or definites null)
'#:alpha-table binders
'#:hi-color hi-color
'#:hi-stxs (if (send config get-highlight-foci?) foci null)
'#:hi2-color "WhiteSmoke"
'#:hi2-stxs (if (send config get-highlight-frontier?) frontier null)))
;; insert-syntax/redex : syntax syntaxes identifiers syntaxes -> void
(define/private (insert-syntax/redex stx foci binders definites frontier)
(insert-syntax/color stx foci binders definites frontier "MistyRose"))
;; insert-syntax/contractum : syntax syntaxes identifiers syntaxes -> void
(define/private (insert-syntax/contractum stx foci binders definites frontier)
(insert-syntax/color stx foci binders definites frontier "LightCyan"))
;; insert-step-separator : string -> void
(define/private (insert-step-separator text)
(send sbview add-text "\n ")
(send sbview add-text
(make-object image-snip%
(build-path (collection-path "icons")
"red-arrow.bmp")))
(send sbview add-text " ")
(send sbview add-text text)
(send sbview add-text "\n\n"))
;; insert-as-separator : string -> void
(define/private (insert-as-separator text)
(send sbview add-text "\n ")
(send sbview add-text text)
(send sbview add-text "\n\n"))
;; insert-step-separator/small : string -> void
(define/private (insert-step-separator/small text)
(send sbview add-text " ")
(send sbview add-text
(make-object image-snip%
(build-path (collection-path "icons")
"red-arrow.bmp")))
(send sbview add-text " ")
(send sbview add-text text)
(send sbview add-text "\n\n"))
(error 'term-record::display-oops "internal error")]))
))

View File

@ -1,131 +1,130 @@
(module warning mzscheme
(require mzlib/class
mred
framework)
(provide warnings%
stepper-warnings%)
;; warnings%
(define warnings%
(class object%
(init parent)
(super-new)
#lang scheme/base
(require scheme/class
mred
framework)
(provide warnings%
stepper-warnings%)
(define super-panel
(new vertical-panel%
(parent parent)
(stretchable-height #f)))
(define main-panel
(new horizontal-panel%
(parent super-panel)
(style '(deleted border))))
(define label (new message% (parent main-panel) (label "Warnings")))
(define text (new text:hide-caret/selection% (auto-wrap #t)))
(define ec
(new editor-canvas%
(parent main-panel)
(editor text)
(style '(auto-vscroll auto-hscroll))
(line-count 3)))
(define dismiss
(new button%
(parent main-panel)
(label "Hide")
(stretchable-height #t)
(callback (lambda _ (show #f)))))
(send text set-autowrap-bitmap #f)
(send text lock #t)
(define/public (get-text) text)
(define/public (show ?)
(send super-panel change-children
(lambda _
(if ?
(list main-panel)
null))))
;; Warning management
(define keys null)
;; clear : -> void
(define/public (clear)
(set! keys null)
(send* text
(lock #f)
(erase)
(lock #t))
(show #f))
;; add : symbol string ... -> void
(define/public (add key . strs)
(unless (memq key keys)
(send text lock #f)
(for-each (lambda (s) (send text insert s)) strs)
(send text insert "\n\n")
(send text scroll-to-position 0)
(send text lock #t)
(show #t)))
))
(define stepper-warnings%
(class warnings%
(super-new)
(inherit add)
(define/private (add-nonlinearity-warning)
(add
'nonlinearity
"An opaque macro duplicated one of its subterms. "
"Macro hiding requires opaque macros to use their subterms linearly. "
"The macro stepper is showing the expansion of that macro use."))
(define/private (add-localactions-warning)
(add
'localactions
"An opaque macro called local-expand, syntax-local-lift-expression, "
"etc. Macro hiding cannot currently handle local actions. "
"The macro stepper is showing the expansion of that macro use."))
(define/private (add-lifts-warning)
(add
'lifts
"A transparent macro called syntax-local-lift-expression or "
"syntax-local-lift-module-end-declaration. "
"The macro stepper is only hiding macro after the "
"lifts are caught."))
;; warnings%
(define warnings%
(class object%
(init parent)
(super-new)
(define/private (add-lift/let-warning)
(add
'lift/let
"Lifts occurred during the expansion of phase 1 or higher code. "
"The macro stepper is showing some expansions that should be hidden."))
(define super-panel
(new vertical-panel%
(parent parent)
(stretchable-height #f)))
(define main-panel
(new horizontal-panel%
(parent super-panel)
(style '(deleted border))))
(define label (new message% (parent main-panel) (label "Warnings")))
(define text (new text:hide-caret/selection% (auto-wrap #t)))
(define ec
(new editor-canvas%
(parent main-panel)
(editor text)
(style '(auto-vscroll auto-hscroll))
(line-count 3)))
(define dismiss
(new button%
(parent main-panel)
(label "Hide")
(stretchable-height #t)
(callback (lambda _ (show #f)))))
(send text set-autowrap-bitmap #f)
(send text lock #t)
(define/public (get-text) text)
(define/public (show ?)
(send super-panel change-children
(lambda _
(if ?
(list main-panel)
null))))
;; Warning management
(define keys null)
;; clear : -> void
(define/public (clear)
(set! keys null)
(send* text
(lock #f)
(erase)
(lock #t))
(show #f))
;; add : symbol string ... -> void
(define/public (add key . strs)
(unless (memq key keys)
(send text lock #f)
(for-each (lambda (s) (send text insert s)) strs)
(send text insert "\n\n")
(send text scroll-to-position 0)
(send text lock #t)
(show #t)))
))
(define/private (add-hidden-lift-site-warning)
(add
'hidden-lift-site
"An opaque macro contained the target of a lifted declaration."
"The macro stepper is showing the expansion of that macro use."))
(define stepper-warnings%
(class warnings%
(super-new)
(inherit add)
(define/private (add-nonlinearity-warning)
(add
'nonlinearity
"An opaque macro duplicated one of its subterms. "
"Macro hiding requires opaque macros to use their subterms linearly. "
"The macro stepper is showing the expansion of that macro use."))
(define/private (add-localactions-warning)
(add
'localactions
"An opaque macro called local-expand, syntax-local-lift-expression, "
"etc. Macro hiding cannot currently handle local actions. "
"The macro stepper is showing the expansion of that macro use."))
(define/private (add-lifts-warning)
(add
'lifts
"A transparent macro called syntax-local-lift-expression or "
"syntax-local-lift-module-end-declaration. "
"The macro stepper is only hiding macro after the "
"lifts are caught."))
(define/private (add-hidden-lift-site/continuing-warning)
(add
'hidden-lift-site/continuing
"The target of a lifted declaration was a hidden #%module-begin context. "
"The macro stepper is omitting the lifted declaration."))
(define/public (add-warning tag args)
(case tag
((nonlinearity)
(add-nonlinearity-warning))
((localactions)
(add-localactions-warning))
((lifts)
(add-lifts-warning))
((lift/let)
(add-lift/let-warning))
((hidden-lift-site)
(add-hidden-lift-site-warning))
((hidden-lift-site/continuing)
(add-hidden-lift-site/continuing-warning))))
))
)
(define/private (add-lift/let-warning)
(add
'lift/let
"Lifts occurred during the expansion of phase 1 or higher code. "
"The macro stepper is showing some expansions that should be hidden."))
(define/private (add-hidden-lift-site-warning)
(add
'hidden-lift-site
"An opaque macro contained the target of a lifted declaration."
"The macro stepper is showing the expansion of that macro use."))
(define/private (add-hidden-lift-site/continuing-warning)
(add
'hidden-lift-site/continuing
"The target of a lifted declaration was a hidden #%module-begin context. "
"The macro stepper is omitting the lifted declaration."))
(define/public (add-warning tag args)
(case tag
((nonlinearity)
(add-nonlinearity-warning))
((localactions)
(add-localactions-warning))
((lifts)
(add-lifts-warning))
((lift/let)
(add-lift/let-warning))
((hidden-lift-site)
(add-hidden-lift-site-warning))
((hidden-lift-site/continuing)
(add-hidden-lift-site/continuing-warning))))
))

View File

@ -1 +1 @@
#lang scheme/base (provide stamp) (define stamp "12dec2008")
#lang scheme/base (provide stamp) (define stamp "14dec2008")

View File

@ -2,6 +2,7 @@
(require scheme/port
scheme/list
scheme/string
syntax/moddep
scheme/gui/dynamic)
@ -17,9 +18,10 @@
sandbox-override-collection-paths
sandbox-path-permissions
sandbox-security-guard
sandbox-exit-handler
sandbox-network-guard
sandbox-exit-handler
sandbox-make-inspector
sandbox-make-code-inspector
sandbox-make-logger
sandbox-memory-limit
sandbox-eval-limits
@ -37,6 +39,8 @@
call-in-nested-thread*
call-with-limits
with-limits
exn:fail:sandbox-terminated?
exn:fail:sandbox-terminated-reason
exn:fail:resource?
exn:fail:resource-resource)
@ -102,33 +106,31 @@
[suffix-re (bytes-append #"(?:$|" sep-re #")")])
(lambda (path)
(if (byte-regexp? path)
path
(let* ([path (path->bytes (simplify-path* path))]
[path (regexp-quote (regexp-replace last-sep path #""))])
(byte-regexp (bytes-append #"^" path suffix-re)))))))
path
(let* ([path (path->bytes (simplify-path* path))]
[path (regexp-quote (regexp-replace last-sep path #""))])
(byte-regexp (bytes-append #"^" path suffix-re)))))))
(define sandbox-path-permissions
(make-parameter '()
(lambda (new)
(map (lambda (perm) (cons (car perm) (map path->bregexp (cdr perm))))
new))))
(lambda (new)
(map (lambda (perm) (list (car perm) (path->bregexp (cadr perm))))
new))))
(define sandbox-network-guard
(make-parameter (lambda (what . xs)
(error what "network access denied: ~e" xs))))
(define default-sandbox-guard
(define (make-default-sandbox-guard)
(let ([orig-security (current-security-guard)])
(make-security-guard
orig-security
(lambda (what path modes)
(when path
(let ([needed (let loop ([order permission-order])
(cond [(null? order)
(let ([needed (car (or (for/or ([p (in-list permission-order)])
(memq p modes))
(error 'default-sandbox-guard
"unknown access modes: ~e" modes)]
[(memq (car order) modes) (car order)]
[else (loop (cdr order))]))]
"unknown access modes: ~e" modes)))]
[bpath (parameterize ([current-security-guard orig-security])
(path->bytes (simplify-path* path)))])
(unless (ormap (lambda (perm)
@ -136,20 +138,29 @@
(regexp-match (cadr perm) bpath)))
(sandbox-path-permissions))
(error what "`~a' access denied for ~a"
(apply string-append
(add-between (map symbol->string modes) "+"))
(string-append* (add-between (map symbol->string modes) "+"))
path)))))
(lambda args (apply (sandbox-network-guard) args)))))
(define sandbox-security-guard (make-parameter default-sandbox-guard))
(define sandbox-security-guard
(make-parameter make-default-sandbox-guard
(lambda (x)
(if (or (security-guard? x)
(and (procedure? x) (procedure-arity-includes? x 0)))
x
(raise-type-error
'sandbox-security-guard
"security-guard or a security-guard translator procedure" x)))))
(define (default-sandbox-exit-handler _)
(error 'exit "sandboxed code cannot exit"))
;; this is never really used (see where it's used in the evaluator)
(define (default-sandbox-exit-handler _) (error 'exit "sandbox exits"))
(define sandbox-exit-handler (make-parameter default-sandbox-exit-handler))
(define sandbox-make-inspector (make-parameter make-inspector))
(define sandbox-make-code-inspector (make-parameter make-inspector))
(define sandbox-make-logger (make-parameter current-logger))
(define (compute-permissions paths+require-perms)
@ -169,7 +180,7 @@
(let ([base (simplify-path* base)])
(loop (cdr paths)
(if (member base bases) bases (cons base bases))))))))
(append (map (lambda (p) `(read ,(path->bytes p))) paths)
(append (map (lambda (p) `(read ,p)) paths)
(map (lambda (b) `(read ,(build-path b "compiled"))) bases)
(map (lambda (b) `(exists ,b)) bases)))
@ -433,21 +444,34 @@
(lambda (x) (abort-current-continuation deftag x)))
(loop (car exprs) (cdr exprs))))))))))
;; We need a powerful enough code inspector to invoke the errortrace library
;; (indirectly through private/sandbox-coverage). But there is a small problem
;; here -- errortrace/stacktrace.ss will grab the global code inspector value
;; at the time it is invoked. So we grab it here too, and use it to wrap the
;; code that invokes errortrace. If errortrace/stacktrace.ss is changed to
;; grab the current inspector, then it would be better to avoid this here, and
;; pass `evaluate-program' the inspector that was in effect when the sandbox
;; was created.
(define orig-code-inspector (current-code-inspector))
(define (evaluate-program program limit-thunk uncovered!)
(when uncovered!
(eval `(,#'#%require scheme/private/sandbox-coverage)))
;; the actual evaluation happens under the specified limits
((limit-thunk (lambda ()
(if (and (pair? program) (eq? 'begin (car program)))
(eval* (cdr program))
(eval program)))))
(parameterize ([current-code-inspector orig-code-inspector])
(when uncovered!
(eval `(,#'#%require scheme/private/sandbox-coverage))))
(let ([ns (syntax-case* program (module) literal-identifier=?
[(module mod . body)
(identifier? #'mod)
(let ([mod #'mod])
(eval `(,#'require (quote ,mod)))
(module->namespace `(quote ,(syntax-e mod))))]
(lambda ()
(eval `(,#'require (quote ,mod)))
(module->namespace `(quote ,(syntax-e mod)))))]
[_else #f])])
;; the actual evaluation happens under the specified limits
((limit-thunk (lambda ()
(if (and (pair? program) (eq? 'begin (car program)))
(eval* (cdr program))
(eval program))
(when ns (set! ns (ns))))))
(when uncovered!
(let ([get (let ([ns (current-namespace)])
(lambda () (eval '(get-uncovered-expressions) ns)))])
@ -492,11 +516,21 @@
(define-evaluator-messenger (get-uncovered-expressions . xs) 'uncovered)
(define-evaluator-messenger (call-in-sandbox-context thunk) 'thunk)
(define-struct (exn:fail:sandbox-terminated exn:fail) (reason) #:transparent)
(define (make-terminated reason)
(make-exn:fail:sandbox-terminated
(format "evaluator: terminated (~a)" reason)
(current-continuation-marks)
reason))
(define (make-evaluator* init-hook allow program-maker)
(define orig-code-inspector (current-code-inspector))
(define orig-cust (current-custodian))
(define memory-cust (make-custodian orig-cust))
(define memory-cust-box (make-custodian-box memory-cust #t))
(define user-cust (make-custodian memory-cust))
(define user-cust-box (make-custodian-box user-cust #t))
(define coverage? (sandbox-coverage-enabled))
(define uncovered #f)
(define input-ch (make-channel))
@ -507,6 +541,18 @@
(define limits (sandbox-eval-limits))
(define user-thread #t) ; set later to the thread
(define user-done-evt #t) ; set in the same place
(define terminated? #f) ; set to an exception value when the sandbox dies
(define (terminated! reason)
(unless terminated?
(set! terminated?
(make-terminated
(cond [(eq? reason #t) ; => guess
(if (custodian-box-value user-cust-box)
'thread-killed
'custodian-shutdown)]
[reason reason] ; => explicit
;; otherwise it's an indication of an internal error
[else "internal error: no termination reason"])))))
(define (limit-thunk thunk)
(let* ([sec (and limits (car limits))]
[mb (and limits (cadr limits))])
@ -515,6 +561,7 @@
(when user-thread
(let ([t user-thread])
(set! user-thread #f)
(terminated! #f)
(custodian-shutdown-all user-cust)
(kill-thread t))) ; just in case
(void))
@ -535,7 +582,8 @@
(let ([n 0])
(let loop ()
(let ([expr (channel-get input-ch)])
(when (eof-object? expr) (channel-put result-ch expr) (user-kill))
(when (eof-object? expr)
(terminated! 'eof) (channel-put result-ch expr) (user-kill))
(with-handlers ([void (lambda (exn)
(channel-put result-ch (cons 'exn exn)))])
(define run
@ -549,22 +597,28 @@
(channel-put result-ch (cons 'vals (call-with-values run list))))
(loop)))))
(define (user-eval expr)
(let ([r (if user-thread
(begin (channel-put input-ch expr)
(let loop ()
(with-handlers ([(lambda (e)
(and (sandbox-propagate-breaks)
(exn:break? e)))
(lambda (e)
(user-break)
(loop))])
(sync user-done-evt result-ch))))
eof)])
(cond [(eof-object? r) (error 'evaluator "terminated~a"
(if (custodian-box-value memory-cust-box)
"" " (memory exceeded)"))]
[(eq? (car r) 'exn) (raise (cdr r))]
[else (apply values (cdr r))])))
;; the thread will usually be running, but it might be killed outside of
;; the sandboxed environment, for example, if you do something like
;; (kill-thread (ev '(current-thread))) when there are no per-expression
;; limits (since then you get a different thread, which is already dead).
(when (and user-thread (thread-dead? user-thread))
(terminated! #t))
(cond
[terminated? => raise]
[(not user-thread) (error 'sandbox "internal error (user-thread is #f)")]
[else
(channel-put input-ch expr)
(let ([r (let loop ()
(with-handlers ([(if (sandbox-propagate-breaks)
exn:break? (lambda (_) #f))
(lambda (e) (user-break) (loop))])
(sync user-done-evt result-ch)))])
(cond [(eof-object? r)
(terminated! (and (not (custodian-box-value memory-cust-box))
'out-of-memory))
(raise terminated?)]
[(eq? (car r) 'exn) (raise (cdr r))]
[else (apply values (cdr r))]))]))
(define get-uncovered
(case-lambda
[() (get-uncovered #t)]
@ -592,7 +646,7 @@
(let ([msg (evaluator-message-msg expr)])
(case msg
[(alive?) (and user-thread (not (thread-dead? user-thread)))]
[(kill) (user-kill)]
[(kill) (terminated! 'evaluator-killed) (user-kill)]
[(break) (user-break)]
[(limits) (set! limits (evaluator-message-args expr))]
[(input) (apply input-putter (evaluator-message-args expr))]
@ -623,7 +677,7 @@
out)]
[else (error 'make-evaluator "bad sandox-~a spec: ~e" what out)]))
;; set global memory limit
(when (sandbox-memory-limit)
(when (and memory-accounting? (sandbox-memory-limit))
(custodian-limit-memory
memory-cust (* (sandbox-memory-limit) 1024 1024) memory-cust))
(parameterize* ; the order in these matters
@ -660,12 +714,26 @@
;; general info
[current-command-line-arguments '#()]
;; restrict the sandbox context from this point
[current-security-guard (sandbox-security-guard)]
[exit-handler (sandbox-exit-handler)]
[current-security-guard
(let ([g (sandbox-security-guard)]) (if (security-guard? g) g (g)))]
[exit-handler
(let ([h (sandbox-exit-handler)])
(if (eq? h default-sandbox-exit-handler)
(lambda _ (terminated! 'exited) (user-kill))
h))]
[current-inspector ((sandbox-make-inspector))]
[current-logger ((sandbox-make-logger))]
;; This breaks because we need to load some libraries that are trusted
;; [current-code-inspector (make-inspector)]
[current-code-inspector (make-inspector)]
;; The code inspector serves two purposes -- making sure that only trusted
;; byte-code is loaded, and avoiding using protected moduel bindings, like
;; the foreign library's `unsafe!'. We don't need the first because we
;; control it indirectly through the security guard, so this handler makes
;; sure that byte-code is loaded using the original inspector.
[current-load/use-compiled
(let ([handler (current-load/use-compiled)])
(lambda (path modname)
(parameterize ([current-code-inspector orig-code-inspector])
(handler path modname))))]
;; Note the above definition of `current-eventspace': in MzScheme, it
;; is an unused parameter. Also note that creating an eventspace
;; starts a thread that will eventually run the callback code (which
@ -673,8 +741,10 @@
;; must be nested in the above (which is what paramaterize* does), or
;; it will not use the new namespace.
[current-eventspace (make-eventspace)])
(set! user-thread (bg-run->thread (run-in-bg user-process)))
(set! user-done-evt (handle-evt user-thread (lambda (_) (user-kill) eof)))
(let ([t (bg-run->thread (run-in-bg user-process))])
(set! user-done-evt
(handle-evt t (lambda (_) (terminated! #t) (user-kill) eof)))
(set! user-thread t))
(let ([r (channel-get result-ch)])
(if (eq? r 'ok)
;; initial program executed ok, so return an evaluator

View File

@ -16,7 +16,10 @@
The @schememodname[scheme/sandbox] module provides utilities for
creating ``sandboxed'' evaluators, which are configured in a
particular way and can have restricted resources (memory and time),
filesystem access, and network access.
filesystem access, and network access. The common use case for this
module is for a restricted sandboxed environment, so the defaults are
set up to make it safe. For other uses you will likely need to change
mane of these settings.
@defproc*[([(make-evaluator [language (or/c module-path?
(list/c 'special symbol?)
@ -240,6 +243,19 @@ used from a module (by using a new namespace):
}
@defproc*[([(exn:fail:sandbox-terminated? [v any/c]) boolean?]
[(exn:fail:sandbox-terminated-reason [exn exn:fail:sandbox-terminated?])
symbol/c])]{
A predicate and accessor for exceptions that are raised when a sandbox
is terminated. Once a sandbox raises such an exception, it will
continue to raise it on further evaluation attempts.
@scheme[call-with-limits]. The @scheme[resource] field holds a symbol,
either @scheme['time] or @scheme['memory].}
@; ----------------------------------------------------------------------
@section{Customizing Evaluators}
@ -414,12 +430,15 @@ done using a fake library that provides the same interface but no
actual interaction. The default is @scheme[null].}
@defparam[sandbox-security-guard guard security-guard?]{
@defparam[sandbox-security-guard guard
(or/c security-guard? (-> security-guard?))]{
A parameter that determines the initial
@scheme[(current-security-guard)] for sandboxed evaluations. The
default forbids all filesystem I/O except for things in
@scheme[sandbox-path-permissions], and it uses
@scheme[(current-security-guard)] for sandboxed evaluations. It can
be either a security guard, or a function to construct one. The
default is a function that restricts the access of the current
security guard by forbidding all filesystem I/O except for
specifications in @scheme[sandbox-path-permissions], and it uses
@scheme[sandbox-network-guard] for network connections.}
@ -451,12 +470,6 @@ collection libraries (including
@scheme[make-evalautor] for more information.}
@defparam[sandbox-exit-handler handler (any/c . -> . any)]{
A parameter that determines the initial @scheme[(exit-handler)] for
sandboxed evaluations. The default handler simply throws an error.}
@defparam[sandbox-network-guard proc
(symbol?
(or/c (and/c string? immutable?) #f)
@ -469,6 +482,14 @@ default @scheme[sandbox-security-guard]. The default forbids all
network connection.}
@defparam[sandbox-exit-handler handler (any/c . -> . any)]{
A parameter that determines the initial @scheme[(exit-handler)] for
sandboxed evaluations. The default kills the evaluator with an
appropriate error message (see
@scheme[exn:fail:sandbox-terminated-reason]).}
@defparam[sandbox-memory-limit limit (or/c exact-nonnegative-integer? #f)]{
A parameter that determines the total memory limit on the sandbox.
@ -495,8 +516,14 @@ is @scheme[(list 30 20)].
Note that these limits apply to the creation of the sandbox
environment too --- even @scheme[(make-evaluator 'scheme/base)] can
fail if the limits are strict enough. Therefore, to avoid surprises
you need to catch errors that happen when the sandbox is created.
fail if the limits are strict enough. For example,
@schemeblock[
(parameterize ([sandbox-eval-limits '(0.25 5)])
(make-evaluator 'scheme/base '(sleep 2)))
]
will throw an error instead of creating an evaluator. Therefore, to
avoid surprises you need to catch errors that happen when the sandbox
is created.
When limits are set, @scheme[call-with-limits] (see below) is wrapped
around each use of the evaluator, so consuming too much time or memory
@ -545,14 +572,26 @@ then, assuming sufficiently small limits,
@defparam[sandbox-make-inspector make (-> inspector?)]{
A parameter that determines the procedure used to create the inspector
for sandboxed evaluation. The procedure is called when initializing an
evaluator, and the default parameter value is @scheme[make-inspector].}
for sandboxed evaluation. The procedure is called when initializing
an evaluator, and the default parameter value is
@scheme[make-inspector].}
@defparam[sandbox-make-code-inspector make (-> inspector?)]{
A parameter that determines the procedure used to create the code
inspector for sandboxed evaluation. The procedure is called when
initializing an evaluator, and the default parameter value is
@scheme[make-inspector].}
@defparam[sandbox-make-logger make (-> logger?)]{
A parameter that determines the procedure used to create the logger
for sandboxed evaluation. The procedure is called when initializing an
evaluator, and the default parameter value is @scheme[current-logger].}
for sandboxed evaluation. The procedure is called when initializing
an evaluator, and the default parameter value is
@scheme[current-logger]. This means that it is not creating a new
logger (this might change in the future).}
@; ----------------------------------------------------------------------
@ -686,7 +725,17 @@ used for evaluating expressions.
This is usually similar to @scheme[(evaluator (list thunk))], except
that this relies on the common meaning of list expressions as function
application (which is not true in all languages), and it relies on
MzScheme's @scheme[eval] forgiving a non-S-expression input.}
MzScheme's @scheme[eval] forgiving a non-S-expression input. In
addition, you can avoid some of the sandboxed restrictions by using
your own permissions, for example,
@schemeblock[
(let ([guard (current-security-guard)])
(call-in-sandbox-context
(lambda ()
(parameterize ([current-security-guard guard])
(code:comment #, @t{can access anything you want here})
))))
]}
@; ----------------------------------------------------------------------

View File

@ -80,7 +80,7 @@
"(define (plus1 x) x)"
"(define (loop) (loop))"
"(define (memory x) (make-vector x))")))
(set-eval-limits ev 1 3)
(set-eval-limits ev 0.5 5)
--eval--
x => 1
(id 1) => 1
@ -102,7 +102,7 @@
(loop) =err> "out of time"
--top--
(when (custodian-memory-accounting-available?)
(t --eval-- (memory 1000000) =err> "out of memory"))
(t --eval-- (memory 3000000) =err> "out of memory"))
;; test parameter settings (tricky to get this right since
;; with-limits runs stuff in a different thread)
(set-eval-limits ev #f #f)
@ -130,12 +130,30 @@
(thread (lambda () (sleep 1) (break-evaluator ev)))
--eval--
(sleep 2) =err> "user break"
(printf "x = ~s\n" x) => (void)
;; termination
--eval--
(printf "x = ~s\n" x) => (void)
,eof =err> "terminated"
x =err> "terminated"
,eof =err> "terminated"
,eof =err> "terminated .eof.$"
123 =err> "terminated .eof.$"
,eof =err> "terminated .eof.$"
;; other termination messages
--top-- (set! ev (make-evaluator 'scheme/base)) (kill-evaluator ev)
--eval-- 123 =err> "terminated .evaluator-killed.$"
;; eval-limits apply to the sandbox creation too
--top--
(set! ev (parameterize ([sandbox-eval-limits '(0.25 5)])
(make-evaluator 'scheme/base '(sleep 2))))
=err> "out of time"
(when (custodian-memory-accounting-available?)
(t --top--
(set! ev (parameterize ([sandbox-eval-limits '(0.25 2)])
(make-evaluator 'scheme/base
'(define a (for/list ([i (in-range 10)])
(collect-garbage)
(make-string 1000))))))
=err> "out of memory"))
;; i/o
--top--
@ -186,9 +204,9 @@
--top--
(kill-evaluator ev) => (void)
--eval--
x =err> "terminated"
y =err> "terminated"
,eof =err> "terminated"
x =err> "terminated .evaluator-killed.$"
y =err> "terminated .evaluator-killed.$"
,eof =err> "terminated .evaluator-killed.$"
--top--
(let-values ([(i1 o1) (make-pipe)] [(i2 o2) (make-pipe)])
;; o1 -> i1 -ev-> o2 -> i2
@ -401,54 +419,58 @@
(set! ev (parameterize ([sandbox-eval-limits #f])
(make-evaluator 'scheme/base)))
--eval--
(kill-thread (current-thread)) =err> "terminated"
(kill-thread (current-thread)) =err> "terminated .thread-killed.$"
--top--
(set! ev (parameterize ([sandbox-eval-limits #f])
(make-evaluator 'scheme/base)))
--eval--
(custodian-shutdown-all (current-custodian)) =err> "terminated"
(custodian-shutdown-all (current-custodian))
=err> "terminated .custodian-shutdown.$"
--top--
;; also happens when it's done directly
(set! ev (parameterize ([sandbox-eval-limits #f])
(make-evaluator 'scheme/base)))
(call-in-sandbox-context ev (lambda () (kill-thread (current-thread))))
=err> "terminated"
=err> "terminated .thread-killed.$"
(set! ev (parameterize ([sandbox-eval-limits #f])
(make-evaluator 'scheme/base)))
(call-in-sandbox-context ev
(lambda () (custodian-shutdown-all (current-custodian))))
=err> "terminated"
=err> "terminated .custodian-shutdown.$"
--top--
;; now make sure it works with per-expression limits too
(set! ev (make-evaluator 'scheme/base))
--eval--
(kill-thread (current-thread)) =err> "terminated"
(kill-thread (current-thread)) =err> "terminated .thread-killed.$"
--top--
(set! ev (make-evaluator 'scheme/base))
--eval--
(custodian-shutdown-all (current-custodian)) =err> "terminated"
(custodian-shutdown-all (current-custodian))
=err> "terminated .custodian-shutdown.$"
--top--
(set! ev (make-evaluator 'scheme/base))
(call-in-sandbox-context ev (lambda () (kill-thread (current-thread))))
=err> "terminated"
=err> "terminated .thread-killed.$"
(set! ev (make-evaluator 'scheme/base))
(call-in-sandbox-context ev
(lambda () (custodian-shutdown-all (current-custodian))))
=err> "terminated"
=err> "terminated .custodian-shutdown.$"
;; when an expression is out of memory, the sandbox should stay alive
--top--
(set! ev (parameterize ([sandbox-eval-limits '(2 5)]
[sandbox-memory-limit 100])
(make-evaluator 'scheme/base)))
--eval--
(define a '())
(define b 1)
(for ([i (in-range 20)])
(set! a (cons (make-bytes 500000) a))
(collect-garbage))
=err> "out of memory"
b => 1
(when (custodian-memory-accounting-available?)
(t --top--
(set! ev (parameterize ([sandbox-eval-limits '(2 5)]
[sandbox-memory-limit 100])
(make-evaluator 'scheme/base)))
--eval--
(define a '())
(define b 1)
(for ([i (in-range 20)])
(set! a (cons (make-bytes 500000) a))
(collect-garbage))
=err> "out of memory"
b => 1))
))

View File

@ -103,7 +103,7 @@ Represents an element.}
Returns @scheme[#t] if @scheme[v] is a @scheme[pcdata] instance,
@scheme[element] instance, an @scheme[entity] instance,
@scheme[comment], or @scheme[pcdata] instance.}
@scheme[comment], or @scheme[cdata] instance.}
@defstruct[(attribute source) ([name symbol?] [value string?])]{

View File

@ -45,7 +45,7 @@ static void *print_out_pointer(const char *prefix, void *p,
trace_page_t *page;
const char *what;
page = find_page(p);
page = pagemap_find_page(GC->page_maps, p);
if (!page || (trace_page_type(page) == TRACE_PAGE_BAD)) {
GCPRINT(GCOUTF, "%s??? %p\n", prefix, p);
return NULL;
@ -94,7 +94,7 @@ static void print_traced_objects(int path_length_limit,
GC_print_tagged_value_proc print_tagged_value)
{
int i;
avoid_collection++;
GC->dumping_avoid_collection++;
GCPRINT(GCOUTF, "Begin Trace\n");
for (i = 0; i < found_object_count; i++) {
void *p;
@ -107,5 +107,5 @@ static void print_traced_objects(int path_length_limit,
}
}
GCPRINT(GCOUTF, "End Trace\n");
--avoid_collection;
--GC->dumping_avoid_collection;
}

View File

@ -934,7 +934,7 @@ static void backtrace_new_page(NewGC *gc, mpage *page)
static void free_backtrace(struct mpage *page)
{
free_pages(page->backtrace, APAGE_SIZE);
free_pages(GC, page->backtrace, APAGE_SIZE);
}
static void *bt_source;
@ -1590,6 +1590,11 @@ void GC_register_traversers(short tag, Size_Proc size, Mark_Proc mark,
mark_tag = BTC_get_redirect_tag(gc, mark_tag);
#endif
#if MZ_GC_BACKTRACE
/* Keep tagged objects in tagged space: */
atomic = 0;
#endif
gc->mark_table[mark_tag] = atomic ? (Mark_Proc)PAGE_ATOMIC : mark;
gc->fixup_table[tag] = fixup;
}
@ -2145,7 +2150,7 @@ static void mark_backpointers(NewGC *gc)
pagemap_add(pagemap, work);
if(work->big_page) {
work->big_page = 2;
push_ptr(PPTR(NUM(work->addr) + PREFIX_SIZE));
push_ptr(PPTR(NUM(work->addr) + PREFIX_SIZE + sizeof(struct objhead)));
} else {
if(work->page_type != PAGE_ATOMIC) {
void **start = PPTR(NUM(work->addr) + PREFIX_SIZE);

File diff suppressed because it is too large Load Diff

View File

@ -123,6 +123,8 @@ static Scheme_Object *write_toplevel(Scheme_Object *obj);
static Scheme_Object *read_toplevel(Scheme_Object *obj);
static Scheme_Object *write_variable(Scheme_Object *obj);
static Scheme_Object *read_variable(Scheme_Object *obj);
static Scheme_Object *write_module_variable(Scheme_Object *obj);
static Scheme_Object *read_module_variable(Scheme_Object *obj);
static Scheme_Object *write_local(Scheme_Object *obj);
static Scheme_Object *read_local(Scheme_Object *obj);
static Scheme_Object *read_local_unbox(Scheme_Object *obj);
@ -561,8 +563,8 @@ static void make_kernel_env(void)
scheme_install_type_reader(scheme_toplevel_type, read_toplevel);
scheme_install_type_writer(scheme_variable_type, write_variable);
scheme_install_type_reader(scheme_variable_type, read_variable);
scheme_install_type_writer(scheme_module_variable_type, write_variable);
scheme_install_type_reader(scheme_module_variable_type, read_variable);
scheme_install_type_writer(scheme_module_variable_type, write_module_variable);
scheme_install_type_reader(scheme_module_variable_type, read_module_variable);
scheme_install_type_writer(scheme_local_type, write_local);
scheme_install_type_reader(scheme_local_type, read_local);
scheme_install_type_writer(scheme_local_unbox_type, write_local);
@ -3319,7 +3321,7 @@ void scheme_optimize_info_done(Optimize_Info *info)
Resolve_Prefix *scheme_resolve_prefix(int phase, Comp_Prefix *cp, int simplify)
{
Resolve_Prefix *rp;
Scheme_Object **tls, **stxes, *simplify_cache;
Scheme_Object **tls, **stxes, *simplify_cache, *m;
Scheme_Hash_Table *ht;
int i;
@ -3344,7 +3346,15 @@ Resolve_Prefix *scheme_resolve_prefix(int phase, Comp_Prefix *cp, int simplify)
if (ht) {
for (i = 0; i < ht->size; i++) {
if (ht->vals[i]) {
tls[SCHEME_TOPLEVEL_POS(ht->vals[i])] = ht->keys[i];
m = ht->keys[i];
if (SAME_TYPE(SCHEME_TYPE(m), scheme_module_variable_type)) {
if (SCHEME_FALSEP(((Scheme_Modidx *)((Module_Variable *)m)->modidx)->base)
&& SCHEME_FALSEP(((Scheme_Modidx *)((Module_Variable *)m)->modidx)->path)) {
/* Reduce self-referece to just a symbol: */
m = ((Module_Variable *)m)->sym;
}
}
tls[SCHEME_TOPLEVEL_POS(ht->vals[i])] = m;
}
}
}
@ -4941,92 +4951,54 @@ static Scheme_Object *read_toplevel(Scheme_Object *obj)
}
static Scheme_Object *write_variable(Scheme_Object *obj)
/* WARNING: phase-0 module variables and #%kernel references
are handled in print.c, instead */
/* #%kernel references are handled in print.c, instead */
{
if (SAME_TYPE(scheme_variable_type, SCHEME_TYPE(obj))) {
Scheme_Object *sym;
Scheme_Env *home;
Scheme_Module *m;
Scheme_Object *sym;
Scheme_Env *home;
Scheme_Module *m;
sym = (Scheme_Object *)(SCHEME_VAR_BUCKET(obj))->key;
sym = (Scheme_Object *)(SCHEME_VAR_BUCKET(obj))->key;
home = ((Scheme_Bucket_With_Home *)obj)->home;
m = home->module;
home = ((Scheme_Bucket_With_Home *)obj)->home;
m = home->module;
/* If we get a writeable variable (instead of a module variable),
it must be a reference to a module referenced directly by its
a symbolic name (i.e., no path). */
/* If we get a writeable variable (instead of a module variable),
it must be a reference to a module referenced directly by its
a symbolic name (i.e., no path). */
if (m) {
sym = scheme_make_pair(m->modname, sym);
if (home->mod_phase)
sym = scheme_make_pair(scheme_make_integer(home->mod_phase), sym);
}
return sym;
} else {
Module_Variable *mv = (Module_Variable *)obj;
return scheme_make_pair(scheme_make_integer(mv->mod_phase),
scheme_make_pair(mv->modidx,
mv->sym));
if (m) {
sym = scheme_make_pair(m->modname, sym);
if (home->mod_phase)
sym = scheme_make_pair(scheme_make_integer(home->mod_phase), sym);
}
return sym;
}
static Scheme_Object *read_variable(Scheme_Object *obj)
/* WARNING: phase-0 module variables and #%kernel references
are handled in read.c, instead */
/* #%kernel references are handled in read.c, instead */
{
Scheme_Env *env;
env = scheme_get_env(NULL);
if (!SCHEME_SYMBOLP(obj)) {
/* Find variable from module. */
Scheme_Object *modname, *varname;
int mod_phase = 0;
if (!SCHEME_PAIRP(obj)) return NULL;
modname = SCHEME_CAR(obj);
if (SCHEME_INTP(modname)) {
mod_phase = SCHEME_INT_VAL(modname);
if (mod_phase != 1) return NULL;
obj = SCHEME_CDR(obj);
if (!SCHEME_PAIRP(obj)) return NULL;
modname = SCHEME_CAR(obj);
}
varname = SCHEME_CDR(obj);
if (SAME_OBJ(modname, kernel_symbol) && !mod_phase) {
return (Scheme_Object *)scheme_global_bucket(varname, scheme_get_kernel_env());
} else {
Module_Variable *mv;
Scheme_Object *insp;
insp = scheme_get_param(scheme_current_config(), MZCONFIG_CODE_INSPECTOR);
mv = MALLOC_ONE_TAGGED(Module_Variable);
mv->so.type = scheme_module_variable_type;
mv->modidx = modname;
mv->sym = varname;
mv->insp = insp;
mv->pos = -1;
mv->mod_phase = mod_phase;
return (Scheme_Object *)mv;
}
}
if (!SCHEME_SYMBOLP(obj)) return NULL;
return (Scheme_Object *)scheme_global_bucket(obj, env);
}
static Scheme_Object *write_module_variable(Scheme_Object *obj)
{
scheme_signal_error("module variables should have been handled in print.c");
return NULL;
}
static Scheme_Object *read_module_variable(Scheme_Object *obj)
{
scheme_signal_error("module variables should have been handled in read.c");
return NULL;
}
static Scheme_Object *write_local(Scheme_Object *obj)
{
return scheme_make_integer(SCHEME_LOCAL_POS(obj));
@ -5128,9 +5100,16 @@ static Scheme_Object *read_resolve_prefix(Scheme_Object *obj)
if (SCHEME_FALSEP(stx)) {
stx = NULL;
} else if (SCHEME_RPAIRP(stx)) {
rp->delay_info = (struct Scheme_Load_Delay *)SCHEME_CDR(stx);
rp->delay_refcount++;
struct Scheme_Load_Delay *d;
Scheme_Object *pr;
d = (struct Scheme_Load_Delay *)SCHEME_CDR(stx);
stx = SCHEME_CAR(stx);
pr = rp->delay_info_rpair;
if (!pr) {
pr = scheme_make_raw_pair(scheme_make_integer(0), (Scheme_Object *)d);
rp->delay_info_rpair = pr;
}
SCHEME_CAR(pr) = scheme_make_integer(SCHEME_INT_VAL(SCHEME_CAR(pr)) + 1);
} else {
if (!SCHEME_STXP(stx)) return NULL;
}

View File

@ -1721,20 +1721,23 @@ Scheme_Object *scheme_make_syntax_compiled(int idx, Scheme_Object *data)
static Scheme_Object *link_module_variable(Scheme_Object *modidx,
Scheme_Object *varname,
Scheme_Object *insp,
int check_access, Scheme_Object *insp,
int pos, int mod_phase,
Scheme_Env *env)
Scheme_Env *env,
Scheme_Object **exprs, int which)
{
Scheme_Object *modname;
Scheme_Env *menv;
int self = 0;
/* If it's a name id, resolve the name. */
modname = scheme_module_resolve(modidx, 1);
if (env->module && SAME_OBJ(env->module->modname, modname)
&& (env->mod_phase == mod_phase))
&& (env->mod_phase == mod_phase)) {
self = 1;
menv = env;
else {
} else {
menv = scheme_module_access(modname, env, mod_phase);
if (!menv && env->phase) {
@ -1757,22 +1760,57 @@ static Scheme_Object *link_module_variable(Scheme_Object *modidx,
return NULL;
}
if (!SAME_OBJ(menv, env)) {
if (check_access && !SAME_OBJ(menv, env)) {
varname = scheme_check_accessible_in_module(menv, insp, NULL, varname, NULL, NULL,
insp, pos, 0, NULL, env);
}
}
if (exprs) {
if (self) {
exprs[which] = varname;
} else {
if (mod_phase != 0)
modname = scheme_make_pair(modname, scheme_make_integer(mod_phase));
modname = scheme_make_pair(varname, modname);
exprs[which] = modname;
}
}
return (Scheme_Object *)scheme_global_bucket(varname, menv);
}
static Scheme_Object *link_toplevel(Scheme_Object *expr, Scheme_Env *env,
static Scheme_Object *link_toplevel(Scheme_Object **exprs, int which, Scheme_Env *env,
Scheme_Object *src_modidx,
Scheme_Object *dest_modidx)
{
if (SCHEME_SYMBOLP(expr)) {
Scheme_Object *expr = exprs[which];
if (SCHEME_FALSEP(expr)) {
/* See scheme_make_environment_dummy */
return (Scheme_Object *)scheme_global_bucket(begin_symbol, env);
} else if (SCHEME_PAIRP(expr) || SCHEME_SYMBOLP(expr)) {
/* Simplified module reference */
Scheme_Object *modname, *varname;
int mod_phase = 0;
if (SCHEME_SYMBOLP(expr)) {
varname = expr;
modname = env->module->modname;
mod_phase = env->mod_phase;
} else {
varname = SCHEME_CAR(expr);
modname = SCHEME_CDR(expr);
if (SCHEME_PAIRP(modname)) {
mod_phase = SCHEME_INT_VAL(SCHEME_CDR(modname));
modname = SCHEME_CAR(modname);
}
}
return link_module_variable(modname,
varname,
0, NULL,
-1, mod_phase,
env,
NULL, 0);
} else if (SAME_TYPE(SCHEME_TYPE(expr), scheme_variable_type)) {
Scheme_Bucket_With_Home *b = (Scheme_Bucket_With_Home *)expr;
@ -1781,18 +1819,20 @@ static Scheme_Object *link_toplevel(Scheme_Object *expr, Scheme_Env *env,
else
return link_module_variable(b->home->module->modname,
(Scheme_Object *)b->bucket.bucket.key,
b->home->module->insp,
1, b->home->module->insp,
-1, b->home->mod_phase,
env);
env,
exprs, which);
} else {
Module_Variable *mv = (Module_Variable *)expr;
return link_module_variable(scheme_modidx_shift(mv->modidx,
src_modidx,
dest_modidx),
mv->sym, mv->insp,
src_modidx,
dest_modidx),
mv->sym, 1, mv->insp,
mv->pos, mv->mod_phase,
env);
env,
exprs, which);
}
}
@ -8589,6 +8629,7 @@ static void *eval_k(void)
v = _scheme_eval_linked_expr_wp(v, p);
} else if (SAME_TYPE(SCHEME_TYPE(v), scheme_compilation_top_type)) {
Scheme_Compilation_Top *top = (Scheme_Compilation_Top *)v;
Resolve_Prefix *rp;
int depth;
depth = top->max_let_depth + scheme_prefix_depth(top->prefix);
@ -8604,6 +8645,9 @@ static void *eval_k(void)
if (use_jit)
v = scheme_jit_expr(v);
else
v = scheme_eval_clone(v);
rp = scheme_prefix_eval_clone(top->prefix);
save_runstack = scheme_push_prefix(env, top->prefix, NULL, NULL, 0, env->phase);
@ -9689,6 +9733,60 @@ local_eval(int argc, Scheme_Object **argv)
return scheme_void;
}
/*========================================================================*/
/* cloning prefix information */
/*========================================================================*/
Scheme_Object *scheme_eval_clone(Scheme_Object *expr)
{
/* Clone as much as necessary of `expr' so that prefixes are
cloned. Cloned prefixes, in turn, can be updated by linking to
reduce the overhead of cross-module references. */
if (SAME_TYPE(SCHEME_TYPE(expr), scheme_syntax_type)) {
int kind;
Scheme_Object *orig, *naya;
kind = SCHEME_PINT_VAL(expr);
orig = SCHEME_IPTR_VAL(expr);
switch (kind) {
case MODULE_EXPD:
naya = scheme_module_eval_clone(orig);
break;
case DEFINE_SYNTAX_EXPD:
case DEFINE_FOR_SYNTAX_EXPD:
naya = scheme_syntaxes_eval_clone(orig);
break;
default:
naya = orig;
break;
}
if (SAME_OBJ(orig, naya))
return expr;
return scheme_make_syntax_resolved(kind, naya);
} else
return expr;
}
Resolve_Prefix *scheme_prefix_eval_clone(Resolve_Prefix *rp)
{
Resolve_Prefix *naya;
Scheme_Object **tls;
if (!rp->num_toplevels)
return rp;
naya = MALLOC_ONE_TAGGED(Resolve_Prefix);
memcpy(naya, rp, sizeof(Resolve_Prefix));
tls = MALLOC_N(Scheme_Object*, rp->num_toplevels);
memcpy(tls, rp->toplevels, sizeof(Scheme_Object *) * rp->num_toplevels);
naya->toplevels = tls;
return naya;
}
/*========================================================================*/
/* creating/pushing prefix for top-levels and syntax objects */
/*========================================================================*/
@ -9725,7 +9823,7 @@ Scheme_Object **scheme_push_prefix(Scheme_Env *genv, Resolve_Prefix *rp,
for (i = 0; i < rp->num_toplevels; i++) {
v = rp->toplevels[i];
if (genv)
v = link_toplevel(rp->toplevels[i], genv, src_modidx, now_modidx);
v = link_toplevel(rp->toplevels, i, genv, src_modidx, now_modidx);
a[i] = v;
}
@ -9733,7 +9831,7 @@ Scheme_Object **scheme_push_prefix(Scheme_Env *genv, Resolve_Prefix *rp,
i = rp->num_toplevels;
v = scheme_stx_phase_shift_as_rename(now_phase - src_phase, src_modidx, now_modidx,
genv ? genv->export_registry : NULL);
if (v || rp->delay_info) {
if (v || (rp->delay_info_rpair && SCHEME_CDR(rp->delay_info_rpair))) {
/* Put lazy-shift info in a[i]: */
Scheme_Object **ls;
ls = MALLOC_N(Scheme_Object *, 2);
@ -9926,15 +10024,17 @@ int scheme_validate_rator_wants_box(Scheme_Object *app_rator, int pos,
int num_toplevels, int num_stxes, int num_lifts)
{
Scheme_Closure_Data *data = NULL;
Scheme_Type ty;
while (1) {
if (SAME_TYPE(SCHEME_TYPE(app_rator), scheme_closure_type)) {
ty = SCHEME_TYPE(app_rator);
if (SAME_TYPE(ty, scheme_closure_type)) {
data = SCHEME_COMPILED_CLOS_CODE(app_rator);
break;
} else if (SAME_TYPE(SCHEME_TYPE(app_rator), scheme_unclosed_procedure_type)) {
} else if (SAME_TYPE(ty, scheme_unclosed_procedure_type)) {
data = (Scheme_Closure_Data *)app_rator;
break;
} else if (SAME_TYPE(SCHEME_TYPE(app_rator), scheme_toplevel_type)) {
} else if (SAME_TYPE(ty, scheme_toplevel_type)) {
int p;
p = SCHEME_TOPLEVEL_POS(app_rator);
while (1) {

View File

@ -3942,6 +3942,9 @@ void scheme_run_module_exptime(Scheme_Env *menv, int set_ns)
for_stx = SCHEME_TRUEP(SCHEME_VEC_ELS(e)[4]);
e = SCHEME_VEC_ELS(e)[1];
if (SCHEME_SYMBOLP(names))
names = scheme_make_pair(names, scheme_null);
eval_exptime(names, scheme_list_length(names), e, exp_env, rhs_env,
rp, let_depth, 1, (for_stx ? for_stx_globals : syntax), for_stx,
NULL);
@ -4602,7 +4605,7 @@ module_execute(Scheme_Object *data)
return scheme_void;
}
static Scheme_Object *rebuild_et_vec(Scheme_Object *naya, Scheme_Object *vec)
static Scheme_Object *rebuild_et_vec(Scheme_Object *naya, Scheme_Object *vec, Resolve_Prefix *rp)
{
Scheme_Object *vec2;
int i;
@ -4613,23 +4616,35 @@ static Scheme_Object *rebuild_et_vec(Scheme_Object *naya, Scheme_Object *vec)
SCHEME_VEC_ELS(vec2)[i] = SCHEME_VEC_ELS(vec)[i];
}
SCHEME_VEC_ELS(vec2)[1] = naya;
SCHEME_VEC_ELS(vec2)[3] = (Scheme_Object *)rp;
return vec2;
}
static Scheme_Object *jit_vector(Scheme_Object *orig_l, int in_vec)
static Scheme_Object *jit_vector(Scheme_Object *orig_l, int in_vec, int jit)
{
Scheme_Object *orig, *naya = NULL;
Resolve_Prefix *orig_rp, *rp;
int i, cnt;
cnt = SCHEME_VEC_SIZE(orig_l);
for (i = 0; i < cnt; i++) {
orig = SCHEME_VEC_ELS(orig_l)[i];
if (in_vec)
if (in_vec) {
orig_rp = (Resolve_Prefix *)SCHEME_VEC_ELS(orig)[3];
rp = scheme_prefix_eval_clone(orig_rp);
orig = SCHEME_VEC_ELS(orig)[1];
} else {
orig_rp = rp = NULL;
}
naya = scheme_jit_expr(orig);
if (!SAME_OBJ(orig, naya))
if (jit)
naya = scheme_jit_expr(orig);
else
naya = orig;
if (!SAME_OBJ(orig, naya)
|| !SAME_OBJ(orig_rp, rp))
break;
}
@ -4641,16 +4656,27 @@ static Scheme_Object *jit_vector(Scheme_Object *orig_l, int in_vec)
SCHEME_VEC_ELS(new_l)[j] = SCHEME_VEC_ELS(orig_l)[j];
}
if (in_vec)
naya = rebuild_et_vec(naya, SCHEME_VEC_ELS(orig_l)[i]);
naya = rebuild_et_vec(naya, SCHEME_VEC_ELS(orig_l)[i], rp);
SCHEME_VEC_ELS(new_l)[i] = naya;
for (i++; i < cnt; i++) {
orig = SCHEME_VEC_ELS(orig_l)[i];
if (in_vec)
orig = SCHEME_VEC_ELS(orig)[1];
naya = scheme_jit_expr(orig);
if (in_vec) {
if (!SAME_OBJ(orig, naya))
naya = rebuild_et_vec(naya, SCHEME_VEC_ELS(orig_l)[i]);
orig_rp = (Resolve_Prefix *)SCHEME_VEC_ELS(orig)[3];
rp = scheme_prefix_eval_clone(orig_rp);
orig = SCHEME_VEC_ELS(orig)[1];
} else {
orig_rp = rp = NULL;
}
if (jit)
naya = scheme_jit_expr(orig);
else
naya = orig;
if (in_vec) {
if (!SAME_OBJ(orig, naya)
|| !SAME_OBJ(rp, orig_rp))
naya = rebuild_et_vec(naya, SCHEME_VEC_ELS(orig_l)[i], rp);
else
naya = SCHEME_VEC_ELS(orig_l)[i];
}
@ -4661,25 +4687,44 @@ static Scheme_Object *jit_vector(Scheme_Object *orig_l, int in_vec)
return orig_l;
}
static Scheme_Object *module_jit(Scheme_Object *data)
static Scheme_Object *do_module_clone(Scheme_Object *data, int jit)
{
Scheme_Module *m = (Scheme_Module *)data;
Scheme_Object *l1, *l2;
Resolve_Prefix *rp;
rp = scheme_prefix_eval_clone(m->prefix);
l1 = jit_vector(m->body, 0);
l2 = jit_vector(m->et_body, 1);
if (jit)
l1 = jit_vector(m->body, 0, jit);
else
l1 = m->body;
l2 = jit_vector(m->et_body, 1, jit);
if (SAME_OBJ(l1, m->body) && SAME_OBJ(l2, m->body))
if (SAME_OBJ(l1, m->body)
&& SAME_OBJ(l2, m->body)
&& SAME_OBJ(rp, m->prefix))
return data;
m = MALLOC_ONE_TAGGED(Scheme_Module);
memcpy(m, data, sizeof(Scheme_Module));
m->body = l1;
m->et_body = l2;
m->prefix = rp;
return (Scheme_Object *)m;
}
static Scheme_Object *module_jit(Scheme_Object *data)
{
return do_module_clone(data, 1);
}
Scheme_Object *scheme_module_eval_clone(Scheme_Object *data)
{
return do_module_clone(data, 0);
}
static void module_validate(Scheme_Object *data, Mz_CPort *port,
char *stack, Validate_TLS tls,
int depth, int letlimit, int delta,
@ -6115,7 +6160,9 @@ static Scheme_Object *do_module_begin(Scheme_Object *form, Scheme_Comp_Env *env,
/* Add code with names and lexical depth to exp-time body: */
vec = scheme_make_vector(5, NULL);
SCHEME_VEC_ELS(vec)[0] = names;
SCHEME_VEC_ELS(vec)[0] = ((SCHEME_PAIRP(names) && SCHEME_NULLP(SCHEME_CDR(names)))
? SCHEME_CAR(names)
: names);
SCHEME_VEC_ELS(vec)[1] = m;
SCHEME_VEC_ELS(vec)[2] = scheme_make_integer(ri->max_let_depth);
SCHEME_VEC_ELS(vec)[3] = (Scheme_Object *)rp;
@ -6125,6 +6172,7 @@ static Scheme_Object *do_module_begin(Scheme_Object *form, Scheme_Comp_Env *env,
m = scheme_sfs(m, NULL, ri->max_let_depth);
if (ri->use_jit)
m = scheme_jit_expr(m);
rp = scheme_prefix_eval_clone(rp);
eval_exptime(names, count, m, eenv->genv, rhs_env, rp, ri->max_let_depth, 0,
(for_stx ? env->genv->exp_env->toplevel : env->genv->syntax), for_stx,

View File

@ -2191,7 +2191,7 @@ static int resolve_prefix_val_MARK(void *p) {
Resolve_Prefix *rp = (Resolve_Prefix *)p;
gcMARK(rp->toplevels);
gcMARK(rp->stxes);
gcMARK(rp->delay_info);
gcMARK(rp->delay_info_rpair);
return
gcBYTES_TO_WORDS(sizeof(Resolve_Prefix));
@ -2201,7 +2201,7 @@ static int resolve_prefix_val_FIXUP(void *p) {
Resolve_Prefix *rp = (Resolve_Prefix *)p;
gcFIXUP(rp->toplevels);
gcFIXUP(rp->stxes);
gcFIXUP(rp->delay_info);
gcFIXUP(rp->delay_info_rpair);
return
gcBYTES_TO_WORDS(sizeof(Resolve_Prefix));

View File

@ -870,7 +870,7 @@ resolve_prefix_val {
Resolve_Prefix *rp = (Resolve_Prefix *)p;
gcMARK(rp->toplevels);
gcMARK(rp->stxes);
gcMARK(rp->delay_info);
gcMARK(rp->delay_info_rpair);
size:
gcBYTES_TO_WORDS(sizeof(Resolve_Prefix));

View File

@ -2358,8 +2358,7 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht,
symtab_set(pp, mt, obj);
}
}
else if (compact && SAME_TYPE(SCHEME_TYPE(obj), scheme_module_variable_type)
&& !((Module_Variable *)obj)->mod_phase)
else if (compact && SAME_TYPE(SCHEME_TYPE(obj), scheme_module_variable_type))
{
Scheme_Object *idx;
@ -2378,7 +2377,11 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht,
print(mv->modidx, notdisplay, 1, ht, mt, pp);
}
print(mv->sym, notdisplay, 1, ht, mt, pp);
print_compact_number(pp, mv->pos);
if (((Module_Variable *)obj)->mod_phase) {
/* mod_phase must be 1 */
print_compact_number(pp, -2);
}
print_compact_number(pp, mv->pos);
symtab_set(pp, mt, obj);
}

View File

@ -4357,7 +4357,7 @@ static Scheme_Object *read_compact_svector(CPort *port, int l)
return o;
}
static int cpt_branch[256];
static unsigned char cpt_branch[256];
static Scheme_Object *read_compact(CPort *port, int use_stack);
@ -4377,8 +4377,7 @@ static Scheme_Object *read_compact(CPort *port, int use_stack)
unsigned int l;
char *s, buffer[BLK_BUF_SIZE];
int ch;
int need_car = 0, proper = 0;
Scheme_Object *v, *first = NULL, *last = NULL;
Scheme_Object *v;
#ifdef DO_STACK_CHECK
{
@ -4392,7 +4391,7 @@ static Scheme_Object *read_compact(CPort *port, int use_stack)
}
#endif
while (1) {
{
ZO_CHECK(port->pos < port->size);
ch = CP_GETC(port);
@ -4530,30 +4529,22 @@ static Scheme_Object *read_compact(CPort *port, int use_stack)
SCHEME_SET_IMMUTABLE(v);
break;
case CPT_PAIR:
if (need_car) {
{
Scheme_Object *car, *cdr;
car = read_compact(port, 0);
cdr = read_compact(port, 0);
v = scheme_make_pair(car, cdr);
} else {
need_car = 1;
continue;
}
break;
case CPT_LIST:
l = read_compact_number(port);
if (need_car) {
if (l == 1) {
Scheme_Object *car, *cdr;
car = read_compact(port, 0);
cdr = read_compact(port, 0);
v = scheme_make_pair(car, cdr);
} else
v = read_compact_list(l, 0, 0, port);
} else {
need_car = l;
continue;
}
if (l == 1) {
Scheme_Object *car, *cdr;
car = read_compact(port, 0);
cdr = read_compact(port, 0);
v = scheme_make_pair(car, cdr);
} else
v = read_compact_list(l, 0, 0, port);
break;
case CPT_VECTOR:
{
@ -4761,7 +4752,12 @@ static Scheme_Object *read_compact(CPort *port, int use_stack)
mv->modidx = mod;
mv->insp = port->insp;
mv->sym = var;
mv->pos = pos;
if (pos == -2) {
mv->mod_phase = 1;
pos = read_compact_number(port);
mv->pos = pos;
} else
mv->pos = pos;
v = (Scheme_Object *)mv;
}
@ -4887,21 +4883,15 @@ static Scheme_Object *read_compact(CPort *port, int use_stack)
{
int ppr = CPT_BETWEEN(ch, SMALL_PROPER_LIST);
l = ch - (ppr ? CPT_SMALL_PROPER_LIST_START : CPT_SMALL_LIST_START);
if (need_car) {
if (l == 1) {
Scheme_Object *car, *cdr;
car = read_compact(port, 0);
cdr = (ppr
? scheme_null
: read_compact(port, 0));
v = scheme_make_pair(car, cdr);
} else
v = read_compact_list(l, ppr, /* use_stack */ 0, port);
} else {
proper = ppr;
need_car = l;
continue;
}
if (l == 1) {
Scheme_Object *car, *cdr;
car = read_compact(port, 0);
cdr = (ppr
? scheme_null
: read_compact(port, 0));
v = scheme_make_pair(car, cdr);
} else
v = read_compact_list(l, ppr, /* use_stack */ 0, port);
}
break;
case CPT_SMALL_APPLICATION_START:
@ -4975,28 +4965,9 @@ static Scheme_Object *read_compact(CPort *port, int use_stack)
if (!v)
scheme_ill_formed_code(port);
if (need_car) {
Scheme_Object *pair;
pair = scheme_make_pair(v, scheme_null);
if (last)
SCHEME_CDR(last) = pair;
else
first = pair;
last = pair;
--need_car;
if (!need_car && proper)
break;
} else {
if (last)
SCHEME_CDR(last) = v;
break;
}
}
return first ? first : v;
return v;
}
static Scheme_Object *read_compact_list(int c, int proper, int use_stack, CPort *port)

View File

@ -1863,8 +1863,7 @@ typedef struct Resolve_Prefix
int num_toplevels, num_stxes, num_lifts;
Scheme_Object **toplevels;
Scheme_Object **stxes; /* simplified */
int delay_refcount;
struct Scheme_Load_Delay *delay_info;
Scheme_Object *delay_info_rpair; /* (rcons refcount Scheme_Load_Delay*) */
} Resolve_Prefix;
typedef struct Resolve_Info
@ -2394,6 +2393,11 @@ Scheme_Object **scheme_push_prefix(Scheme_Env *genv, Resolve_Prefix *rp,
int src_phase, int now_phase);
void scheme_pop_prefix(Scheme_Object **rs);
Scheme_Object *scheme_eval_clone(Scheme_Object *expr);
Resolve_Prefix *scheme_prefix_eval_clone(Resolve_Prefix *rp);
Scheme_Object *scheme_module_eval_clone(Scheme_Object *data);
Scheme_Object *scheme_syntaxes_eval_clone(Scheme_Object *form);
Scheme_Object *scheme_make_environment_dummy(Scheme_Comp_Env *env);
Scheme_Env *scheme_environment_from_dummy(Scheme_Object *dummy);

View File

@ -13,12 +13,12 @@
consistently.)
*/
#define MZSCHEME_VERSION "4.1.3.5"
#define MZSCHEME_VERSION "4.1.3.6"
#define MZSCHEME_VERSION_X 4
#define MZSCHEME_VERSION_Y 1
#define MZSCHEME_VERSION_Z 3
#define MZSCHEME_VERSION_W 5
#define MZSCHEME_VERSION_W 6
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)

View File

@ -1823,12 +1823,18 @@ Scheme_Object *scheme_add_rename(Scheme_Object *o, Scheme_Object *rename)
void scheme_load_delayed_syntax(struct Resolve_Prefix *rp, long i)
{
Scheme_Object *stx;
int c;
stx = scheme_load_delayed_code(SCHEME_INT_VAL(rp->stxes[i]),
rp->delay_info);
(struct Scheme_Load_Delay *)SCHEME_CDR(rp->delay_info_rpair));
rp->stxes[i] = stx;
--rp->delay_refcount;
if (!rp->delay_refcount)
rp->delay_info = NULL;
c = SCHEME_INT_VAL(SCHEME_CAR(rp->delay_info_rpair));
--c;
SCHEME_CAR(rp->delay_info_rpair) = scheme_make_integer(c);
if (!c) {
SCHEME_CDR(rp->delay_info_rpair) = NULL;
rp->delay_info_rpair = NULL;
}
}
Scheme_Object *scheme_delayed_rename(Scheme_Object **o, long i)

View File

@ -5294,29 +5294,44 @@ define_for_syntaxes_execute(Scheme_Object *form)
return do_define_syntaxes_execute(form, NULL, 1);
}
static Scheme_Object *do_define_syntaxes_jit(Scheme_Object *expr)
static Scheme_Object *do_define_syntaxes_jit(Scheme_Object *expr, int jit)
{
Scheme_Object *naya;
Resolve_Prefix *rp, *orig_rp;
Scheme_Object *naya, *rhs;
naya = scheme_jit_expr(SCHEME_VEC_ELS(expr)[0]);
rhs = SCHEME_VEC_ELS(expr)[0];
if (jit)
naya = scheme_jit_expr(rhs);
else
naya = rhs;
orig_rp = (Resolve_Prefix *)SCHEME_VEC_ELS(expr)[1];
rp = scheme_prefix_eval_clone(orig_rp);
if (SAME_OBJ(naya, expr))
if (SAME_OBJ(naya, rhs)
&& SAME_OBJ(orig_rp, rp))
return expr;
else {
expr = clone_vector(expr, 0);
SCHEME_VEC_ELS(expr)[0] = naya;
SCHEME_VEC_ELS(expr)[1] = (Scheme_Object *)rp;
return expr;
}
}
static Scheme_Object *define_syntaxes_jit(Scheme_Object *expr)
{
return do_define_syntaxes_jit(expr);
return do_define_syntaxes_jit(expr, 1);
}
static Scheme_Object *define_for_syntaxes_jit(Scheme_Object *expr)
{
return do_define_syntaxes_jit(expr);
return do_define_syntaxes_jit(expr, 1);
}
Scheme_Object *scheme_syntaxes_eval_clone(Scheme_Object *expr)
{
return do_define_syntaxes_jit(expr, 0);
}
static void do_define_syntaxes_validate(Scheme_Object *data, Mz_CPort *port,
@ -5611,10 +5626,9 @@ define_for_syntaxes_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Exp
Scheme_Object *scheme_make_environment_dummy(Scheme_Comp_Env *env)
{
/* Get a prefixed-based accessor for a dummy top-level bucket. It's
used to "link" to the right environment at run time. The `begin'
symbol is arbitrary; the top-level/prefix support handles a symbol
as a "toplevel" specially. */
return scheme_register_toplevel_in_prefix(begin_symbol, env, NULL, 0);
used to "link" to the right environment at run time. The #f as
a toplevel is handled in the prefix linker specially. */
return scheme_register_toplevel_in_prefix(scheme_false, env, NULL, 0);
}
Scheme_Env *scheme_environment_from_dummy(Scheme_Object *dummy)

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="4.1.3.5"
version="4.1.3.6"
processorArchitecture="X86"
name="Org.PLT-Scheme.MrEd"
type="win32"

View File

@ -20,8 +20,8 @@ APPLICATION ICON DISCARDABLE "mred.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,1,3,5
PRODUCTVERSION 4,1,3,5
FILEVERSION 4,1,3,6
PRODUCTVERSION 4,1,3,6
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -39,11 +39,11 @@ BEGIN
VALUE "CompanyName", "PLT Scheme Inc.\0"
VALUE "FileDescription", "PLT Scheme GUI application\0"
VALUE "InternalName", "MrEd\0"
VALUE "FileVersion", "4, 1, 3, 5\0"
VALUE "FileVersion", "4, 1, 3, 6\0"
VALUE "LegalCopyright", "Copyright © 1995-2008\0"
VALUE "OriginalFilename", "MrEd.exe\0"
VALUE "ProductName", "PLT Scheme\0"
VALUE "ProductVersion", "4, 1, 3, 5\0"
VALUE "ProductVersion", "4, 1, 3, 6\0"
END
END
BLOCK "VarFileInfo"

View File

@ -53,8 +53,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,1,3,5
PRODUCTVERSION 4,1,3,5
FILEVERSION 4,1,3,6
PRODUCTVERSION 4,1,3,6
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -70,12 +70,12 @@ BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "MzCOM Module"
VALUE "FileVersion", "4, 1, 3, 5"
VALUE "FileVersion", "4, 1, 3, 6"
VALUE "InternalName", "MzCOM"
VALUE "LegalCopyright", "Copyright 2000-2008 PLT (Paul Steckler)"
VALUE "OriginalFilename", "MzCOM.EXE"
VALUE "ProductName", "MzCOM Module"
VALUE "ProductVersion", "4, 1, 3, 5"
VALUE "ProductVersion", "4, 1, 3, 6"
END
END
BLOCK "VarFileInfo"

View File

@ -1,19 +1,19 @@
HKCR
{
MzCOM.MzObj.4.1.3.5 = s 'MzObj Class'
MzCOM.MzObj.4.1.3.6 = s 'MzObj Class'
{
CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}'
}
MzCOM.MzObj = s 'MzObj Class'
{
CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}'
CurVer = s 'MzCOM.MzObj.4.1.3.5'
CurVer = s 'MzCOM.MzObj.4.1.3.6'
}
NoRemove CLSID
{
ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class'
{
ProgID = s 'MzCOM.MzObj.4.1.3.5'
ProgID = s 'MzCOM.MzObj.4.1.3.6'
VersionIndependentProgID = s 'MzCOM.MzObj'
ForceRemove 'Programmable'
LocalServer32 = s '%MODULE%'

View File

@ -29,8 +29,8 @@ APPLICATION ICON DISCARDABLE "mzscheme.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,1,3,5
PRODUCTVERSION 4,1,3,5
FILEVERSION 4,1,3,6
PRODUCTVERSION 4,1,3,6
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -48,11 +48,11 @@ BEGIN
VALUE "CompanyName", "PLT Scheme Inc.\0"
VALUE "FileDescription", "PLT Scheme application\0"
VALUE "InternalName", "MzScheme\0"
VALUE "FileVersion", "4, 1, 3, 5\0"
VALUE "FileVersion", "4, 1, 3, 6\0"
VALUE "LegalCopyright", "Copyright <20>© 1995-2008\0"
VALUE "OriginalFilename", "mzscheme.exe\0"
VALUE "ProductName", "PLT Scheme\0"
VALUE "ProductVersion", "4, 1, 3, 5\0"
VALUE "ProductVersion", "4, 1, 3, 6\0"
END
END
BLOCK "VarFileInfo"

View File

@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,1,3,5
PRODUCTVERSION 4,1,3,5
FILEVERSION 4,1,3,6
PRODUCTVERSION 4,1,3,6
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -45,7 +45,7 @@ BEGIN
#ifdef MZSTART
VALUE "FileDescription", "PLT Scheme Launcher\0"
#endif
VALUE "FileVersion", "4, 1, 3, 5\0"
VALUE "FileVersion", "4, 1, 3, 6\0"
#ifdef MRSTART
VALUE "InternalName", "mrstart\0"
#endif
@ -60,7 +60,7 @@ BEGIN
VALUE "OriginalFilename", "MzStart.exe\0"
#endif
VALUE "ProductName", "PLT Scheme\0"
VALUE "ProductVersion", "4, 1, 3, 5\0"
VALUE "ProductVersion", "4, 1, 3, 6\0"
END
END
BLOCK "VarFileInfo"