char/avril

(wip) why'd you have to go and make things so complicaaaaated?

git clone https://git.t4t.associates/char/avril

Charlotte Somrearrange libs into lib and extensions into extsf4a0f5b

main
3.3 KiB96 linesraw
1use std::rc::Rc;
2use std::sync::Arc;
3
4use avril_core::{Op, Runtime, RuntimeOptions, Snapshot};
5
6use super::{Settings, WorkerScope, extensions};
7use crate::authority::SourceAuthority;
8use crate::caps::{Capabilities, Initial};
9use crate::modules::ModuleGraph;
10use crate::registry::{Options, PackageStore};
11use avril_ext_process::SignalMode;
12use avril_ext_stdio::Stdio;
13use avril_host::Host;
14use avril_host::environment::Environment;
15
16#[derive(Debug, thiserror::Error)]
17#[error("Live operation during snapshot generation: {0}")]
18struct LiveOp(&'static str);
19
20/// Generate main and worker contexts in one artifact, without ambient guest authority.
21/// Must be the first V8 use in a dedicated generator process; live runtimes are
22/// disabled in that process so the deterministic generation seed cannot reach guests.
23pub fn create() -> Result<Snapshot, Box<dyn std::error::Error>> {
24    avril_core::initialize_snapshot_generator()?;
25    let directory = tempfile::tempdir()?;
26    let root = directory.path();
27    let host = Host::new()?;
28    let caps = Capabilities::new(Initial::new(false), root.to_owned());
29    let store = Arc::new(PackageStore::new_with_authority(
30        host.handle(),
31        Options {
32            jsr_registry: "https://jsr.invalid/".parse()?,
33            npm_registry: "https://npm.invalid/".parse()?,
34            cache: root.join("cache"),
35            lock: root.join("avril.lock"),
36            project_root: root.to_owned(),
37            offline: true,
38            frozen: false,
39            update: false,
40            ephemeral_lock: true,
41            vendor: None,
42        },
43        SourceAuthority::execute(caps.clone()),
44    )?);
45    let settings = Settings {
46        snapshot: None,
47        storage: avril_webstorage::Persistent::new(
48            root.join("storage"),
49            &root.join("avril.conf"),
50            "snapshot",
51        ),
52        caps,
53        environment: Environment::default(),
54        args: Vec::new(),
55        store: store.clone(),
56        runtime: host.handle(),
57        broker: Arc::default(),
58        process_signal: SignalMode::Run,
59    };
60    let graph = Rc::new(ModuleGraph::open_shared(
61        SourceAuthority::execute(settings.caps.clone()),
62        store,
63    ));
64    let mut layouts = Vec::new();
65    for worker in [false, true] {
66        let scope = if worker {
67            Some(WorkerScope {
68                control: Arc::default(),
69                inbox: settings.broker.pair()?.1,
70                url: "https://worker.invalid/snapshot.js".into(),
71                name: String::new(),
72            })
73        } else {
74            None
75        };
76        let mut extensions = extensions(
77            graph.clone(),
78            settings.clone(),
79            Stdio::new()?,
80            scope,
81            None,
82            None,
83        )?;
84        for extension in &mut extensions {
85            for op in &mut extension.ops {
86                // Only these operations depend solely on target and codec tables.
87                if !matches!(op.name, "op_path_platform" | "op_encoding_label") {
88                    let name = op.name;
89                    *op = Op::try_raw(name, move |_, _| Err(LiveOp(name)));
90                }
91            }
92        }
93        layouts.push(RuntimeOptions { extensions, module_loader: None });
94    }
95    Ok(Runtime::create_snapshot(layouts)?)
96}