summaryrefslogtreecommitdiff
path: root/js/src/shell/ModuleLoader.js
blob: a457d7aa44d2757b20329f4a53b7b9305d6bbbff (plain)
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
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// A basic synchronous module loader for testing the shell.

Reflect.Loader = new class {
    constructor() {
        this.registry = new Map();
        this.loadPath = getModuleLoadPath();
    }

    resolve(name) {
        if (os.path.isAbsolute(name))
            return name;

        return os.path.join(this.loadPath, name);
    }

    fetch(path) {
        return os.file.readFile(path);
    }

    loadAndParse(name) {
        let path = this.resolve(name);

        if (this.registry.has(path))
            return this.registry.get(path);

        let source = this.fetch(path);
        let module = parseModule(source, path);
        this.registry.set(path, module);
        return module;
    }

    ["import"](name, referencingInfo) {
        let module = this.loadAndParse(name);
        module.declarationInstantiation();
        return module.evaluation();
    }

    populateImportMeta(module, metaObject) {
        // For the shell, use the script's filename as the base URL.

        let path;
        if (ReflectApply(MapPrototypeHas, this.modulePaths, [module])) {
            path = ReflectApply(MapPrototypeGet, this.modulePaths, [module]);
        } else {
            path = "(unknown)";
        }
        metaObject.url = path;
    }
};

setModuleResolveHook((referencingInfo, requestName) => {
    let path = ReflectLoader.resolve(requestName, referencingInfo);
    return ReflectLoader.loadAndParse(path);
});
 
setModuleMetadataHook((module, metaObject) => {
    ReflectLoader.populateImportMeta(module, metaObject);
});
 
setModuleDynamicImportHook((referencingInfo, specifier, promise) => {
    try {
        let path = ReflectLoader.resolve(specifier, referencingInfo);
        ReflectLoader.loadAndExecute(path);
        finishDynamicModuleImport(referencingInfo, specifier, promise);
    } catch (err) {
        abortDynamicModuleImport(referencingInfo, specifier, promise, err);
    }
});