1 /*
2 * module.c - module implementation
3 *
4 * Copyright (c) 2000-2020 Shiro Kawai <shiro@acm.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the authors nor the names of its contributors
18 * may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #define LIBGAUCHE_BODY
35 #include "gauche.h"
36 #include "gauche/class.h"
37 #include "gauche/priv/builtin-syms.h"
38 #include "gauche/priv/moduleP.h"
39
40 /*
41 * Modules
42 *
43 * A module maps symbols to global locations (GLOCs).
44 * The mapping is resolved at the compile time.
45 * Scheme's current-module is therefore a syntax, instead of
46 * a procedure, to capture compile-time information.
47 *
48 * Each module has two hashtables; the 'internal' table keeps all the
49 * bindings in the module, while the 'external' table keeps only the
50 * bindings that are exported. In most cases, the latter is a subset
51 * of the former. If a binding is renamed on export, however,
52 * two tables map different symbols on the same GLOC.
53 *
54 * Modules are registered to a global hash table using their names
55 * as keys, so that the module is retrieved by its name. The exception
56 * is "anonymous modules", which have #f as the name field
57 * and not registered in the global table. Anonymous modules are especially
58 * useful for certain applications that need temporary, segregated
59 * namespace---for example, a 'sandbox' environment to evaluate an
60 * expression sent over the network during a session.
61 * The anonymous namespace will be garbage-collected if nobody references
62 * it, recovering its resources.
63 */
64
65 /* Note on mutex of module operation
66 *
67 * Each module used to have a mutex for accesses to it. I changed it
68 * to use a single global lock (modules.mutex), based on the following
69 * observations:
70 *
71 * - Profiling showed mutex_lock was taking around 10% of program loading
72 * phase in the previous version.
73 *
74 * - Module operations almost always occur during program loading and
75 * interactive session. Having giant lock for module operations won't
76 * affect normal runtime performance.
77 *
78 * Benchmark showed the change made program loading 30% faster.
79 */
80
81 /* Special treatment of keyword modules.
82 * We need to achieve two goals:
83 *
84 * (1) For ordinary Gauche programs (modules that uses implicit inheritance
85 * of #<module gauche>), we want to see all keywords being bound to
86 * itself by default. It can be achieved by inheriting a module that
87 * has such keyword bindings.
88 * (2) For R7RS programs we want to see the default keyword bindings only
89 * when the programmer explicitly asks so - notably, by importing some
90 * special module. It can be achieved by a module that has all keywords
91 * each bound to itself, *and* exports all of such bindings.
92 *
93 * It turned out we can't use one 'keyword' module for both purpose; if
94 * we have a keyword module that exports all bindings, they are automatically
95 * exported from modules that inherits them. This means if a R7RS program
96 * imports any of Gauche modules, it carries all of keyword bindings. It's
97 * not only nasty, but also dangerous for it can shadow bindings to the
98 * symbols starting with a colon inadvertently.
99 *
100 * So we have two modules, #<module gauche.keyword> and
101 * #<module keyword>. The former have export-all flag, and to be imported
102 * from R7RS programs as needed. The latter doesn't export anything, and
103 * to be inherited to Gauche modules by default. Whenever a keyword
104 * is created, its default binding is inserted to both - actually,
105 * to prevent two modules from being out of sync, we specially wire them
106 * to share a single hashtable for their internal bindings.
107 */
108
109 /* Note on gauche.require-base module
110 It is an immutable module to which 'require' loads code.
111 We need a base module where 'define-module' and 'define-library' are
112 visible in order for requiring modules using them to work, so
113 loading into the current module won't cut it. However, we don't
114 want to use a specific mutable module (such as #<module gauche>) as
115 a base, since if the required module has toplevel defines without
116 switching the module, it will modify the base module.
117 By using immutable module as a base, we can reject the latter case;
118 requiring a code that inserts toplevel binding without specifying
119 a module is simply a bad idea and shouldn't be allowed.
120 */
121
122 /* Global module table */
123 static struct {
124 ScmHashTable *table; /* Maps name -> module. */
125 ScmInternalMutex mutex; /* Lock for table. Only register_module and
126 lookup_module may hold the lock. */
127 } modules;
128
129 /* Predefined modules - slots will be initialized by Scm__InitModule */
130 #define DEFINE_STATIC_MODULE(cname) \
131 static ScmModule cname;
132
133 DEFINE_STATIC_MODULE(nullModule); /* #<module null> */
134 DEFINE_STATIC_MODULE(schemeModule); /* #<module scheme> */
135 DEFINE_STATIC_MODULE(gaucheModule); /* #<module gauche> */
136 DEFINE_STATIC_MODULE(internalModule); /* #<module gauche.internal> */
137 DEFINE_STATIC_MODULE(gfModule); /* #<module gauche.gf> */
138 DEFINE_STATIC_MODULE(userModule); /* #<module user> */
139 DEFINE_STATIC_MODULE(keywordModule); /* #<module keyword> */
140 DEFINE_STATIC_MODULE(gkeywordModule); /* #<module gauche.keyword> */
141 DEFINE_STATIC_MODULE(reqbaseModule); /* #<module gauche.require-base> */
142
143 static ScmObj defaultParents = SCM_NIL; /* will be initialized */
144 static ScmObj defaultMpl = SCM_NIL; /* will be initialized */
145
146 /*----------------------------------------------------------------------
147 * Constructor
148 */
149
init_module(ScmModule * m,ScmObj name,ScmHashTable * internal)150 static void init_module(ScmModule *m, ScmObj name, ScmHashTable *internal)
151 {
152 m->name = name;
153 m->imported = m->depended = SCM_NIL;
154 m->exportAll = FALSE;
155 m->parents = defaultParents;
156 m->mpl = Scm_Cons(SCM_OBJ(m), defaultMpl);
157 if (internal) {
158 m->internal = internal;
159 } else {
160 m->internal = SCM_HASH_TABLE(Scm_MakeHashTableSimple(SCM_HASH_EQ, 0));
161 }
162 m->external = SCM_HASH_TABLE(Scm_MakeHashTableSimple(SCM_HASH_EQ, 0));
163 m->origin = m->prefix = SCM_FALSE;
164 m->sealed = FALSE;
165 m->placeholding = FALSE;
166 }
167
168 /* Internal */
make_module(ScmObj name,ScmHashTable * internal)169 static ScmObj make_module(ScmObj name, ScmHashTable *internal)
170 {
171 ScmModule *m = SCM_NEW(ScmModule);
172 SCM_SET_CLASS(m, SCM_CLASS_MODULE);
173 init_module(m, name, internal);
174 return SCM_OBJ(m);
175 }
176
177 /* Internal. Lookup module with name N from the table. */
lookup_module(ScmSymbol * name)178 static ScmModule *lookup_module(ScmSymbol *name)
179 {
180 (void)SCM_INTERNAL_MUTEX_LOCK(modules.mutex);
181 ScmObj v = Scm_HashTableRef(modules.table, SCM_OBJ(name), SCM_UNBOUND);
182 (void)SCM_INTERNAL_MUTEX_UNLOCK(modules.mutex);
183 if (SCM_UNBOUNDP(v)) return NULL;
184 else return SCM_MODULE(v);
185 }
186
187 /* Internal. Lookup module, and if there's none, create one. */
lookup_module_create(ScmSymbol * name,int * created)188 static ScmModule *lookup_module_create(ScmSymbol *name, int *created)
189 {
190 (void)SCM_INTERNAL_MUTEX_LOCK(modules.mutex);
191 ScmDictEntry *e = Scm_HashCoreSearch(SCM_HASH_TABLE_CORE(modules.table),
192 (intptr_t)name,
193 SCM_DICT_CREATE);
194 if (e->value == 0) {
195 (void)SCM_DICT_SET_VALUE(e, make_module(SCM_OBJ(name), NULL));
196 *created = TRUE;
197 } else {
198 *created = FALSE;
199 }
200 (void)SCM_INTERNAL_MUTEX_UNLOCK(modules.mutex);
201 return SCM_MODULE(e->value);
202 }
203
Scm_MakeModule(ScmSymbol * name,int error_if_exists)204 ScmObj Scm_MakeModule(ScmSymbol *name, int error_if_exists)
205 {
206 if (name == NULL) {
207 return make_module(SCM_FALSE, NULL);
208 }
209 int created;
210 ScmObj r = SCM_OBJ(lookup_module_create(name, &created));
211 if (!created) {
212 if (error_if_exists) {
213 Scm_Error("couldn't create module '%S': named module already exists",
214 SCM_OBJ(name));
215 }
216 return SCM_FALSE;
217 }
218 return r;
219 }
220
221 /* internal API to create an anonymous wrapper module */
Scm__MakeWrapperModule(ScmModule * origin,ScmObj prefix)222 ScmObj Scm__MakeWrapperModule(ScmModule *origin, ScmObj prefix)
223 {
224 ScmModule *m = SCM_MODULE(make_module(SCM_FALSE, NULL));
225 m->parents = SCM_LIST1(SCM_OBJ(origin));
226 m->mpl = Scm_Cons(SCM_OBJ(m), origin->mpl);
227 m->prefix = prefix;
228 while (SCM_MODULEP(origin->origin)) {
229 origin = SCM_MODULE(origin->origin);
230 }
231 m->origin = SCM_OBJ(origin);
232 return SCM_OBJ(m);
233 }
234
235 /* Common code to report error on sealed module.
236 One common error is to try to 'use' or 'require' a file that doesn't
237 have module definitions in it. The default error message in that case
238 is perplexing, so we use more helpful message in that case.
239 */
err_sealed(ScmObj source,ScmModule * target)240 static void err_sealed(ScmObj source, ScmModule *target)
241 {
242 const char *what = "";
243 if (SCM_MODULEP(source)) what = "import a module";
244 else what = "create a binding";
245
246 if (target == Scm__RequireBaseModule()) {
247 Scm_Error("Attempted to %s (%S) into gauche.require-base. "
248 "This may be caused by trying to 'use' or 'require' a file"
249 " in which no module is defined. Make sure the file has"
250 " define-module/select-module or define-library at the"
251 " beginning.",
252 what, source, SCM_OBJ(target));
253 } else {
254 Scm_Error("Attempted to %s (%S) in a sealed module: %S",
255 what, source, SCM_OBJ(target));
256 }
257 }
258
259 /*----------------------------------------------------------------------
260 * Finding and modifying bindings
261 */
262
263 #define SEARCHED_ARRAY_SIZE 64
264
265 /* Keep record of searched modules. we use stack array for small # of
266 modules, in order to avoid consing for typical cases. */
267 typedef struct {
268 int num_searched;
269 ScmObj searched[SEARCHED_ARRAY_SIZE];
270 ScmObj more_searched;
271 } module_cache;
272
273
init_module_cache(module_cache * c)274 static inline void init_module_cache(module_cache *c)
275 {
276 c->num_searched = 0;
277 c->more_searched = SCM_NIL;
278 }
279
module_visited_p(module_cache * c,ScmModule * m)280 static inline int module_visited_p(module_cache *c, ScmModule *m)
281 {
282 for (int i=0; i<c->num_searched; i++) {
283 if (SCM_EQ(SCM_OBJ(m), c->searched[i])) return TRUE;
284 }
285 if (!SCM_NULLP(c->more_searched)) {
286 if (!SCM_FALSEP(Scm_Memq(SCM_OBJ(m), c->more_searched))) return TRUE;
287 }
288 return FALSE;
289 }
290
module_add_visited(module_cache * c,ScmModule * m)291 static inline void module_add_visited(module_cache *c, ScmModule *m)
292 {
293 if (c->num_searched < SEARCHED_ARRAY_SIZE) {
294 c->searched[c->num_searched++] = SCM_OBJ(m);
295 } else {
296 c->more_searched = Scm_Cons(SCM_OBJ(m), c->more_searched);
297 }
298 }
299
300 /* The main logic of global binding search. We factored this out since
301 we need recursive searching in case of phantom binding (see gloc.h
302 about phantom bindings). The flags stay_in_module and external_only
303 corresponds to the flags passed to Scm_FindBinding. The exclude_self
304 flag is only used in recursive search. */
search_binding(ScmModule * module,ScmSymbol * symbol,int stay_in_module,int external_only,int exclude_self)305 static ScmGloc *search_binding(ScmModule *module, ScmSymbol *symbol,
306 int stay_in_module, int external_only,
307 int exclude_self)
308 {
309 module_cache searched;
310 init_module_cache(&searched);
311
312 /* First, search from the specified module. In this phase, we just ignore
313 phantom bindings, for we'll search imported bindings later anyway. */
314 if (!exclude_self) {
315 ScmObj v = Scm_HashTableRef(
316 external_only? module->external : module->internal,
317 SCM_OBJ(symbol), SCM_FALSE);
318 if (SCM_GLOCP(v)) {
319 if (SCM_GLOC_PHANTOM_BINDING_P(SCM_GLOC(v))) {
320 /* If we're here, the symbol is external to MODULE but
321 the real GLOC is somewhere in imported or inherited
322 modules. We turn off external_only switch so that
323 when we search inherited modules we look into it's
324 internal bindings. */
325 external_only = FALSE;
326 symbol = SCM_GLOC(v)->name; /* in case it's renamed on export */
327 } else {
328 return SCM_GLOC(v);
329 }
330 }
331 if (stay_in_module) return NULL;
332 module_add_visited(&searched, module);
333 }
334
335 ScmObj p, mp;
336 /* Next, search from imported modules
337 If the import is prefixed, we avoid caching the result. */
338 SCM_FOR_EACH(p, module->imported) {
339 ScmObj elt = SCM_CAR(p);
340 ScmObj sym = SCM_OBJ(symbol);
341 int prefixed = FALSE;
342
343 SCM_ASSERT(SCM_MODULEP(elt));
344 SCM_FOR_EACH(mp, SCM_MODULE(elt)->mpl) {
345 ScmGloc *g;
346
347 SCM_ASSERT(SCM_MODULEP(SCM_CAR(mp)));
348 ScmModule *m = SCM_MODULE(SCM_CAR(mp));
349 if (!prefixed && module_visited_p(&searched, m)) continue;
350 if (SCM_SYMBOLP(m->prefix)) {
351 sym = Scm_SymbolSansPrefix(SCM_SYMBOL(sym),
352 SCM_SYMBOL(m->prefix));
353 if (!SCM_SYMBOLP(sym)) break;
354 prefixed = TRUE;
355 }
356
357 ScmObj v = Scm_HashTableRef(m->external, SCM_OBJ(sym), SCM_FALSE);
358 if (SCM_GLOCP(v)) {
359 g = SCM_GLOC(v);
360 if (g->hidden) break;
361 if (SCM_GLOC_PHANTOM_BINDING_P(g)) {
362 g = search_binding(m, g->name, FALSE, FALSE, TRUE);
363 if (g) return g;
364 } else {
365 return g;
366 }
367 }
368 if (!prefixed) module_add_visited(&searched, m);
369 }
370 }
371
372 /* Then, search from parent modules */
373 SCM_ASSERT(SCM_PAIRP(module->mpl));
374 SCM_FOR_EACH(mp, SCM_CDR(module->mpl)) {
375 SCM_ASSERT(SCM_MODULEP(SCM_CAR(mp)));
376 ScmModule *m = SCM_MODULE(SCM_CAR(mp));
377
378 if (SCM_SYMBOLP(m->prefix)) {
379 ScmObj sym = Scm_SymbolSansPrefix(symbol, SCM_SYMBOL(m->prefix));
380 if (!SCM_SYMBOLP(sym)) return NULL;
381 symbol = SCM_SYMBOL(sym);
382 }
383 ScmObj v = Scm_HashTableRef(external_only?m->external:m->internal,
384 SCM_OBJ(symbol), SCM_FALSE);
385
386 if (SCM_GLOCP(v)) {
387 if (SCM_GLOC_PHANTOM_BINDING_P(SCM_GLOC(v))) {
388 symbol = SCM_GLOC(v)->name; /* in case it's renamed on export */ ScmGloc *g = search_binding(m, symbol, FALSE, FALSE, TRUE);
389 if (g) return g;
390 external_only = FALSE; /* See above comment */
391 } else {
392 return SCM_GLOC(v);
393 }
394 }
395 }
396 return NULL;
397 }
398
Scm_FindBinding(ScmModule * module,ScmSymbol * symbol,int flags)399 ScmGloc *Scm_FindBinding(ScmModule *module, ScmSymbol *symbol, int flags)
400 {
401 int stay_in_module = flags&SCM_BINDING_STAY_IN_MODULE;
402 int external_only = flags&SCM_BINDING_EXTERNAL;
403 ScmGloc *gloc = NULL;
404
405 SCM_INTERNAL_MUTEX_SAFE_LOCK_BEGIN(modules.mutex);
406 gloc = search_binding(module, symbol, stay_in_module, external_only, FALSE);
407 SCM_INTERNAL_MUTEX_SAFE_LOCK_END();
408 return gloc;
409 }
410
Scm_GlobalVariableRef(ScmModule * module,ScmSymbol * symbol,int flags)411 ScmObj Scm_GlobalVariableRef(ScmModule *module,
412 ScmSymbol *symbol,
413 int flags)
414 {
415 ScmGloc *g = Scm_FindBinding(module, symbol, flags);
416
417 if (g == NULL) return SCM_UNBOUND;
418 ScmObj val = SCM_GLOC_GET(g);
419 if (SCM_AUTOLOADP(val)) {
420 /* NB: Scm_ResolveAutoload may return SCM_UNBOUND */
421 val = Scm_ResolveAutoload(SCM_AUTOLOAD(val), 0);
422 }
423 return val;
424 }
425
426 /*
427 * Definition.
428 */
Scm_MakeBinding(ScmModule * module,ScmSymbol * symbol,ScmObj value,int flags)429 ScmGloc *Scm_MakeBinding(ScmModule *module, ScmSymbol *symbol,
430 ScmObj value, int flags)
431 {
432 if (module->sealed) err_sealed(SCM_OBJ(symbol), module);
433
434 ScmGloc *g;
435 ScmObj oldval = SCM_UNDEFINED;
436 int prev_kind = 0;
437 int kind = ((flags&SCM_BINDING_CONST)
438 ? SCM_BINDING_CONST
439 : ((flags&SCM_BINDING_INLINABLE)
440 ? SCM_BINDING_INLINABLE
441 : 0));
442
443 SCM_INTERNAL_MUTEX_SAFE_LOCK_BEGIN(modules.mutex);
444 ScmObj v = Scm_HashTableRef(module->internal, SCM_OBJ(symbol), SCM_FALSE);
445 /* NB: this function bypasses check of gloc setter */
446 if (SCM_GLOCP(v)) {
447 g = SCM_GLOC(v);
448 if (Scm_GlocConstP(g)) prev_kind = SCM_BINDING_CONST;
449 else if (Scm_GlocInlinableP(g)) prev_kind = SCM_BINDING_INLINABLE;
450 oldval = g->value;
451 } else {
452 g = SCM_GLOC(Scm_MakeGloc(symbol, module));
453 Scm_HashTableSet(module->internal, SCM_OBJ(symbol), SCM_OBJ(g), 0);
454 /* If module is marked 'export-all', export this binding by default */
455 if (module->exportAll && SCM_SYMBOL_INTERNED(symbol)) {
456 Scm_HashTableSet(module->external, SCM_OBJ(symbol), SCM_OBJ(g), 0);
457 }
458 }
459 SCM_INTERNAL_MUTEX_SAFE_LOCK_END();
460
461 g->value = value;
462 Scm_GlocMark(g, kind);
463
464 if (prev_kind != 0) {
465 /* NB: Scm_EqualP may throw an error. It won't leave the state
466 inconsistent, but be aware. */
467 if (prev_kind != kind || !Scm_EqualP(value, oldval)) {
468 Scm_Warn("redefining %s %S::%S",
469 (prev_kind == SCM_BINDING_CONST)? "constant" : "inlinable",
470 g->module->name, g->name);
471 }
472 }
473 return g;
474 }
475
476 /* Convenience wrapper (return value is ScmObj for the backward compatibility)*/
Scm_Define(ScmModule * module,ScmSymbol * symbol,ScmObj value)477 ScmObj Scm_Define(ScmModule *module, ScmSymbol *symbol, ScmObj value)
478 {
479 return SCM_OBJ(Scm_MakeBinding(module, symbol, value, 0));
480 }
481
Scm_DefineConst(ScmModule * module,ScmSymbol * symbol,ScmObj value)482 ScmObj Scm_DefineConst(ScmModule *module, ScmSymbol *symbol, ScmObj value)
483 {
484 return SCM_OBJ(Scm_MakeBinding(module, symbol, value, SCM_BINDING_CONST));
485 }
486
487 /*
488 * Injecting hidden binding
489 * This inserts a dummy binding with hidden==true so that
490 * the module effectively removes the binding of the given symbol
491 * inherited from parent.
492 * This is not for genreral use. It is intended to be used for
493 * intermediate anonymous modules, created by import handling
494 * routine to implement :except and :rename qualifiers.
495 * Since we assume MODULE is for intermediate modules, we only
496 * insert bindings to the external table, for those modules are
497 * only searched in the 'import' path.
498 */
Scm_HideBinding(ScmModule * module,ScmSymbol * symbol)499 void Scm_HideBinding(ScmModule *module, ScmSymbol *symbol)
500 {
501 if (module->sealed) err_sealed(SCM_OBJ(symbol), module);
502
503 int err_exists = FALSE;
504
505 (void)SCM_INTERNAL_MUTEX_LOCK(modules.mutex);
506 ScmObj v = Scm_HashTableRef(module->external, SCM_OBJ(symbol), SCM_FALSE);
507 if (!SCM_FALSEP(v)) {
508 err_exists = TRUE;
509 } else {
510 ScmGloc *g = SCM_GLOC(Scm_MakeGloc(symbol, module));
511 g->hidden = TRUE;
512 Scm_HashTableSet(module->external, SCM_OBJ(symbol), SCM_OBJ(g), 0);
513 }
514 (void)SCM_INTERNAL_MUTEX_UNLOCK(modules.mutex);
515
516 if (err_exists) {
517 Scm_Error("hide-binding: binding already exists: %S (exports=%S)", SCM_OBJ(symbol), Scm_ModuleExports(module));
518 }
519 }
520
521 /*
522 * Binding aliasing
523 * This is a special operation to realize :only and :rename import option.
524 * The name ORIGINNAME is looked up in the module ORIGIN to get a gloc.
525 * Then the gloc is directly inserted into the module TARGET under the name
526 * TARGETNAME.
527 * Since gloc is shared, subsequent changes in the binding are also shared.
528 *
529 * If the original binding doesn't exist, or isn't exported, noop and
530 * FALSE is returned. Otherwise TRUE is returned.
531 *
532 * CAVEATS:
533 *
534 * - gloc's module remains the same.
535 * - autoload won't be resolved.
536 * - TARGETNAME shouldn't be bound in TARGET beforehand. We don't check
537 * it and just insert the gloc. If there is an existing binding,
538 * it would become orphaned, possibly causing problems.
539 *
540 * NB: This is the only operation that causes a gloc to be shared between
541 * more than one modules. I'm not yet clear on the implication of such
542 * sharing in general, so this should be used with care. At least it
543 * won't cause much trouble if the target module is an implicit anonymous
544 * module created by :only and :rename import options.
545 */
Scm_AliasBinding(ScmModule * target,ScmSymbol * targetName,ScmModule * origin,ScmSymbol * originName)546 int Scm_AliasBinding(ScmModule *target, ScmSymbol *targetName,
547 ScmModule *origin, ScmSymbol *originName)
548 {
549 if (target->sealed) err_sealed(SCM_OBJ(targetName), target);
550
551 ScmGloc *g = Scm_FindBinding(origin, originName, SCM_BINDING_EXTERNAL);
552 if (g == NULL) return FALSE;
553 SCM_INTERNAL_MUTEX_SAFE_LOCK_BEGIN(modules.mutex);
554 Scm_HashTableSet(target->external, SCM_OBJ(targetName), SCM_OBJ(g), 0);
555 Scm_HashTableSet(target->internal, SCM_OBJ(targetName), SCM_OBJ(g), 0);
556 SCM_INTERNAL_MUTEX_SAFE_LOCK_END();
557 return TRUE;
558 }
559
560 /*
561 * Import
562 */
Scm_ImportModule(ScmModule * module,ScmObj imported,ScmObj prefix,u_long flags SCM_UNUSED)563 ScmObj Scm_ImportModule(ScmModule *module,
564 ScmObj imported,
565 ScmObj prefix,
566 u_long flags SCM_UNUSED) /* reserved for future use */
567 {
568 if (module->sealed) err_sealed(SCM_OBJ(imported), module);
569
570 ScmModule *imp = NULL;
571 if (SCM_MODULEP(imported)) {
572 imp = SCM_MODULE(imported);
573 } else if (SCM_SYMBOLP(imported)) {
574 imp = Scm_FindModule(SCM_SYMBOL(imported), 0);
575 } else if (SCM_IDENTIFIERP(imported)) {
576 imp = Scm_FindModule(Scm_UnwrapIdentifier(SCM_IDENTIFIER(imported)), 0);
577 } else {
578 Scm_Error("module name or module required, but got %S", imported);
579 }
580
581 if (SCM_SYMBOLP(prefix)) {
582 imp = SCM_MODULE(Scm__MakeWrapperModule(imp, prefix));
583 }
584
585 /* Preallocate a pair, so that we won't call malloc during locking */
586 ScmObj p = Scm_Cons(SCM_OBJ(imp), SCM_NIL);
587
588 /* Prepend imported module to module->imported list. */
589 (void)SCM_INTERNAL_MUTEX_LOCK(modules.mutex);
590 {
591 ScmObj ms, prev = p;
592 SCM_SET_CDR_UNCHECKED(p, module->imported);
593 /* Remove duplicate module, if any.
594 NB: We allow to import the same module multiple times if they are
595 qualified by :only, :prefix, etc. Theoretically we should check
596 exactly same qualifications, but we hope that kind of duplication
597 is rare.
598 */
599 SCM_FOR_EACH(ms, SCM_CDR(p)) {
600 ScmModule *m = SCM_MODULE(SCM_CAR(ms));
601 if (!SCM_EQ(SCM_OBJ(m), SCM_OBJ(imp))) {
602 prev = ms;
603 continue;
604 }
605 SCM_SET_CDR_UNCHECKED(prev, SCM_CDR(ms));
606 break;
607 }
608 module->imported = p;
609 }
610 (void)SCM_INTERNAL_MUTEX_UNLOCK(modules.mutex);
611
612 return module->imported;
613 }
614
615 /* Deprecated */
Scm_ImportModules(ScmModule * module,ScmObj list)616 ScmObj Scm_ImportModules(ScmModule *module, ScmObj list)
617 {
618 ScmObj lp;
619 SCM_FOR_EACH(lp, list) {
620 Scm_ImportModule(module, SCM_CAR(lp), SCM_FALSE, 0);
621 }
622 return module->imported;
623 }
624
625 /*
626 * Export
627 */
628 /* <spec> :: <name> | (rename <name> <exported-name>) */
Scm_ExportSymbols(ScmModule * module,ScmObj specs)629 ScmObj Scm_ExportSymbols(ScmModule *module, ScmObj specs)
630 {
631 ScmObj lp;
632 ScmObj overwritten = SCM_NIL; /* list of (exported-name orig-internal-name
633 new-internal-name). */
634 /* Check input first */
635 SCM_FOR_EACH(lp, specs) {
636 ScmObj spec = SCM_CAR(lp);
637 if (!(SCM_SYMBOLP(spec)
638 || (SCM_PAIRP(spec) && SCM_PAIRP(SCM_CDR(spec))
639 && SCM_PAIRP(SCM_CDDR(spec))
640 && SCM_NULLP(SCM_CDR(SCM_CDDR(spec)))
641 && SCM_EQ(SCM_CAR(spec), SCM_SYM_RENAME)
642 && SCM_SYMBOLP(SCM_CADR(spec))
643 && SCM_SYMBOLP(SCM_CAR(SCM_CDDR(spec)))))) {
644 Scm_Error("Invalid export-spec; a symbol, or (rename <symbol> <symbol>) is expected, but got %S", spec);
645 }
646 }
647
648 (void)SCM_INTERNAL_MUTEX_LOCK(modules.mutex);
649 SCM_FOR_EACH(lp, specs) {
650 ScmObj spec = SCM_CAR(lp);
651 ScmSymbol *name, *exported_name;
652 if (SCM_SYMBOLP(spec)) {
653 name = exported_name = SCM_SYMBOL(spec);
654 } else {
655 /* we already knew those are symbols */
656 name = SCM_SYMBOL(SCM_CADR(spec));
657 exported_name = SCM_SYMBOL(SCM_CAR(SCM_CDDR(spec)));
658 }
659 ScmDictEntry *e = Scm_HashCoreSearch(SCM_HASH_TABLE_CORE(module->external),
660 (intptr_t)exported_name, SCM_DICT_GET);
661 if (e) {
662 /* If we have e, it's already exported. Check if
663 the previous export is for the same binding. */
664 SCM_ASSERT(SCM_DICT_VALUE(e) && SCM_GLOCP(SCM_DICT_VALUE(e)));
665 ScmGloc *g = SCM_GLOC(SCM_DICT_VALUE(e));
666 if (!SCM_EQ(name, g->name)) {
667 /* exported_name got a different meaning. we record it to warn
668 later, then 'unexport' the old one. */
669 overwritten = Scm_Cons(SCM_LIST3(SCM_OBJ(exported_name),
670 SCM_OBJ(g->name),
671 SCM_OBJ(name)),
672 overwritten);
673 Scm_HashCoreSearch(SCM_HASH_TABLE_CORE(module->external),
674 (intptr_t)exported_name, SCM_DICT_DELETE);
675 e = NULL;
676 }
677 }
678 /* we check again, for the symbol may be unexported above. */
679 if (e == NULL) {
680 /* This symbol hasn't been exported. Either it only has an
681 internal binding, or there's no binding at all. In the latter
682 case, we create a new binding (without value). */
683 e = Scm_HashCoreSearch(SCM_HASH_TABLE_CORE(module->internal),
684 (intptr_t)name, SCM_DICT_CREATE);
685 if (!e->value) {
686 ScmGloc *g = SCM_GLOC(Scm_MakeGloc(name, module));
687 (void)SCM_DICT_SET_VALUE(e, SCM_OBJ(g));
688 }
689 Scm_HashTableSet(module->external, SCM_OBJ(exported_name),
690 SCM_DICT_VALUE(e), 0);
691 }
692 }
693 (void)SCM_INTERNAL_MUTEX_UNLOCK(modules.mutex);
694
695 /* Now, if this export changes the meaning of exported symbols, we
696 warn it. We expect this only happens at the development time, when
697 one is fiddling exports incrementally, so we just use Scm_Warn -
698 a library ready to be used shouldn't cause this warning. */
699 if (!SCM_NULLP(overwritten)) {
700 ScmObj lp;
701 SCM_FOR_EACH(lp, overwritten) {
702 ScmObj p = SCM_CAR(lp);
703 Scm_Warn("Exporting %S from %S as %S overrides the previous export of %S",
704 SCM_CAR(SCM_CDDR(p)), SCM_OBJ(module), SCM_CAR(p),
705 SCM_CADR(p));
706 }
707 }
708
709 return SCM_UNDEFINED; /* we might want to return something more useful...*/
710 }
711
Scm_ExportAll(ScmModule * module)712 ScmObj Scm_ExportAll(ScmModule *module)
713 {
714 (void)SCM_INTERNAL_MUTEX_LOCK(modules.mutex);
715 if (!module->exportAll) {
716 /* Mark the module 'export-all' so that the new bindings would get
717 exported mark by default. */
718 module->exportAll = TRUE;
719
720 /* Scan the module and mark all existing bindings as exported. */
721 ScmHashIter iter;
722 Scm_HashIterInit(&iter, SCM_HASH_TABLE_CORE(module->internal));
723 ScmDictEntry *e;
724 while ((e = Scm_HashIterNext(&iter)) != NULL) {
725 ScmDictEntry *ee;
726 ee = Scm_HashCoreSearch(SCM_HASH_TABLE_CORE(module->external),
727 e->key, SCM_DICT_CREATE);
728 if (!ee->value) {
729 (void)SCM_DICT_SET_VALUE(ee, SCM_DICT_VALUE(e));
730 }
731 }
732 }
733 (void)SCM_INTERNAL_MUTEX_UNLOCK(modules.mutex);
734 return SCM_OBJ(module);
735 }
736
737 /* Returns list of exported symbols. We assume this is infrequent
738 operation, so we build the list every call. If it becomes a problem,
739 we can cache the result. */
Scm_ModuleExports(ScmModule * module)740 ScmObj Scm_ModuleExports(ScmModule *module)
741 {
742 ScmObj h = SCM_NIL, t = SCM_NIL;
743
744 (void)SCM_INTERNAL_MUTEX_LOCK(modules.mutex);
745 ScmHashIter iter;
746 Scm_HashIterInit(&iter, SCM_HASH_TABLE_CORE(module->external));
747 ScmDictEntry *e;
748 while ((e = Scm_HashIterNext(&iter)) != NULL) {
749 SCM_APPEND1(h, t, SCM_DICT_KEY(e));
750 }
751 (void)SCM_INTERNAL_MUTEX_UNLOCK(modules.mutex);
752 return h;
753 }
754
755 /*----------------------------------------------------------------------
756 * Extending (inheriting) modules
757 */
758
759 /* Module inheritance obeys the same rule as class inheritance,
760 hence we use monotonic merge. */
761 /* NB: ExtendModule alters module's precedence list, and may cause
762 unwanted side effects when used carelessly. */
763
Scm_ExtendModule(ScmModule * module,ScmObj supers)764 ScmObj Scm_ExtendModule(ScmModule *module, ScmObj supers)
765 {
766 if (module->sealed) {
767 Scm_Error("Attempt to extend a sealed module: %S", SCM_OBJ(module));
768 }
769
770 ScmObj seqh = SCM_NIL, seqt = SCM_NIL;
771 ScmObj sp;
772 SCM_FOR_EACH(sp, supers) {
773 if (!SCM_MODULEP(SCM_CAR(sp))) {
774 Scm_Error("non-module object found in the extend syntax: %S",
775 SCM_CAR(sp));
776 }
777 SCM_APPEND1(seqh, seqt, SCM_MODULE(SCM_CAR(sp))->mpl);
778 }
779 SCM_APPEND1(seqh, seqt, supers);
780 module->parents = supers;
781 ScmObj mpl = Scm_MonotonicMerge1(seqh);
782 if (SCM_FALSEP(mpl)) {
783 Scm_Error("can't extend those modules simultaneously because of inconsistent precedence lists: %S", supers);
784 }
785 module->mpl = Scm_Cons(SCM_OBJ(module), mpl);
786 return module->mpl;
787 }
788
789 /*----------------------------------------------------------------------
790 * Module sealing
791 */
792
793 /* NB: In general it is a bad idea to "unseal" module, so we only
794 provide an API to make module sealed. However, unsealing might
795 be useful for debugging. */
Scm_ModuleSeal(ScmModule * module)796 void Scm_ModuleSeal(ScmModule *module)
797 {
798 module->sealed = TRUE;
799 }
800
801 /*----------------------------------------------------------------------
802 * Finding modules
803 */
804
Scm_FindModule(ScmSymbol * name,int flags)805 ScmModule *Scm_FindModule(ScmSymbol *name, int flags)
806 {
807 if (flags & SCM_FIND_MODULE_CREATE) {
808 int created;
809 ScmModule *m = lookup_module_create(name, &created);
810 SCM_ASSERT(m != NULL);
811 /* If the module is ever called with CREATE and PLACEHOLDING flag,
812 turn placeholding flag on. The flag is cleared if the module
813 is ever called with CREATE but without PLACEHOLDING. */
814 if (created && (flags & SCM_FIND_MODULE_PLACEHOLDING)) {
815 m->placeholding = TRUE;
816 }
817 if (!(flags & SCM_FIND_MODULE_PLACEHOLDING)) {
818 m->placeholding = FALSE;
819 }
820 return m;
821 } else {
822 ScmModule *m = lookup_module(name);
823 if (m == NULL) {
824 if (!(flags & SCM_FIND_MODULE_QUIET)) {
825 Scm_Error("no such module: %S", name);
826 }
827 return NULL;
828 } else {
829 return m;
830 }
831 }
832 }
833
Scm_AllModules(void)834 ScmObj Scm_AllModules(void)
835 {
836 ScmObj h = SCM_NIL, t = SCM_NIL;
837 ScmHashIter iter;
838 ScmDictEntry *e;
839
840 (void)SCM_INTERNAL_MUTEX_LOCK(modules.mutex);
841 Scm_HashIterInit(&iter, SCM_HASH_TABLE_CORE(modules.table));
842 while ((e = Scm_HashIterNext(&iter)) != NULL) {
843 ScmModule *m = SCM_MODULE(SCM_DICT_VALUE(e));
844 if (!m->placeholding) {
845 SCM_APPEND1(h, t, SCM_DICT_VALUE(e));
846 }
847 }
848 (void)SCM_INTERNAL_MUTEX_UNLOCK(modules.mutex);
849 return h;
850 }
851
Scm_SelectModule(ScmModule * mod)852 void Scm_SelectModule(ScmModule *mod)
853 {
854 SCM_ASSERT(SCM_MODULEP(mod));
855 Scm_VM()->module = mod;
856 }
857
858 /*----------------------------------------------------------------------
859 * Module and pathnames
860 */
861
862 /* Convert module name and pathname (mod load-path) and vice versa.
863 We moved the definition in Scheme. These are just stubs to call them. */
Scm_ModuleNameToPath(ScmSymbol * name)864 ScmObj Scm_ModuleNameToPath(ScmSymbol *name)
865 {
866 static ScmObj module_name_to_path_proc = SCM_UNDEFINED;
867 SCM_BIND_PROC(module_name_to_path_proc, "module-name->path", Scm_GaucheModule());
868 return Scm_ApplyRec1(module_name_to_path_proc, SCM_OBJ(name));
869 }
870
Scm_PathToModuleName(ScmString * path)871 ScmObj Scm_PathToModuleName(ScmString *path)
872 {
873 static ScmObj path_to_module_name_proc = SCM_UNDEFINED;
874 SCM_BIND_PROC(path_to_module_name_proc, "path->module-name", Scm_GaucheModule());
875 return Scm_ApplyRec1(path_to_module_name_proc, SCM_OBJ(path));
876 }
877
878 /*----------------------------------------------------------------------
879 * Predefined modules and initialization
880 */
881
Scm_NullModule(void)882 ScmModule *Scm_NullModule(void)
883 {
884 return &nullModule;
885 }
886
Scm_SchemeModule(void)887 ScmModule *Scm_SchemeModule(void)
888 {
889 return &schemeModule;
890 }
891
Scm_GaucheModule(void)892 ScmModule *Scm_GaucheModule(void)
893 {
894 return &gaucheModule;
895 }
896
Scm_GaucheInternalModule(void)897 ScmModule *Scm_GaucheInternalModule(void)
898 {
899 return &internalModule;
900 }
901
Scm_UserModule(void)902 ScmModule *Scm_UserModule(void)
903 {
904 return &userModule;
905 }
906
Scm__KeywordModule(void)907 ScmModule *Scm__KeywordModule(void) /* internal */
908 {
909 return &keywordModule;
910 }
911
Scm__GaucheKeywordModule(void)912 ScmModule *Scm__GaucheKeywordModule(void) /* internal */
913 {
914 return &gkeywordModule;
915 }
916
Scm__RequireBaseModule(void)917 ScmModule *Scm__RequireBaseModule(void) /* internal */
918 {
919 return &reqbaseModule;
920 }
921
Scm_CurrentModule(void)922 ScmModule *Scm_CurrentModule(void)
923 {
924 return Scm_VM()->module;
925 }
926
927 /* NB: we don't need to lock the global module table in initialization */
928 #define INIT_MOD(mod, mname, mpl, inttab) \
929 do { \
930 SCM_SET_CLASS(&mod, SCM_CLASS_MODULE); \
931 init_module(&mod, mname, inttab); \
932 Scm_HashTableSet(modules.table, (mod).name, SCM_OBJ(&mod), 0); \
933 mod.parents = (SCM_NULLP(mpl)? SCM_NIL : SCM_LIST1(SCM_CAR(mpl))); \
934 mpl = mod.mpl = Scm_Cons(SCM_OBJ(&mod), mpl); \
935 } while (0)
936
Scm__InitModule(void)937 void Scm__InitModule(void)
938 {
939 /* List of builtin modules. We create these so that 'use' or r7rs 'import'
940 won't try to search the file.
941 The modules listed here are marked "provided" at the startup, so it can
942 no longer be loaded by 'use' or 'require'. Don't list modules that
943 needs to be loaded.
944 */
945 static const char *builtin_modules[] = {
946 "srfi-2", "srfi-6", "srfi-8", "srfi-10", "srfi-16", "srfi-17",
947 "srfi-22", "srfi-23", "srfi-28", "srfi-34",
948 "srfi-35", "srfi-36", "srfi-38", "srfi-45", "srfi-61",
949 "srfi-62", "srfi-87", "srfi-95", "srfi-111",
950 NULL };
951 const char **modname;
952
953 (void)SCM_INTERNAL_MUTEX_INIT(modules.mutex);
954 modules.table = SCM_HASH_TABLE(Scm_MakeHashTableSimple(SCM_HASH_EQ, 64));
955
956 /* standard module chain */
957 ScmObj mpl = SCM_NIL;
958 INIT_MOD(nullModule, SCM_SYM_NULL, mpl, NULL);
959 INIT_MOD(schemeModule, SCM_SYM_SCHEME, mpl, NULL);
960 INIT_MOD(keywordModule, SCM_SYM_KEYWORD, mpl, NULL);
961 INIT_MOD(gaucheModule, SCM_SYM_GAUCHE, mpl, NULL);
962 INIT_MOD(gfModule, SCM_SYM_GAUCHE_GF, mpl, NULL);
963 INIT_MOD(userModule, SCM_SYM_USER, mpl, NULL);
964
965 mpl = SCM_CDR(mpl); /* default mpl doesn't include user module */
966 defaultParents = SCM_LIST1(SCM_CAR(mpl));
967 defaultMpl = mpl;
968
969 /* other modules */
970 mpl = defaultMpl;
971 INIT_MOD(internalModule, SCM_SYM_GAUCHE_INTERNAL, mpl, NULL);
972 INIT_MOD(reqbaseModule, SCM_INTERN("gauche.require-base"), mpl, NULL);
973 Scm_ModuleSeal(&reqbaseModule);
974
975 mpl = keywordModule.mpl;
976 INIT_MOD(gkeywordModule, SCM_INTERN("gauche.keyword"), mpl,
977 keywordModule.internal);
978 gkeywordModule.exportAll = TRUE;
979
980 /* create predefined moudles */
981 for (modname = builtin_modules; *modname; modname++) {
982 (void)SCM_FIND_MODULE(*modname, SCM_FIND_MODULE_CREATE);
983 }
984 }
985