File: code-inspectors.scrbl

package info (click to toggle)
racket 7.9%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 178,684 kB
  • sloc: ansic: 282,112; lisp: 234,887; pascal: 70,954; sh: 27,112; asm: 16,268; makefile: 4,613; cpp: 2,715; ada: 1,681; javascript: 1,244; cs: 879; exp: 499; csh: 422; python: 274; xml: 106; perl: 104
file content (72 lines) | stat: -rw-r--r-- 3,672 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#lang scribble/doc
@(require "mz.rkt")

@title[#:tag "modprotect"]{Code Inspectors}

In the same way that inspectors control access to structure fields
(see @secref["inspectors"]), inspectors also control access to
@tech{module bindings}. Inspectors used this way are @deftech{code
inspectors}. The default code inspector for @tech{module
bindings} is determined by the @racket[current-code-inspector]
parameter, instead of the @racket[current-inspector] parameter.

When a @racket[module] declaration is evaluated, the value of the
@racket[current-code-inspector] parameter is associated with the
module declaration. When the module is invoked via @racket[require] or
@racket[dynamic-require], a sub-inspector of the module's
declaration-time inspector is created, and this sub-inspector is
associated with the module invocation. Any inspector that controls the
sub-inspector (including the declaration-time inspector and its
superior) controls the module invocation. In particular, if the value
of @racket[current-code-inspector] never changes, then no control is
lost for any module invocation, since the module's invocation is
associated with a sub-inspector of @racket[current-code-inspector].

When an inspector that controls a module invocation is installed with
@racket[current-code-inspector], it enables using
@racket[module->namespace] on the module, and it enables access to the
module's protected exports (i.e., those identifiers exported from the
module with @racket[protect-out]) via @racket[dynamic-require]. A
module cannot @racket[require] a module that has a weaker
declaration-time code inspector.

When a @racket[module] form is expanded or a @tech{namespace} is
created, the value of @racket[current-code-inspector] is associated
with the module or namespace's top-level @tech{lexical information}.
Syntax objects with that @tech{lexical information} gain access to the
protected and unexported bindings of any module that the inspector
controls. In the case of a @racket[module], the inspector sticks with
such syntax objects even the syntax object is used in the expansion of
code in a less powerful context; furthermore, if the syntax object is
an identifier that is compiled as a variable reference, the inspector
sticks with the variable reference even if it appears in a module form
that is evaluated (i.e., declared) with a weaker inspector. When a
syntax object or variable reference is within compiled code that is
printed (see @secref["print-compiled"]), the associated inspector is
not preserved.

When compiled code in printed form is @racket[read] back in, no
inspectors are associated with the code. When the code is
@racket[eval]uated, the instantiated syntax-object literals and
module-variable references acquire value of
@racket[current-code-inspector] as their inspector.

When a module instantiation is attached to multiple @tech{namespaces},
each with its own @tech{module registry}, the inspector for the module
invocation can be registry-specific. The invocation inspector in a
particular module registry can be changed via
@racket[namespace-unprotect-module] (but changing the inspector
requires control over the old one).

@history[#:changed "8.1.0.8" @elem{Added constraint against
                                    @racket[require] of a module with
                                    a weaker code inspector.}]

@defparam[current-code-inspector insp inspector?]{

A @tech{parameter} that determines an inspector to control access to
module bindings and redefinitions.

If the code inspector is changed from its original value, then
bytecode loaded by the default @tech{compiled-load handler} is marked
as non-runnable.}