document compiler/zo-parse and compiler/decompile
svn: r12947
This commit is contained in:
parent
0cd2537a82
commit
7aec6b8761
|
@ -23,7 +23,7 @@
|
|||
(close-output-port out)
|
||||
in)))])
|
||||
(let ([n (match v
|
||||
[(struct compilation-top (_ prefix (struct primitive (n)))) n]
|
||||
[(struct compilation-top (_ prefix (struct primval (n)))) n]
|
||||
[else #f])])
|
||||
(hash-set! table n (car b)))))
|
||||
table))
|
||||
|
@ -77,7 +77,7 @@
|
|||
lift-ids)
|
||||
(map (lambda (stx id)
|
||||
`(define ,id ,(if stx
|
||||
`(#%decode-syntax ,stx #;(stx-encoded stx))
|
||||
`(#%decode-syntax ,(stx-encoded stx))
|
||||
#f)))
|
||||
stxs stx-ids)))]
|
||||
[else (error 'decompile-prefix "huh?: ~e" a-prefix)]))
|
||||
|
@ -126,7 +126,7 @@
|
|||
`(let ()
|
||||
,@defns
|
||||
,(decompile-expr rhs globs '(#%globals) closed))))]
|
||||
[(struct sequence (forms))
|
||||
[(struct seq (forms))
|
||||
`(begin ,@(map (lambda (form)
|
||||
(decompile-form form globs stack closed))
|
||||
forms))]
|
||||
|
@ -179,7 +179,7 @@
|
|||
`(#%checked ,id)))]
|
||||
[(struct topsyntax (depth pos midpt))
|
||||
(list-ref/protect globs (+ midpt pos) 'topsyntax)]
|
||||
[(struct primitive (id))
|
||||
[(struct primval (id))
|
||||
(hash-ref primitive-table id)]
|
||||
[(struct assign (id rhs undef-ok?))
|
||||
`(set! ,(decompile-expr id globs stack closed)
|
||||
|
@ -249,7 +249,7 @@
|
|||
[(struct apply-values (proc args-expr))
|
||||
`(#%apply-values ,(decompile-expr proc globs stack closed)
|
||||
,(decompile-expr args-expr globs stack closed))]
|
||||
[(struct sequence (exprs))
|
||||
[(struct seq (exprs))
|
||||
`(begin ,@(for/list ([expr (in-list exprs)])
|
||||
(decompile-expr expr globs stack closed)))]
|
||||
[(struct beg0 (exprs))
|
||||
|
|
|
@ -7,11 +7,18 @@
|
|||
;; ----------------------------------------
|
||||
;; Structures to represent bytecode
|
||||
|
||||
(define-syntax-rule (define-form-struct id (field-id ...))
|
||||
(define-syntax-rule (define-form-struct* id id+par (field-id ...))
|
||||
(begin
|
||||
(define-struct id (field-id ...) #:transparent)
|
||||
(define-struct id+par (field-id ...) #:transparent)
|
||||
(provide (struct-out id))))
|
||||
|
||||
(define-syntax define-form-struct
|
||||
(syntax-rules ()
|
||||
[(_ (id sup) . rest)
|
||||
(define-form-struct* id (id sup) . rest)]
|
||||
[(_ id . rest)
|
||||
(define-form-struct* id id . rest)]))
|
||||
|
||||
(define-form-struct compilation-top (max-let-depth prefix code)) ; compiled code always wrapped with this
|
||||
|
||||
(define-form-struct prefix (num-lifts toplevels stxs)) ; sets up top-level and syntax-object array
|
||||
|
@ -21,43 +28,46 @@
|
|||
(define-form-struct module-variable (modidx sym pos phase)) ; direct access to exported id
|
||||
|
||||
;; In stxs of prefix:
|
||||
(define-form-struct stx (encoded)) ; todo: decode syntax objects
|
||||
(define-form-struct stx (encoded))
|
||||
|
||||
(define-form-struct mod (name self-modidx prefix provides requires body syntax-body max-let-depth))
|
||||
(define-form-struct form ())
|
||||
(define-form-struct (expr form) ())
|
||||
|
||||
(define-form-struct lam (name flags num-params rest? closure-map max-let-depth body)) ; `lambda'
|
||||
(define-form-struct closure (code gen-id)) ; a static closure (nothing to close over)
|
||||
(define-form-struct case-lam (name clauses)) ; each clause is an lam
|
||||
(define-form-struct (mod form) (name self-modidx prefix provides requires body syntax-body max-let-depth))
|
||||
|
||||
(define-form-struct let-one (rhs body)) ; pushes one value onto stack
|
||||
(define-form-struct let-void (count boxes? body)) ; create new stack slots
|
||||
(define-form-struct install-value (count pos boxes? rhs body)) ; set existing stack slot(s)
|
||||
(define-form-struct let-rec (procs body)) ; put `letrec'-bound closures into existing stack slots
|
||||
(define-form-struct boxenv (pos body)) ; box existing stack element
|
||||
(define-form-struct (lam expr) (name flags num-params rest? closure-map max-let-depth body)) ; `lambda'
|
||||
(define-form-struct (closure expr) (code gen-id)) ; a static closure (nothing to close over)
|
||||
(define-form-struct (case-lam expr) (name clauses)) ; each clause is an lam
|
||||
|
||||
(define-form-struct localref (unbox? offset clear?)) ; access local via stack
|
||||
(define-form-struct (let-one expr) (rhs body)) ; pushes one value onto stack
|
||||
(define-form-struct (let-void expr) (count boxes? body)) ; create new stack slots
|
||||
(define-form-struct (install-value expr) (count pos boxes? rhs body)) ; set existing stack slot(s)
|
||||
(define-form-struct (let-rec expr) (procs body)) ; put `letrec'-bound closures into existing stack slots
|
||||
(define-form-struct (boxenv expr) (pos body)) ; box existing stack element
|
||||
|
||||
(define-form-struct toplevel (depth pos const? ready?)) ; access binding via prefix array (which is on stack)
|
||||
(define-form-struct topsyntax (depth pos midpt)) ; access syntax object via prefix array (which is on stack)
|
||||
(define-form-struct (localref expr) (unbox? pos clear?)) ; access local via stack
|
||||
|
||||
(define-form-struct application (rator rands)) ; function call
|
||||
(define-form-struct branch (test then else)) ; `if'
|
||||
(define-form-struct with-cont-mark (key val body)) ; `with-continuation-mark'
|
||||
(define-form-struct beg0 (seq)) ; `begin0'
|
||||
(define-form-struct sequence (forms)) ; `begin'
|
||||
(define-form-struct splice (forms)) ; top-level `begin'
|
||||
(define-form-struct varref (toplevel)) ; `#%variable-reference'
|
||||
(define-form-struct assign (id rhs undef-ok?)) ; top-level or module-level set!
|
||||
(define-form-struct apply-values (proc args-expr)) ; `(call-with-values (lambda () ,args-expr) ,proc)
|
||||
(define-form-struct primitive (id)) ; direct preference to a kernel primitive
|
||||
(define-form-struct (toplevel expr) (depth pos const? ready?)) ; access binding via prefix array (which is on stack)
|
||||
(define-form-struct (topsyntax expr) (depth pos midpt)) ; access syntax object via prefix array (which is on stack)
|
||||
|
||||
(define-form-struct (application expr) (rator rands)) ; function call
|
||||
(define-form-struct (branch expr) (test then else)) ; `if'
|
||||
(define-form-struct (with-cont-mark expr) (key val body)) ; `with-continuation-mark'
|
||||
(define-form-struct (beg0 expr) (seq)) ; `begin0'
|
||||
(define-form-struct (seq form) (forms)) ; `begin'
|
||||
(define-form-struct (splice form) (forms)) ; top-level `begin'
|
||||
(define-form-struct (varref expr) (toplevel)) ; `#%variable-reference'
|
||||
(define-form-struct (assign expr) (id rhs undef-ok?)) ; top-level or module-level set!
|
||||
(define-form-struct (apply-values expr) (proc args-expr)) ; `(call-with-values (lambda () ,args-expr) ,proc)
|
||||
(define-form-struct (primval expr) (id)) ; direct preference to a kernel primitive
|
||||
|
||||
;; Definitions (top level or within module):
|
||||
(define-form-struct def-values (ids rhs))
|
||||
(define-form-struct def-syntaxes (ids rhs prefix max-let-depth))
|
||||
(define-form-struct def-for-syntax (ids rhs prefix max-let-depth))
|
||||
(define-form-struct (def-values form) (ids rhs))
|
||||
(define-form-struct (def-syntaxes form) (ids rhs prefix max-let-depth))
|
||||
(define-form-struct (def-for-syntax form) (ids rhs prefix max-let-depth))
|
||||
|
||||
;; Top-level `require'
|
||||
(define-form-struct req (reqs dummy))
|
||||
(define-form-struct (req form) (reqs dummy))
|
||||
|
||||
;; A static closure can refer directly to itself, creating a cycle
|
||||
(define-struct indirect ([v #:mutable]) #:prefab)
|
||||
|
@ -145,7 +155,7 @@
|
|||
(make-with-cont-mark key val body)]))
|
||||
|
||||
(define (read-sequence v)
|
||||
(make-sequence v))
|
||||
(make-seq v))
|
||||
|
||||
(define (read-define-values v)
|
||||
(make-def-values
|
||||
|
@ -173,7 +183,7 @@
|
|||
|
||||
(define (read-begin0 v)
|
||||
(match v
|
||||
[(struct sequence (exprs))
|
||||
[(struct seq (exprs))
|
||||
(make-beg0 exprs)]))
|
||||
|
||||
(define (read-boxenv v)
|
||||
|
@ -429,9 +439,12 @@
|
|||
;; Synatx unmarshaling
|
||||
|
||||
(define-form-struct wrapped (datum wraps certs))
|
||||
(define-form-struct lexical-rename (alist))
|
||||
(define-form-struct phase-shift (amt src dest))
|
||||
(define-form-struct module-rename (phase kind set-id unmarshals renames mark-renames plus-kern?))
|
||||
|
||||
(define-form-struct wrap ())
|
||||
(define-form-struct (lexical-rename wrap) (alist))
|
||||
(define-form-struct (phase-shift wrap) (amt src dest))
|
||||
(define-form-struct (module-rename wrap) (phase kind set-id unmarshals renames mark-renames plus-kern?))
|
||||
|
||||
(define-form-struct all-from-module (path phase src-phase exceptions prefix))
|
||||
(define-form-struct module-binding (path mod-phase import-phase id nominal-path nominal-phase nominal-id))
|
||||
|
||||
|
@ -696,7 +709,7 @@
|
|||
[read-accept-quasiquote #t])
|
||||
(read (open-input-bytes s))))]
|
||||
[(reference)
|
||||
(make-primitive (read-compact-number cp))]
|
||||
(make-primval (read-compact-number cp))]
|
||||
[(small-list small-proper-list)
|
||||
(let* ([l (- ch cpt-start)]
|
||||
[ppr (eq? cpt-tag 'small-proper-list)])
|
||||
|
|
|
@ -486,29 +486,33 @@
|
|||
(define-syntax defstruct
|
||||
(syntax-rules ()
|
||||
[(_ name fields #:mutable #:inspector #f desc ...)
|
||||
(**defstruct name fields #f #t desc ...)]
|
||||
(**defstruct name fields #f #t #f desc ...)]
|
||||
[(_ name fields #:mutable #:transparent desc ...)
|
||||
(**defstruct name fields #f #t desc ...)]
|
||||
(**defstruct name fields #f #t #f desc ...)]
|
||||
[(_ name fields #:mutable #:prefab desc ...)
|
||||
(**defstruct name fields #f #t #t desc ...)]
|
||||
[(_ name fields #:mutable desc ...)
|
||||
(**defstruct name fields #f #f desc ...)]
|
||||
(**defstruct name fields #f #f #f desc ...)]
|
||||
[(_ name fields #:inspector #f desc ...)
|
||||
(**defstruct name fields #t #t desc ...)]
|
||||
(**defstruct name fields #t #t #f desc ...)]
|
||||
[(_ name fields #:transparent desc ...)
|
||||
(**defstruct name fields #t #t desc ...)]
|
||||
(**defstruct name fields #t #t #f desc ...)]
|
||||
[(_ name fields #:prefab desc ...)
|
||||
(**defstruct name fields #t #t #t desc ...)]
|
||||
[(_ name fields desc ...)
|
||||
(**defstruct name fields #t #f desc ...)]))
|
||||
(**defstruct name fields #t #f #f desc ...)]))
|
||||
|
||||
(define-syntax-rule (**defstruct name ([field field-contract] ...) immutable?
|
||||
transparent? desc ...)
|
||||
transparent? prefab? desc ...)
|
||||
(with-togetherable-scheme-variables
|
||||
()
|
||||
()
|
||||
(*defstruct (quote-syntax/loc name) 'name
|
||||
'([field field-contract] ...)
|
||||
(list (lambda () (schemeblock0 field-contract)) ...)
|
||||
immutable? transparent? (lambda () (list desc ...)))))
|
||||
immutable? transparent? prefab? (lambda () (list desc ...)))))
|
||||
|
||||
(define (*defstruct stx-id name fields field-contracts immutable? transparent?
|
||||
(define (*defstruct stx-id name fields field-contracts immutable? transparent? prefab?
|
||||
content-thunk)
|
||||
(define (field-name f) ((if (pair? (car f)) caar car) f))
|
||||
(define (field-view f)
|
||||
|
@ -634,7 +638,9 @@
|
|||
(list flow-spacer flow-spacer
|
||||
(to-flow (make-element
|
||||
#f
|
||||
(list (to-element '#:transparent)
|
||||
(list (if prefab?
|
||||
(to-element '#:prefab)
|
||||
(to-element '#:transparent))
|
||||
(schemeparenfont ")"))))
|
||||
'cont
|
||||
'cont))]
|
||||
|
@ -652,7 +658,9 @@
|
|||
(list flow-spacer flow-spacer
|
||||
(to-flow (make-element
|
||||
#f
|
||||
(list (to-element '#:transparent)
|
||||
(list (if prefab?
|
||||
(to-element '#:prefab)
|
||||
(to-element '#:transparent))
|
||||
(schemeparenfont ")"))))
|
||||
'cont
|
||||
'cont))]
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#lang scribble/doc
|
||||
@(require scribble/manual
|
||||
"common.ss"
|
||||
(for-label scheme/base))
|
||||
(for-label scheme/base
|
||||
compiler/decompile
|
||||
(only-in compiler/zo-parse compilation-top?)))
|
||||
|
||||
@title[#:tag "decompile"]{Decompiling Bytecode}
|
||||
|
||||
|
@ -84,3 +86,18 @@ Many forms in the decompiled code, such as @scheme[module],
|
|||
syntax objects to a readable form.}
|
||||
|
||||
]
|
||||
|
||||
@; ------------------------------------------------------------
|
||||
|
||||
@section{Scheme API for Decompiling}
|
||||
|
||||
@defmodule[compiler/decompile]
|
||||
|
||||
@defproc[(decompile [top compilation-top?]) any/c]{
|
||||
|
||||
Consumes the result of parsing bytecode and returns an S-expression
|
||||
(as described above) that represents the compiled code.}
|
||||
|
||||
@; ------------------------------------------------------------
|
||||
|
||||
@include-section["zo-parse.scrbl"]
|
||||
|
|
448
collects/scribblings/mzc/zo-parse.scrbl
Normal file
448
collects/scribblings/mzc/zo-parse.scrbl
Normal file
|
@ -0,0 +1,448 @@
|
|||
#lang scribble/doc
|
||||
@(require scribble/manual
|
||||
(for-label scheme/base
|
||||
compiler/zo-parse))
|
||||
|
||||
@(define-syntax-rule (defstruct+ id fields . rest)
|
||||
(defstruct id fields #:transparent . rest))
|
||||
|
||||
@title{Scheme API for Parsing Bytecode}
|
||||
|
||||
@defmodule[compiler/zo-parse]
|
||||
|
||||
@defproc[(zo-parse [in input-port?]) compilation-top?]{
|
||||
|
||||
Parses a port (typically the result of opening a @filepath{.zo} file)
|
||||
containing byte. The parsed bytecode is returned in a
|
||||
@scheme[compilation-top] structure.
|
||||
|
||||
Beware that the structure types used to represent the bytecode are
|
||||
subject to frequent changes across PLT Scheme versons.}
|
||||
|
||||
@; --------------------------------------------------
|
||||
@section{Prefix}
|
||||
|
||||
@defstruct+[compilation-top ([max-let-depth exact-nonnegative-integer?]
|
||||
[prefix prefix?]
|
||||
[code (or/c form? any/c)])]{
|
||||
|
||||
Wraps compiled code. The @scheme[max-let-depth] field indicates the
|
||||
maximum stack depth that @scheme[code] creates (not counting the
|
||||
@scheme[prefix] array). The @scheme[prefix] field contains global
|
||||
variable, cross-module variable, and syntax-object literal
|
||||
mappings. The @scheme[code] field contains executable code; it is
|
||||
normally a @scheme[form], but a literal value is represented as
|
||||
itself.}
|
||||
|
||||
|
||||
@defstruct+[prefix ([num-lifts exact-nonnegative-integer?]
|
||||
[toplevels (listof (or/c #f symbol? global-bucket? module-variable?))]
|
||||
[stxs (listof stx?)])]{
|
||||
|
||||
Represents a closure ``prefix'' that is pushed onto the stack before
|
||||
evaluating a top-level sequence. The prefix is an array, where buckets
|
||||
holding the values for @scheme[toplevels] are first, then a bucket for
|
||||
another array if @scheme[stxs] is non-empty, then @scheme[num-lifts]
|
||||
extra buckets for lifted local procedures.
|
||||
|
||||
In @scheme[toplevels]:
|
||||
|
||||
@itemize[
|
||||
|
||||
@item{@scheme[#f] indicates a dummy variable that is used to access
|
||||
the enclosing module/namespace at run time}
|
||||
|
||||
@item{a symbol is a reference to a variable defined in the enclosing
|
||||
module}
|
||||
|
||||
@item{a @scheme[global-bucket] is a top-level variable, and it
|
||||
appears only outside of modules}
|
||||
|
||||
@item{a @scheme[module-variable] indicates a variable imported from
|
||||
another module}
|
||||
|
||||
]
|
||||
|
||||
The variable buckets and syntax objects recorded by a prefix are
|
||||
accessed by @scheme[toplevel] and @scheme[topsyntax] expression forms.}
|
||||
|
||||
|
||||
@defstruct+[global-bucket ([name symbol?])]{
|
||||
|
||||
Represents a top-level variable, and used only in a @scheme[prefix].}
|
||||
|
||||
|
||||
@defstruct+[module-variable ([modidx module-path-index?]
|
||||
[sym symbol?]
|
||||
[pos exact-integer?]
|
||||
[phase (or/c 0 1)])]{
|
||||
|
||||
Represents a top-level variable, and used only in a @scheme[prefix].
|
||||
The @scheme[pos] may record the variable's offset within its module,
|
||||
or it can be @scheme[-1] if the variable is always accessed by name.
|
||||
The @scheme[phase] indicates the phase level of the definition within
|
||||
it module.}
|
||||
|
||||
|
||||
@defstruct+[stx ([encoded wrapped?])]{
|
||||
|
||||
Wraps a syntax object in a @scheme[prefix].}
|
||||
|
||||
|
||||
@; --------------------------------------------------
|
||||
@section{Forms}
|
||||
|
||||
@defstruct+[form ()]{
|
||||
|
||||
A supertype for all forms that can appear in compiled code, except for
|
||||
literals that are represented as themselves.}
|
||||
|
||||
@defstruct+[(def-values form) ([ids (listof toplevel?)]
|
||||
[rhs (or/c expr? seq? indirect? any/c)])]{
|
||||
|
||||
Represents a @scheme[define-values] form.
|
||||
|
||||
After @scheme[rhs] is evaluated, the stack is restored to its depth
|
||||
from before evaluating @scheme[rhs].}
|
||||
|
||||
@deftogether[(
|
||||
@defstruct+[(def-syntaxes form) ([ids (listof toplevel?)]
|
||||
[rhs (or/c expr? seq? indirect? any/c)]
|
||||
[prefix prefix?]
|
||||
[max-let-depth nonnegative-exact-integer?])]
|
||||
@defstruct+[(def-for-syntax form) ([ids (listof toplevel?)]
|
||||
[rhs (or/c expr? seq? indirect? any/c)]
|
||||
[prefix prefix?]
|
||||
[max-let-depth nonnegative-exact-integer?])]
|
||||
)]{
|
||||
|
||||
Represents a @scheme[define-syntaxes] or
|
||||
@scheme[define-values-for-syntax] form. The @scheme[rhs] expression
|
||||
has its own @scheme[prefix], which is pushed before evaluating
|
||||
@scheme[rhs]; the stack is restored after obtaining the result
|
||||
values.}
|
||||
|
||||
@defstruct+[(req form) ([reqs (listof module-path?)]
|
||||
[dummy toplevel?])]{
|
||||
|
||||
Represents a top-level @scheme[require] form (but not one in a
|
||||
@scheme[module] form). The @scheme[dummy] variable is used to access
|
||||
to the top-level namespace.}
|
||||
|
||||
|
||||
@defstruct+[(mod form) ([name symbol?]
|
||||
[self-modidx module-path-index?]
|
||||
[prefix prefix?]
|
||||
[provides (listof symbol?)]
|
||||
[requires (listof (cons/c (or/c exact-integer? #f) (listof module-path-index?)))]
|
||||
[body (listof (or/c form? any/c))]
|
||||
[syntax-body (listof (or/c def-syntaxes? def-for-syntax?))]
|
||||
[max-let-depth exact-nonnegative-integer?])]{
|
||||
|
||||
Represents a @scheme[module] declaration. The @scheme[body] forms use
|
||||
@scheme[prefix], rather than any prefix in place for the module
|
||||
declaration itself (and each @scheme[syntax-body] has its own
|
||||
prefix). The @scheme[body] field contains the module's run-time code,
|
||||
and @scheme[syntax-body] contains the module's compile-time code. The
|
||||
@scheme[max-let-depth] field indicates the maximum stack depth created
|
||||
by @scheme[body] forms (not counting the @scheme[prefix] array).}
|
||||
|
||||
|
||||
@defstruct+[(seq form) ([forms (listof (or/c form? any/c))])]{
|
||||
|
||||
Represents a @scheme[begin] form, either as an expression or at the
|
||||
top level (though the latter is more commonly a @scheme[splice] form).
|
||||
When a @scheme[seq] appears in an expression position, its
|
||||
@scheme[forms] are expressions.
|
||||
|
||||
After each form in @scheme[forms] is evaluated, the stack is restored
|
||||
to its depth from before evaluating the form.}
|
||||
|
||||
|
||||
@defstruct+[(splice form) ([forms (listof (or/c form? any/c))])]{
|
||||
|
||||
Represents a top-level @scheme[begin] form where each evaluation is
|
||||
wrapped with a continuation prompt.
|
||||
|
||||
After each form in @scheme[forms] is evaluated, the stack is restored
|
||||
to its depth from before evaluating the form.}
|
||||
|
||||
|
||||
@; --------------------------------------------------
|
||||
@section{Expressions}
|
||||
|
||||
@defstruct+[(expr form) ()]{
|
||||
|
||||
A supertype for all expression forms that can appear in compiled code,
|
||||
except for literals that are represented as themselves, and except for
|
||||
@scheme[seq] (which can appear as an expression as long as it contains
|
||||
only other things that can be expressions).}
|
||||
|
||||
|
||||
@defstruct+[(lam expr) ([name (or/c symbol? vector?)]
|
||||
[flags exact-integer?]
|
||||
[num-params exact-nonnegative-integer?]
|
||||
[rest? boolean?]
|
||||
[closure-map (vectorof exact-nonnegative-integer?)]
|
||||
[max-let-depth exact-nonnegative-integer?]
|
||||
[body (or/c expr? seq? indirect? any/c)])]{
|
||||
|
||||
Represents a @scheme[lambda] form. The @scheme[name] field is a name
|
||||
for debugging purposes. The @scheme[num-params] field indicates the
|
||||
number of argumets accepted by the procedure, not counting a rest
|
||||
argument; the @scheme[rest?] field indicates whether extra arguments
|
||||
are accepted and collected into a ``rest'' variable. The
|
||||
@scheme[closure-map] field is a vector of stack positions that are
|
||||
captured when evaluating the @scheme[lambda] form to create a closure.
|
||||
|
||||
When the function is called, the rest-argument list (if any) is pushed
|
||||
onto the stack, then the normal arguments in reverse order, then the
|
||||
closure-captured values in reverse order. Thus, when @scheme[body] is
|
||||
run, the first value on the stack is the first value captured by the
|
||||
@scheme[closure-map] array, and so on.
|
||||
|
||||
The @scheme[max-let-depth] field indicates the maximum stack depth
|
||||
created by @scheme[body] (not including arguments and closure-captured
|
||||
values pushed onto the stack). The @scheme[body] field is the
|
||||
expression for the closure's body.}
|
||||
|
||||
|
||||
@defstruct+[(closure expr) ([code lam?] [gen-id symbol?])]{
|
||||
|
||||
A @scheme[lambda] form with an empty closure, which is a procedure
|
||||
constant. The procedure constant can appear multiple times in the
|
||||
graph of expressions for bytecode, and the @scheme[code] field can
|
||||
refer back to the same @scheme[closure] through an @scheme[indirect]
|
||||
for a recursive constant procedure; the @scheme[gen-id] is different
|
||||
for each such constant.}
|
||||
|
||||
|
||||
@defstruct[indirect ([v closure?]) #:mutable #:prefab]{
|
||||
|
||||
An indirection used in expression positions to form cycles.}
|
||||
|
||||
|
||||
@defstruct+[(case-lam expr) ([name (or/c symbol? vector?)]
|
||||
[clauses (listof lam?)])]{
|
||||
|
||||
Represents a @scheme[case-lambda] form as a combination of
|
||||
@scheme[lambda] forms that are tried (in order) based on the number of
|
||||
arguments given.}
|
||||
|
||||
|
||||
@defstruct+[(let-one expr) ([rhs (or/c expr? seq? indirect? any/c)]
|
||||
[body (or/c expr? seq? indirect? any/c)])]{
|
||||
|
||||
Pushes an uninitialized slot onto the stack, evaluates @scheme[rhs]
|
||||
and puts its value into the slot, and then runs @scheme[body].
|
||||
|
||||
After @scheme[rhs] is evaluated, the stack is restored to its depth
|
||||
from before evaluating @scheme[rhs]. Note that the new slot is created
|
||||
before evaluating @scheme[rhs].}
|
||||
|
||||
|
||||
@defstruct+[(let-void expr) ([count nonnegative-exact-integer?]
|
||||
[boxes? boolean?]
|
||||
[body (or/c expr? seq? indirect? any/c)])]{
|
||||
|
||||
Pushes @scheme[count] uninitialized slots onto the stack and then runs
|
||||
@scheme[body]. If @scheme[boxes?] is @scheme[#t], then the slots are
|
||||
filled with boxes that contain @|undefined-const|.}
|
||||
|
||||
|
||||
@defstruct+[(install-value expr) ([count nonnegative-exact-integer?]
|
||||
[pos nonnegative-exact-integer?]
|
||||
[boxes? boolean?]
|
||||
[rhs (or/c expr? seq? indirect? any/c)]
|
||||
[body (or/c expr? seq? indirect? any/c)])]{
|
||||
|
||||
Runs @scheme[rhs] to obtain @scheme[count] results, and installs them
|
||||
into existing slots on the stack in order, skipping the first
|
||||
@scheme[pos] stack positions. If @scheme[boxes?] is @scheme[#t], then
|
||||
the values are put into existing boxes in the stack slots.
|
||||
|
||||
After @scheme[rhs] is evaluated, the stack is restored to its depth
|
||||
from before evaluating @scheme[rhs].}
|
||||
|
||||
|
||||
@defstruct+[(let-rec expr) ([procs (listof lam?)]
|
||||
[body (or/c expr? seq? indirect? any/c)])]{
|
||||
|
||||
Represents a @scheme[letrec] form with @scheme[lambda] bindings. It
|
||||
allocates a closure shell for each @scheme[lambda] form in
|
||||
@scheme[procs], pushes them onto the stack in reverse order, fills out
|
||||
each shell's closure using the created shells, and then evaluates
|
||||
@scheme[body].}
|
||||
|
||||
|
||||
@defstruct+[(boxenv expr) ([pos nonnegative-exact-integer?]
|
||||
[body (or/c expr? seq? indirect? any/c)])]{
|
||||
|
||||
Sets the stack slot @scheme[pos] elements deep into the stack to a new
|
||||
box containing the slot's old value. This form appears when a
|
||||
@scheme[lambda] argument is mutated using @scheme[set!] within its
|
||||
body; calling the function initially pushes the value directly on the
|
||||
stack, and this form boxes the value so that it can be mutated later.}
|
||||
|
||||
|
||||
@defstruct+[(localref expr) ([unbox? boolean?]
|
||||
[pos nonnegative-exact-integer?]
|
||||
[clear? boolean?])]{
|
||||
|
||||
Represents a local-variable reference; access the value in the stack
|
||||
slot skipping the first @scheme[pos] slots. If @scheme[unbox?] is
|
||||
@scheme[#t], the stack slot contains a box, and a value is extracted
|
||||
from the box. If @scheme[clear?] is @scheme[#t], then after the value
|
||||
is obtained, the stack slot is cleared (to avoid retaining a reference
|
||||
that can prevent reclamation of the value as garbage).}
|
||||
|
||||
|
||||
@defstruct+[(toplevel expr) ([depth nonnegative-exact-integer?]
|
||||
[pos nonnegative-exact-integer?]
|
||||
[const? boolean?]
|
||||
[ready? boolean?])]{
|
||||
|
||||
Represents a reference to a top-level or imported variable via the
|
||||
@scheme[prefix] array. The @scheme[depth] field indicates the number
|
||||
of stack slots to skip to reach the prefix array, and @scheme[pos] is
|
||||
the offset into the array. If @scheme[const?] is @scheme[#t], then the
|
||||
variable will definitely have a value and the value stays constant. If
|
||||
@scheme[ready?] is @scheme[#t], then the variable will definitely have
|
||||
a value (but the value might change in the future).}
|
||||
|
||||
|
||||
@defstruct+[(topsyntax expr) ([depth nonnegative-exact-integer?]
|
||||
[pos nonnegative-exact-integer?]
|
||||
[midpt nonnegative-exact-integer?])]{
|
||||
|
||||
Represents a reference to a quoted syntax object via the
|
||||
@scheme[prefix] array. The @scheme[depth] field indicates the number
|
||||
of stack slots to skip to reach the prefix array, and @scheme[pos] is
|
||||
the offset into the array. The @scheme[midpt] value is used internally
|
||||
for lazy calculation of syntax information.}
|
||||
|
||||
|
||||
@defstruct+[(application expr) ([rator (or/c expr? seq? indirect? any/c)]
|
||||
[rands (listof (or/c expr? seq? indirect? any/c))])]{
|
||||
|
||||
Represents a function call. The @scheme[rator] field is the expression
|
||||
for the function, and @scheme[rands] are the argument
|
||||
expressions. Before any of the expressions are evaluated,
|
||||
@scheme[(length rands)] uninitialized stack slots are created (to be
|
||||
used as temporary space).}
|
||||
|
||||
|
||||
@defstruct+[(branch expr) ([test (or/c expr? seq? indirect? any/c)]
|
||||
[then (or/c expr? seq? indirect? any/c)]
|
||||
[else (or/c expr? seq? indirect? any/c)])]{
|
||||
|
||||
Represents an @scheme[if] form.
|
||||
|
||||
After @scheme[test] is evaluated, the stack is restored to its depth
|
||||
from before evaluating @scheme[test].}
|
||||
|
||||
|
||||
@defstruct+[(with-cont-mark expr) ([key (or/c expr? seq? indirect? any/c)]
|
||||
[val (or/c expr? seq? indirect? any/c)]
|
||||
[body (or/c expr? seq? indirect? any/c)])]{
|
||||
|
||||
Represents a @scheme[with-continuation-mark] expression.
|
||||
|
||||
After each of @scheme[key] and @scheme[val] is evaluated, the stack is
|
||||
restored to its depth from before evaluating @scheme[key] or
|
||||
@scheme[val].}
|
||||
|
||||
@defstruct+[(beg0 expr) ([seq (listof (or/c expr? seq? indirect? any/c))])]{
|
||||
|
||||
Represents a @scheme[begin0] expression.
|
||||
|
||||
After each expression in @scheme[seq] is evaluated, the stack is
|
||||
restored to its depth from before evaluating the expression.}
|
||||
|
||||
|
||||
@defstruct+[(varref expr) ([toplevel toplevel?])]{
|
||||
|
||||
Represents a @scheme[#%variable-reference] form.}
|
||||
|
||||
|
||||
@defstruct+[(assign expr) ([id toplevel?]
|
||||
[rhs (or/c expr? seq? indirect? any/c)]
|
||||
[undef-ok? boolean?])]{
|
||||
|
||||
Represents a @scheme[set!] expression that assigns to a top-level or
|
||||
module-level variable. (Assignments to local variables are converted
|
||||
to @scheme[install-value] expression.)
|
||||
|
||||
After @scheme[rhs] is evaluated, the stack is restored to its depth
|
||||
from before evaluating @scheme[rhs].}
|
||||
|
||||
|
||||
@defstruct+[(apply-values expr) ([proc (or/c expr? seq? indirect? any/c)]
|
||||
[args-expr (or/c expr? seq? indirect? any/c)])]{
|
||||
|
||||
Represents @scheme[(call-with-values (lambda () args-expr) proc)],
|
||||
which is handled specially by the run-time system.}
|
||||
|
||||
|
||||
@defstruct+[(primval expr) ([id symbol?])]{
|
||||
|
||||
Represents a direct reference to a variable imported from the run-time
|
||||
kernel.}
|
||||
|
||||
@; --------------------------------------------------
|
||||
@section{Syntax Objects}
|
||||
|
||||
@defstruct+[wrapped ([datum any/c]
|
||||
[wraps (listof wrap?)]
|
||||
[certs list?])]{
|
||||
|
||||
Represents a syntax object, where @scheme[wraps] contain the lexical
|
||||
information and @scheme[certs] is certificate information. When the
|
||||
@scheme[datum] part it itself compound, its pieces are wrapped, too.}
|
||||
|
||||
|
||||
@defstruct+[wrap ()]{
|
||||
|
||||
A supertype for lexical information elements.}
|
||||
|
||||
|
||||
@defstruct+[(lexical-rename wrap) ([alist (listof (cons/c identifier? identifier?))])]{
|
||||
|
||||
A local-binding mapping from symbols to binding-set names.}
|
||||
|
||||
|
||||
@defstruct+[(phase-shift wrap) ([amt exact-integer?]
|
||||
[src module-path-index?]
|
||||
[dest module-path-index?])]{
|
||||
|
||||
Shifts module bindings later in the wrap set.}
|
||||
|
||||
@defstruct+[(module-rename wrap) ([phase exact-integer?]
|
||||
[kind (or/c 'marked 'normal)]
|
||||
[set-id any/c]
|
||||
[unmarshals (listof make-all-from-module?)]
|
||||
[renames (listof module-binding?)]
|
||||
[mark-renames any/c]
|
||||
[plus-kern? boolean?])]{
|
||||
|
||||
Represents a set of module and import bindings.}
|
||||
|
||||
@defstruct+[all-from-module ([path module-path-index?]
|
||||
[phase (or/c exact-integer? #f)]
|
||||
[src-phase (or/c exact-integer? #f)]
|
||||
[exceptions (listof symbol?)]
|
||||
[prefix symbol?])]{
|
||||
|
||||
Represents a set of simple imports from one module within a
|
||||
@scheme[module-rename].}
|
||||
|
||||
@defstruct+[module-binding ([path module-path-index?]
|
||||
[mod-phase (or/c exact-integer? #f)]
|
||||
[import-phase (or/c exact-integer? #f)]
|
||||
[id symbol?]
|
||||
[nominal-path module-path-index?]
|
||||
[nominal-phase (or/c exact-integer? #f)]
|
||||
[nominal-id (or/c exact-integer? #f)])]{
|
||||
|
||||
Represents a single identifier import (i.e., the general case) within
|
||||
a @scheme[module-rename].}
|
|
@ -3301,19 +3301,19 @@ static Scheme_Object *make_struct_type(int argc, Scheme_Object **argv)
|
|||
Scheme_Object *parent = argv[1];
|
||||
if (!SCHEME_FALSEP(parent) && !((Scheme_Struct_Type *)parent)->prefab_key) {
|
||||
bad = ("make-struct-type: generative supertype disallowed"
|
||||
" for non-generative structure type with name: ");
|
||||
" for non-generative structure type with name: %S");
|
||||
} else if (!SCHEME_NULLP(props)) {
|
||||
bad = ("make-struct-type: properties disallowed"
|
||||
" for non-generative structure type with name: ");
|
||||
" for non-generative structure type with name: %S");
|
||||
} else if (proc_attr) {
|
||||
bad = ("make-struct-type: procedure specification disallowed"
|
||||
" for non-generative structure type with name: ");
|
||||
" for non-generative structure type with name: %S");
|
||||
} else if (guard) {
|
||||
bad = ("make-struct-type: guard disallowed"
|
||||
" for non-generative structure type with name: ");
|
||||
" for non-generative structure type with name: %S");
|
||||
}
|
||||
if (bad) {
|
||||
scheme_raise_exn(MZEXN_FAIL_CONTRACT, bad, inspector);
|
||||
scheme_raise_exn(MZEXN_FAIL_CONTRACT, bad, argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user