add var-ref->mod-decl-insp' and switch cur-code-insp' uses

Macros and other tools that need syntax privilege used
`(current-code-inspector)' at the module top-level to try to
capture the right code inspector at load time. It's more
consistent to instead use the enclosing module's declaration-time
inspector, and `var-ref->mod-decl-insp' provides that. The
new function works only on references to anonymous variables,
which limits access to the inspector.

The real function name is longer, of course.
This commit is contained in:
Matthew Flatt 2011-09-20 13:29:42 -06:00
parent f21187248a
commit 0197902309
44 changed files with 1090 additions and 1015 deletions

View File

@ -36,7 +36,8 @@
;; install functions that can be used later.
(define (non-valueable-prims) (procedure-calling-prims))
(define code-insp (current-code-inspector))
(define code-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define (keep-mzc-property stx-out stx)
(let ([v (syntax-property stx 'mzc-cffi)]

View File

@ -334,7 +334,8 @@
(syntax-e new-s)
old-s
old-s))]))
(define code-insp (current-code-inspector))
(define code-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define (convert stx trans? lookup-stx set-stx safe-vector-ref-stx id li in-module?
simple-constant? stop-properties)

View File

@ -37,7 +37,8 @@
(hash-for-each hash (lambda (x y) (unless (eq? x 'base) (set! covered (cons x covered)))))
(values all covered)))
(define code-insp (current-code-inspector))
(define code-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define (disarm stx)
(syntax-disarm stx code-insp))

View File

@ -254,7 +254,8 @@
[bodyl (map (lambda (b) (annotate b phase)) bodys)])
(rebuild expr (map cons bodys bodyl))))
(define orig-inspector (current-code-inspector))
(define orig-inspector (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define (rearm orig new)
(syntax-rearm new orig))

View File

@ -252,7 +252,8 @@
;; new syntax transformer be an object that carries extra information, later
;; used by `expand-fun-syntax/fun'.
(define orig-inspector (current-code-inspector))
(define orig-inspector (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define (disarm stx)
(syntax-disarm stx orig-inspector))

View File

@ -707,7 +707,8 @@
free ...)
(lambda forms body ...))]))
(define-for-syntax code-insp (current-code-inspector))
(define-for-syntax code-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define-syntax (command-lambda stx)

View File

@ -397,4 +397,5 @@
(define (disarm stx) (syntax-disarm stx code-insp))
(define (rearm old new) (syntax-rearm new old))
(define code-insp (current-code-inspector)))
(define code-insp (variable-reference->module-declaration-inspector
(#%variable-reference))))

View File

@ -12,7 +12,8 @@
scheme/base
(only-in "teachprims.rkt" [advanced-cons the-cons])))
(define code-insp (current-code-inspector))
(define code-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define shared/proc
(lambda (stx make-check-cdr undefined-expr)

View File

@ -46,7 +46,8 @@
((bound-identifier=? id (caar renames)) (car renames))
(else (stx-assoc id (cdr renames)))))
(define insp (current-code-inspector))
(define insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define (rebuild ctxt val)
(if (syntax? ctxt)

View File

@ -9,7 +9,8 @@
(provide shared)
(define-for-syntax code-insp (current-code-inspector))
(define-for-syntax code-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define undefined (letrec ([x x]) x))
(require (only-in scheme/base [cons the-cons]))

View File

@ -28,7 +28,8 @@
((char-range-arg #'#\1 #'here) (char->integer #\1))
((char-range-arg #'"1" #'here) (char->integer #\1)))
(define orig-insp (current-code-inspector))
(define orig-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define (disarm stx)
(syntax-disarm stx orig-insp))

View File

@ -11,7 +11,8 @@
(provide parse/legacy)
(define orig-insp (current-code-inspector))
(define orig-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define (parse/legacy stx)
(define (rearm new-stx) (syntax-rearm new-stx stx))

View File

@ -17,7 +17,8 @@
[(a b) #'(list a b)]
[x (identifier? #'x) #'x]))
(define orig-insp (current-code-inspector))
(define orig-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
;; parse : syntax -> Pat
;; compile stx into a pattern, using the new syntax

View File

@ -102,7 +102,8 @@
orig
orig))
(define-for-syntax code-insp (current-code-inspector))
(define-for-syntax code-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define-for-syntax (disarm* stx)
(cond
[(and (syntax? stx)

View File

@ -633,9 +633,10 @@
(syntax-property l 'method-arity-error #t))
;; `class' wants to be priviledged with respect to
;; syntax taints: save the load-time inspector and use it
;; syntax taints: save the declaration-time inspector and use it
;; to disarm syntax taints
(define method-insp (current-code-inspector))
(define method-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define (disarm stx)
(syntax-disarm stx method-insp))
(define (rearm new old)

View File

@ -5,7 +5,8 @@
(for-template scheme/base "class-events.rkt")
"define-struct.rkt")
(define insp (current-code-inspector))
(define insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define (class-syntax-protect stx)
(syntax-arm stx insp #t))

View File

@ -159,7 +159,8 @@
;; ill-formed clause...
clause]))
(define orig-insp (current-code-inspector))
(define orig-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define (for-clause-syntax-protect clause)
;; This is slightly painful. The expansion into `:do-in' involves a lot

View File

@ -5,7 +5,8 @@
(require (for-syntax racket/base
"provide-transform.rkt"))
(define-for-syntax orig-insp (current-code-inspector))
(define-for-syntax orig-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define-for-syntax (make-provide-macro proc)
(make-provide-transformer

View File

@ -42,7 +42,8 @@
[(v) v]
[(v mark) v]))
(define orig-insp (current-code-inspector))
(define orig-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
;; expand-export : stx -> (listof export)
(define (expand-export stx modes)

View File

@ -5,7 +5,8 @@
(require (for-syntax racket/base
"require-transform.rkt"))
(define-for-syntax orig-insp (current-code-inspector))
(define-for-syntax orig-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define-for-syntax (make-require-macro proc)
(make-require-transformer

View File

@ -71,7 +71,8 @@
[(v) v]
[(v mark) v]))
(define orig-insp (current-code-inspector))
(define orig-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
;; expand-import : stx bool -> (listof import)
(define (expand-import stx)

View File

@ -560,13 +560,13 @@
;; 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.rkt 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.rkt 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))
;; here -- errortrace/stacktrace.rkt will grab the declaration-tme code inspector.
;; So we grab it here too, and use it to wrap the code that invokes errortrace.
;; If errortrace/stacktrace.rkt 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 (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define (evaluate-program program limit-thunk uncovered!)
(when uncovered!

View File

@ -72,7 +72,8 @@
(define %true
(lambda (fk) fk))
(define-for-syntax orig-insp (current-code-inspector))
(define-for-syntax orig-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define-syntax (%is stx)
(syntax-case stx ()

View File

@ -201,10 +201,11 @@ With this arrangement, macro-generating macros require some care,
since the generating macro may embed syntax objects in the generated
macro that need to have the generating module's protection level,
rather than the protection level of the module that contains the
generated macro. To avoid this problem, capture the value of
@racket[(current-code-inspector)] as part of the generating macro's
expand-time code and used it to define a variant of
@racket[syntax-protect] that uses the captured inspector.
generated macro. To avoid this problem, use the module's
declaration-time inspector, which is accessible as
@racket[(variable-reference->module-declaration-inspector
(#%variable-reference))], and use it to define a variant of
@racket[syntax-protect].
For example, suppose that the @racket[go] macro is implemented through
a macro:
@ -243,7 +244,8 @@ racket
(+ n 17))
(define-for-syntax go-syntax-protect
(let ([insp (current-code-inspector)])
(let ([insp (variable-reference->module-declaration-inspector
(#%variable-reference))])
(lambda (stx) (syntax-arm stx insp))))
(define-syntax (def-go stx)
@ -269,7 +271,7 @@ prevent access from untrusted modules. Such exports should use the
Code inspectors, again, provide the mechanism for determining which
modules are trusted and which are untrusted. When a module is
declared, the value of @racket[current-code-inspector] is associated
to the module instance. When a module is instantiated (i.e., when the
to the module declaration. When a module is instantiated (i.e., when the
body of the declaration is actually executed), a sub-inspector is
created to guard the module's exports. Access to the module's
@tech{protected} exports requires a code inspector higher in the

View File

@ -423,3 +423,12 @@ for @racket[varref] is not within a module.
For a variable with a module, the result is less than the result of
@racket[(variable-reference->phase varref)] by @math{n} when the
variable is bound at @tech{phase level} @math{n} within the module.}
@defproc[(variable-reference->module-declaration-inspector [varref variable-reference?])
inspector?]{
Returns the declaration @tech{inspector} (see @secref["modprotect"])
for the module of @racket[varref], where @racket[varref] must refer to
an anonymous module variable as produced by
@racket[(#%variable-reference)].}

View File

@ -32,7 +32,8 @@ pict snip :
get-snp/poss
build-lib-pict-stx)
(define orig-inspector (current-code-inspector))
(define orig-inspector (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define orig-lcp (current-library-collection-paths))
(define tool@

View File

@ -1371,9 +1371,6 @@
; body of local
(annotate/top-level main-exp))
(define saved-code-inspector (current-code-inspector))
(define (stepper-recertify new-stx old-stx)
(syntax-rearm new-stx old-stx #t))

View File

@ -358,7 +358,7 @@
[stepper-safe-expanded (skipto/auto expanded-application 'discard (lambda (x) x))]
[just-the-fn
(kernel:kernel-syntax-case
(syntax-disarm stepper-safe-expanded (current-code-inspector)) #f
(syntax-disarm stepper-safe-expanded saved-code-inspector) #f
; STC: lazy racket case
; Must change this case if lazy language changes!
[(#%plain-app

View File

@ -82,7 +82,7 @@
re-intern-identifier
finished-xml-box-table
language-level->name
saved-code-inspector
stepper-syntax-property
with-stepper-syntax-properties
@ -421,7 +421,8 @@
(define (queue-length queue)
(length (unbox queue)))
(define saved-code-inspector (current-code-inspector))
(define saved-code-inspector (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define (rebuild-stx new old)
(datum->syntax old new old old))

View File

@ -43,39 +43,39 @@
;; free-vars : expr-stx -> (listof id)
;; Returns a list of free lambda- and let-bound identifiers in a
;; given epression. The expression must be fully expanded.
(define (free-vars e)
(let ([code-insp (current-code-inspector)])
(let free-vars ([e e])
(kernel-syntax-case (syntax-disarm e code-insp) #f
[id
(identifier? #'id)
(if (eq? 'lexical (identifier-binding #'id))
(list #'id)
null)]
[(#%top . id) null]
[(quote q) null]
[(quote-syntax q) null]
[(#%plain-lambda formals expr ...)
(let ([free (merge (map free-vars (syntax->list #'(expr ...))))]
[bindings (formals->boundmap #'formals)])
(filter (lambda (id)
(not (bound-identifier-mapping-get bindings id (lambda () #f))))
free))]
[(case-lambda [formals expr ...] ...)
(merge (map free-vars (syntax->list
#'((#%plain-lambda formals expr ...) ...))))]
[(let-values ([(id ...) rhs] ...) expr ...)
(merge (cons (free-vars #'(#%plain-lambda (id ... ...) expr ...))
(map free-vars (syntax->list #'(rhs ...)))))]
[(letrec-values ([(id ...) rhs] ...) expr ...)
(free-vars #'(#%plain-lambda (id ... ...) rhs ... expr ...))]
[(letrec-syntaxes+values stx-bindings ([(id ...) rhs] ...) expr ...)
(free-vars #'(#%plain-lambda (id ... ...) rhs ... expr ...))]
[(kw expr ...)
(ormap (lambda (k) (free-identifier=? k #'kw))
(list #'if #'begin #'begin0 #'set! #'#%plain-app #'#%expression
#'#%variable-reference #'with-continuation-mark))
(merge (map free-vars (syntax->list #'(expr ...))))]
[(kw . _)
(error 'free-vars "unknown core form: ~a" (syntax->datum #'kw))]))))
(define (free-vars e [code-insp
(variable-reference->module-declaration-inspector
(#%variable-reference))])
(let free-vars ([e e])
(kernel-syntax-case (syntax-disarm e code-insp) #f
[id
(identifier? #'id)
(if (eq? 'lexical (identifier-binding #'id))
(list #'id)
null)]
[(#%top . id) null]
[(quote q) null]
[(quote-syntax q) null]
[(#%plain-lambda formals expr ...)
(let ([free (merge (map free-vars (syntax->list #'(expr ...))))]
[bindings (formals->boundmap #'formals)])
(filter (lambda (id)
(not (bound-identifier-mapping-get bindings id (lambda () #f))))
free))]
[(case-lambda [formals expr ...] ...)
(merge (map free-vars (syntax->list
#'((#%plain-lambda formals expr ...) ...))))]
[(let-values ([(id ...) rhs] ...) expr ...)
(merge (cons (free-vars #'(#%plain-lambda (id ... ...) expr ...))
(map free-vars (syntax->list #'(rhs ...)))))]
[(letrec-values ([(id ...) rhs] ...) expr ...)
(free-vars #'(#%plain-lambda (id ... ...) rhs ... expr ...))]
[(letrec-syntaxes+values stx-bindings ([(id ...) rhs] ...) expr ...)
(free-vars #'(#%plain-lambda (id ... ...) rhs ... expr ...))]
[(kw expr ...)
(ormap (lambda (k) (free-identifier=? k #'kw))
(list #'if #'begin #'begin0 #'set! #'#%plain-app #'#%expression
#'#%variable-reference #'with-continuation-mark))
(merge (map free-vars (syntax->list #'(expr ...))))]
[(kw . _)
(error 'free-vars "unknown core form: ~a" (syntax->datum #'kw))])))

View File

@ -5,9 +5,15 @@
@defmodule[syntax/free-vars]
@defproc[(free-vars [expr-stx syntax?]) (listof identifier?)]{
@defproc[(free-vars [expr-stx syntax?] [insp inspector? _mod-decl-insp])
(listof identifier?)]{
Returns a list of free @racket[lambda]- and @racket[let]-bound
identifiers in @racket[expr-stx]. The expression must be fully
expanded (see @secref[#:doc refman "fully-expanded"] and
@racket[expand]).}
@racket[expand]).
The inspector @racket[insp] is used to disarm @racket[expr-stx] and
sub-expressions before extracting idenrifiers. The default
@racket[insp] is the declaration-time inspector of the
@racketmodname[syntax/free-vars] module.}

View File

@ -179,6 +179,10 @@
(eval '(begin-for-syntax 10))))
(test "1\n0\n2\n1\n" get-output-string s))
(err/rt-test (variable-reference->module-declaration-inspector (#%variable-reference)))
(err/rt-test (variable-reference->module-declaration-inspector (#%variable-reference car)))
(test (void) eval `(module m racket/base (variable-reference->module-declaration-inspector (#%variable-reference))))
;; ----------------------------------------
(parameterize ([current-namespace (make-base-namespace)])

View File

@ -37,6 +37,9 @@
stx]
[else-stx
(general-top-level-expr-iterator stx)]))
(define code-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define (general-top-level-expr-iterator stx)
(kernel-syntax-case stx #f
@ -45,17 +48,17 @@
(cond [(= (length var-list) 1) #`(define-values (var ...)
#,(expr-iterator #'expr
(car var-list)
(current-code-inspector)
code-insp
#f))]
[else #`(define-values (var ...) #,(expr-iterator #'expr #f (current-code-inspector) #f))]))]
[else #`(define-values (var ...) #,(expr-iterator #'expr #f code-insp #f))]))]
[(define-syntaxes (var ...) expr)
#`(define-syntaxes (var ...) #,(expr-iterator #'expr #f (current-code-inspector) #t))]
#`(define-syntaxes (var ...) #,(expr-iterator #'expr #f code-insp #t))]
[(begin . top-level-exprs)
#`(begin #,@(map top-level-expr-iterator (syntax->list #'top-level-exprs)))]
[(#%require . require-specs)
stx]
[else
(expr-iterator stx #f (current-code-inspector) #f)]))
(expr-iterator stx #f code-insp #f)]))
(define (expr-iterator stx potential-name insp trans?-expr)
(let* ([name-guess (or (syntax-property stx 'inferred-name) potential-name)]

View File

@ -1056,6 +1056,7 @@
[variable-reference->empty-namespace (-> -Variable-Reference -Namespace)]
[variable-reference->namespace (-> -Variable-Reference -Namespace)]
[variable-reference->resolved-module-path (-> -Variable-Reference (-opt -Resolved-Module-Path))]
[variable-reference->module-declaration-inspector (-> -Variable-Reference -Inspector)]
[variable-reference->module-source (-> -Variable-Reference (Un Sym (-val #f) -Path))]
[variable-reference->phase (-> -Variable-Reference -Nat)]
[variable-reference-constant? (-> -Variable-Reference -Boolean)]

View File

@ -22,5 +22,7 @@
(cons a d)))]
[else v])))
(define orig-insp (current-code-inspector))
(define orig-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))

View File

@ -2,7 +2,9 @@
(require (for-syntax syntax/parse racket/base syntax/id-table racket/dict
unstable/debug))
(define-for-syntax code-insp (current-code-inspector))
(define-for-syntax code-insp
(variable-reference->module-declaration-inspector
(#%variable-reference)))
(define-for-syntax (rewrite stx tbl from)
(define (rw stx)

View File

@ -12,9 +12,12 @@
(define-syntax-rule (define-re-transformer id lam)
(define-syntax id (re-transformer lam)))
(define-for-syntax code-insp (variable-reference->module-declaration-inspector
(#%variable-reference)))
(define-for-syntax (re-expand stx)
(syntax-parse
(syntax-disarm stx (current-code-inspector))
(syntax-disarm stx code-insp)
#:literals (complement seq union star epsilon nullset dseq rec unquote)
[((~and op complement) lhs:expr)
(quasisyntax/loc stx

View File

@ -16,7 +16,9 @@
(define transformer? (make-parameter #f))
(define code-insp (current-code-inspector))
(define code-insp
(variable-reference->module-declaration-inspector
(#%variable-reference)))
(define (disarm expr)
(syntax-disarm expr code-insp))

View File

@ -1,8 +1,13 @@
Version 5.1.3.10
Added variable-reference->module-declare-inspector, which allows
a macro or other syntax tool to get the enclosing module's
declaration-time inspector for taint operations
Version 5.1.3.9
Add syntax-shift-phase-level
errortrace: with-mark and make-st-mark now take a phase level
place:place* and dynamic place* forms now take in, out, and err named
arguments which become the standard io ports for the new place
racket/place: added place* and dynamic-place* to specify the input,
output, and error ports to use for a new place
Version 5.1.3.8
Add syntax-transforming-module-expression? and
@ -20,9 +25,10 @@ compiler/zo-structs: removed def-for-syntax, added
def-syntaxes
Version 5.1.3.6
unsafe/ffi:Changed cstructs to not be generative.
place:cpointers and file descriptors can now be sent across
place channels.
ffi/unsafe: changed define-cstruct to use an interned symbol tag,
which means that it is not generative
racket/place: cpointers, file-stream ports, and TCP ports can be
sent across place channels
Version 5.1.3.4
Add support for the collection links file, including

File diff suppressed because it is too large Load Diff

View File

@ -78,6 +78,7 @@ static Scheme_Object *variable_namespace(int, Scheme_Object *[]);
static Scheme_Object *variable_top_level_namespace(int, Scheme_Object *[]);
static Scheme_Object *variable_phase(int, Scheme_Object *[]);
static Scheme_Object *variable_base_phase(int, Scheme_Object *[]);
static Scheme_Object *variable_inspector(int, Scheme_Object *[]);
static Scheme_Object *variable_const_p(int, Scheme_Object *[]);
static Scheme_Object *now_transforming(int argc, Scheme_Object *argv[]);
static Scheme_Object *now_transforming_module(int argc, Scheme_Object *argv[]);
@ -645,6 +646,7 @@ static void make_kernel_env(void)
GLOBAL_PRIM_W_ARITY("variable-reference->namespace", variable_top_level_namespace, 1, 1, env);
GLOBAL_PRIM_W_ARITY("variable-reference->phase", variable_phase, 1, 1, env);
GLOBAL_PRIM_W_ARITY("variable-reference->module-base-phase", variable_base_phase, 1, 1, env);
GLOBAL_PRIM_W_ARITY("variable-reference->module-declaration-inspector", variable_inspector, 1, 1, env);
REGISTER_SO(scheme_varref_const_p_proc);
scheme_varref_const_p_proc = scheme_make_prim_w_arity(variable_const_p,
@ -1682,6 +1684,14 @@ static Scheme_Object *do_variable_namespace(const char *who, int tl, int argc, S
return scheme_make_integer(ph);
} else if (tl == 3) {
return scheme_make_integer(ph - env->mod_phase);
} else if (tl == 4) {
if (((Scheme_Object *)((Scheme_Bucket *)v)->key != scheme_stack_dump_key)
|| !env->module) {
scheme_arg_mismatch(who,
"variable reference does not refer to an anonymous module variable: ",
v);
}
return env->module->insp;
} else if (tl) {
/* return env directly; need to set up */
if (!env->phase && env->module)
@ -1717,6 +1727,11 @@ static Scheme_Object *variable_base_phase(int argc, Scheme_Object *argv[])
return do_variable_namespace("variable-reference->phase", 3, argc, argv);
}
static Scheme_Object *variable_inspector(int argc, Scheme_Object *argv[])
{
return do_variable_namespace("variable-reference->module-declaration-inspector", 4, argc, argv);
}
static Scheme_Object *variable_const_p(int argc, Scheme_Object *argv[])
{
Scheme_Object *v;

View File

@ -4869,7 +4869,6 @@ void *scheme_module_run_finish(Scheme_Env *menv, Scheme_Env *env)
config = scheme_extend_config(scheme_current_config(),
MZCONFIG_ENV,
(Scheme_Object *)env);
scheme_push_continuation_frame(&cframe);
scheme_set_cont_mark(scheme_parameterization_key, (Scheme_Object *)config);
}

View File

@ -13,7 +13,7 @@
#define USE_COMPILED_STARTUP 1
#define EXPECTED_PRIM_COUNT 1034
#define EXPECTED_PRIM_COUNT 1035
#define EXPECTED_UNSAFE_COUNT 78
#define EXPECTED_FLFXNUM_COUNT 68
#define EXPECTED_FUTURES_COUNT 11

View File

@ -13,12 +13,12 @@
consistently.)
*/
#define MZSCHEME_VERSION "5.1.3.9"
#define MZSCHEME_VERSION "5.1.3.10"
#define MZSCHEME_VERSION_X 5
#define MZSCHEME_VERSION_Y 1
#define MZSCHEME_VERSION_Z 3
#define MZSCHEME_VERSION_W 9
#define MZSCHEME_VERSION_W 10
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)