instantiate require'd modules in the order that they are require'd

This order is now specified, whereas the order was previously unspecified,
and the previous reverse order was an artifact of the implementation.
This commit is contained in:
Matthew Flatt 2012-05-16 07:10:49 -06:00
parent 68029b4ade
commit 9270936a28
4 changed files with 30 additions and 6 deletions

View File

@ -232,7 +232,11 @@ module, whose full name depends both on @racket[id] or
A module body is executed only when the module is explicitly
@techlink{instantiate}d via @racket[require] or
@racket[dynamic-require]. On invocation, expressions and definitions
@racket[dynamic-require]. On invocation, imported modules are
instantiated in the order in which they are @racket[require]d
into the module (although earlier instantiations or transitive
@racket[require]s can trigger the instantiation of a module before
its order within a given module). Then, expressions and definitions
are evaluated in order as they appear within the module. Each
evaluation of an expression or definition is wrapped with a
continuation prompt (see @racket[call-with-continuation-prompt]) for

View File

@ -182,7 +182,7 @@
(test '(d b c) values l)
(eval `(module f mzscheme
(,here 'f)
(require 'b 'e)))
(require 'e 'b)))
(test '(d b d b c) values l)
(eval `(require 'f))
(let ([finished '(f b e a d b d b d b c)])
@ -764,6 +764,18 @@
(err/rt-test (eval '(define-syntax m (syntax-local-module-defined-identifiers))))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Check that invocation order matches `require' order:
(module order-check-module-a racket/base 'a)
(module order-check-module-b racket/base 'b)
(module order-check-module racket/base (require 'order-check-module-a
'order-check-module-b))
(let ([o (open-output-string)])
(parameterize ([current-output-port o])
(dynamic-require ''order-check-module #f))
(test "'a\n'b\n" get-output-string o))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(report-errs)

View File

@ -1,4 +1,5 @@
Version 5.3.0.8
Required modules are instantiated in the order that they are required
Added variable-reference->module-path-index
Added syntax-local-submodules
Added relative-in

View File

@ -2766,7 +2766,6 @@ void scheme_prep_namespace_rename(Scheme_Env *menv)
if (l) {
/* Do initial import first to get shadowing right: */
l = scheme_reverse(l);
for (; SCHEME_PAIRP(l); l = SCHEME_CDR(l)) {
idx = SCHEME_CAR(l);
name = scheme_module_resolve(idx, 0);
@ -4497,7 +4496,7 @@ static void show_done(const char *what, Scheme_Env *menv, int v1, int v2, int i,
static void compute_require_names(Scheme_Env *menv, Scheme_Object *phase,
Scheme_Env *load_env, Scheme_Object *syntax_idx)
{
Scheme_Object *np, *midx, *l, *reqs, *req_names;
Scheme_Object *np, *np_first, *np_last, *midx, *l, *reqs, *req_names;
if (SAME_OBJ(phase, scheme_make_integer(0))) {
req_names = menv->require_names;
@ -4532,7 +4531,8 @@ static void compute_require_names(Scheme_Env *menv, Scheme_Object *phase,
if (req_names && !SCHEME_NULLP(req_names))
return;
np = scheme_null;
np_first = scheme_null;
np_last = NULL;
for (l = reqs; !SCHEME_NULLP(l); l = SCHEME_CDR(l)) {
midx = do_modidx_shift(SCHEME_CAR(l),
@ -4543,9 +4543,16 @@ static void compute_require_names(Scheme_Env *menv, Scheme_Object *phase,
if (load_env)
module_load(scheme_module_resolve(midx, 1), load_env, NULL);
np = cons(midx, np);
np = cons(midx, scheme_null);
if (np_last)
SCHEME_CDR(np_last) = np;
else
np_first = np;
np_last = np;
}
np = np_first;
if (!SAME_OBJ(np, req_names)) {
if (SAME_OBJ(phase, scheme_make_integer(0))) {
menv->require_names = np;