mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
feat(core): Ability to create snapshots from existing snapshots (#16597)
Co-authored-by: crowlkats <crowlkats@toaxl.com>
This commit is contained in:
parent
fedeea6dde
commit
d232746928
22 changed files with 1144 additions and 991 deletions
13
Cargo.lock
generated
13
Cargo.lock
generated
|
@ -781,25 +781,13 @@ dependencies = [
|
||||||
"data-url",
|
"data-url",
|
||||||
"deno_ast 0.21.0",
|
"deno_ast 0.21.0",
|
||||||
"deno_bench_util",
|
"deno_bench_util",
|
||||||
"deno_broadcast_channel",
|
|
||||||
"deno_cache",
|
|
||||||
"deno_console",
|
|
||||||
"deno_core",
|
"deno_core",
|
||||||
"deno_crypto",
|
|
||||||
"deno_doc",
|
"deno_doc",
|
||||||
"deno_emit",
|
"deno_emit",
|
||||||
"deno_fetch",
|
|
||||||
"deno_graph",
|
"deno_graph",
|
||||||
"deno_lint",
|
"deno_lint",
|
||||||
"deno_net",
|
|
||||||
"deno_node",
|
|
||||||
"deno_runtime",
|
"deno_runtime",
|
||||||
"deno_task_shell",
|
"deno_task_shell",
|
||||||
"deno_url",
|
|
||||||
"deno_web",
|
|
||||||
"deno_webgpu",
|
|
||||||
"deno_websocket",
|
|
||||||
"deno_webstorage",
|
|
||||||
"dissimilar",
|
"dissimilar",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"dprint-plugin-json",
|
"dprint-plugin-json",
|
||||||
|
@ -822,6 +810,7 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"lsp-types",
|
"lsp-types",
|
||||||
|
"lzzzz",
|
||||||
"mitata",
|
"mitata",
|
||||||
"monch",
|
"monch",
|
||||||
"napi_sym",
|
"napi_sym",
|
||||||
|
|
|
@ -26,25 +26,16 @@ harness = false
|
||||||
path = "./bench/lsp_bench_standalone.rs"
|
path = "./bench/lsp_bench_standalone.rs"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
deno_broadcast_channel = { version = "0.72.0", path = "../ext/broadcast_channel" }
|
deno_runtime = { version = "0.86.0", path = "../runtime" }
|
||||||
deno_cache = { version = "0.10.0", path = "../ext/cache" }
|
|
||||||
deno_console = { version = "0.78.0", path = "../ext/console" }
|
|
||||||
deno_core = { version = "0.160.0", path = "../core" }
|
deno_core = { version = "0.160.0", path = "../core" }
|
||||||
deno_crypto = { version = "0.92.0", path = "../ext/crypto" }
|
|
||||||
deno_fetch = { version = "0.101.0", path = "../ext/fetch" }
|
|
||||||
deno_net = { version = "0.70.0", path = "../ext/net" }
|
|
||||||
deno_node = { version = "0.15.0", path = "../ext/node" }
|
|
||||||
deno_url = { version = "0.78.0", path = "../ext/url" }
|
|
||||||
deno_web = { version = "0.109.0", path = "../ext/web" }
|
|
||||||
deno_webgpu = { version = "0.79.0", path = "../ext/webgpu" }
|
|
||||||
deno_websocket = { version = "0.83.0", path = "../ext/websocket" }
|
|
||||||
deno_webstorage = { version = "0.73.0", path = "../ext/webstorage" }
|
|
||||||
regex = "=1.6.0"
|
regex = "=1.6.0"
|
||||||
serde = { version = "=1.0.144", features = ["derive"] }
|
serde = { version = "=1.0.144", features = ["derive"] }
|
||||||
serde_json = "1.0.64"
|
serde_json = "1.0.64"
|
||||||
zstd = '=0.11.2'
|
zstd = '=0.11.2'
|
||||||
glibc_version = "0.1.2"
|
glibc_version = "0.1.2"
|
||||||
|
|
||||||
|
lzzzz = '1.0'
|
||||||
|
|
||||||
[target.'cfg(windows)'.build-dependencies]
|
[target.'cfg(windows)'.build-dependencies]
|
||||||
winapi = "=0.3.9"
|
winapi = "=0.3.9"
|
||||||
winres = "=0.1.12"
|
winres = "=0.1.12"
|
||||||
|
@ -86,6 +77,7 @@ jsonc-parser = { version = "=0.21.0", features = ["serde"] }
|
||||||
libc = "=0.2.126"
|
libc = "=0.2.126"
|
||||||
log = { version = "=0.4.17", features = ["serde"] }
|
log = { version = "=0.4.17", features = ["serde"] }
|
||||||
lsp-types = "=0.93.2" # used by tower-lsp and "proposed" feature is unstable in patch releases
|
lsp-types = "=0.93.2" # used by tower-lsp and "proposed" feature is unstable in patch releases
|
||||||
|
lzzzz = '1.0'
|
||||||
mitata = "=0.0.7"
|
mitata = "=0.0.7"
|
||||||
monch = "=0.4.0"
|
monch = "=0.4.0"
|
||||||
notify = "=5.0.0"
|
notify = "=5.0.0"
|
||||||
|
|
570
cli/build.rs
570
cli/build.rs
|
@ -1,306 +1,319 @@
|
||||||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
use deno_core::error::custom_error;
|
|
||||||
use deno_core::error::AnyError;
|
|
||||||
use deno_core::op;
|
|
||||||
use deno_core::serde::Deserialize;
|
|
||||||
use deno_core::serde_json::json;
|
|
||||||
use deno_core::serde_json::Value;
|
|
||||||
use deno_core::Extension;
|
use deno_core::Extension;
|
||||||
use deno_core::JsRuntime;
|
|
||||||
use deno_core::OpState;
|
|
||||||
use deno_core::RuntimeOptions;
|
|
||||||
use regex::Regex;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
// TODO(bartlomieju): this module contains a lot of duplicated
|
use deno_core::snapshot_util::*;
|
||||||
// logic with `runtime/build.rs`, factor out to `deno_core`.
|
use deno_runtime::deno_cache::SqliteBackedCache;
|
||||||
fn create_snapshot(
|
use deno_runtime::permissions::Permissions;
|
||||||
mut js_runtime: JsRuntime,
|
use deno_runtime::*;
|
||||||
snapshot_path: &Path,
|
|
||||||
files: Vec<PathBuf>,
|
mod ts {
|
||||||
) {
|
use super::*;
|
||||||
// TODO(nayeemrmn): https://github.com/rust-lang/cargo/issues/3946 to get the
|
use crate::deno_webgpu_get_declaration;
|
||||||
// workspace root.
|
use deno_core::error::custom_error;
|
||||||
let display_root = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap();
|
use deno_core::error::AnyError;
|
||||||
for file in files {
|
use deno_core::op;
|
||||||
println!("cargo:rerun-if-changed={}", file.display());
|
use deno_core::OpState;
|
||||||
let display_path = file.strip_prefix(display_root).unwrap();
|
use regex::Regex;
|
||||||
let display_path_str = display_path.display().to_string();
|
use serde::Deserialize;
|
||||||
js_runtime
|
use serde_json::json;
|
||||||
.execute_script(
|
use serde_json::Value;
|
||||||
&("deno:".to_string() + &display_path_str.replace('\\', "/")),
|
use std::collections::HashMap;
|
||||||
&std::fs::read_to_string(&file).unwrap(),
|
use std::path::Path;
|
||||||
)
|
use std::path::PathBuf;
|
||||||
.unwrap();
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct LoadArgs {
|
||||||
|
/// The fully qualified specifier that should be loaded.
|
||||||
|
specifier: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
let snapshot = js_runtime.snapshot();
|
pub fn create_compiler_snapshot(
|
||||||
let snapshot_slice: &[u8] = &snapshot;
|
snapshot_path: PathBuf,
|
||||||
println!("Snapshot size: {}", snapshot_slice.len());
|
files: Vec<PathBuf>,
|
||||||
|
cwd: &Path,
|
||||||
let compressed_snapshot_with_size = {
|
) {
|
||||||
let mut vec = vec![];
|
// libs that are being provided by op crates.
|
||||||
|
let mut op_crate_libs = HashMap::new();
|
||||||
vec.extend_from_slice(
|
op_crate_libs.insert("deno.cache", deno_cache::get_declaration());
|
||||||
&u32::try_from(snapshot.len())
|
op_crate_libs.insert("deno.console", deno_console::get_declaration());
|
||||||
.expect("snapshot larger than 4gb")
|
op_crate_libs.insert("deno.url", deno_url::get_declaration());
|
||||||
.to_le_bytes(),
|
op_crate_libs.insert("deno.web", deno_web::get_declaration());
|
||||||
|
op_crate_libs.insert("deno.fetch", deno_fetch::get_declaration());
|
||||||
|
op_crate_libs.insert("deno.webgpu", deno_webgpu_get_declaration());
|
||||||
|
op_crate_libs.insert("deno.websocket", deno_websocket::get_declaration());
|
||||||
|
op_crate_libs.insert("deno.webstorage", deno_webstorage::get_declaration());
|
||||||
|
op_crate_libs.insert("deno.crypto", deno_crypto::get_declaration());
|
||||||
|
op_crate_libs.insert(
|
||||||
|
"deno.broadcast_channel",
|
||||||
|
deno_broadcast_channel::get_declaration(),
|
||||||
);
|
);
|
||||||
|
op_crate_libs.insert("deno.net", deno_net::get_declaration());
|
||||||
|
|
||||||
vec.extend_from_slice(
|
// ensure we invalidate the build properly.
|
||||||
&zstd::bulk::compress(snapshot_slice, 22)
|
for (_, path) in op_crate_libs.iter() {
|
||||||
.expect("snapshot compression failed"),
|
println!("cargo:rerun-if-changed={}", path.display());
|
||||||
);
|
}
|
||||||
|
|
||||||
vec
|
// libs that should be loaded into the isolate before snapshotting.
|
||||||
};
|
let libs = vec![
|
||||||
|
// Deno custom type libraries
|
||||||
|
"deno.window",
|
||||||
|
"deno.worker",
|
||||||
|
"deno.shared_globals",
|
||||||
|
"deno.ns",
|
||||||
|
"deno.unstable",
|
||||||
|
// Deno built-in type libraries
|
||||||
|
"es5",
|
||||||
|
"es2015.collection",
|
||||||
|
"es2015.core",
|
||||||
|
"es2015",
|
||||||
|
"es2015.generator",
|
||||||
|
"es2015.iterable",
|
||||||
|
"es2015.promise",
|
||||||
|
"es2015.proxy",
|
||||||
|
"es2015.reflect",
|
||||||
|
"es2015.symbol",
|
||||||
|
"es2015.symbol.wellknown",
|
||||||
|
"es2016.array.include",
|
||||||
|
"es2016",
|
||||||
|
"es2017",
|
||||||
|
"es2017.intl",
|
||||||
|
"es2017.object",
|
||||||
|
"es2017.sharedmemory",
|
||||||
|
"es2017.string",
|
||||||
|
"es2017.typedarrays",
|
||||||
|
"es2018.asyncgenerator",
|
||||||
|
"es2018.asynciterable",
|
||||||
|
"es2018",
|
||||||
|
"es2018.intl",
|
||||||
|
"es2018.promise",
|
||||||
|
"es2018.regexp",
|
||||||
|
"es2019.array",
|
||||||
|
"es2019",
|
||||||
|
"es2019.object",
|
||||||
|
"es2019.string",
|
||||||
|
"es2019.symbol",
|
||||||
|
"es2020.bigint",
|
||||||
|
"es2020",
|
||||||
|
"es2020.date",
|
||||||
|
"es2020.intl",
|
||||||
|
"es2020.number",
|
||||||
|
"es2020.promise",
|
||||||
|
"es2020.sharedmemory",
|
||||||
|
"es2020.string",
|
||||||
|
"es2020.symbol.wellknown",
|
||||||
|
"es2021",
|
||||||
|
"es2021.intl",
|
||||||
|
"es2021.promise",
|
||||||
|
"es2021.string",
|
||||||
|
"es2021.weakref",
|
||||||
|
"es2022",
|
||||||
|
"es2022.array",
|
||||||
|
"es2022.error",
|
||||||
|
"es2022.intl",
|
||||||
|
"es2022.object",
|
||||||
|
"es2022.string",
|
||||||
|
"esnext",
|
||||||
|
"esnext.array",
|
||||||
|
"esnext.intl",
|
||||||
|
];
|
||||||
|
|
||||||
println!(
|
let path_dts = cwd.join("dts");
|
||||||
"Snapshot compressed size: {}",
|
// ensure we invalidate the build properly.
|
||||||
compressed_snapshot_with_size.len()
|
for name in libs.iter() {
|
||||||
);
|
println!(
|
||||||
|
"cargo:rerun-if-changed={}",
|
||||||
|
path_dts.join(format!("lib.{}.d.ts", name)).display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
std::fs::write(snapshot_path, compressed_snapshot_with_size).unwrap();
|
// create a copy of the vector that includes any op crate libs to be passed
|
||||||
println!("Snapshot written to: {} ", snapshot_path.display());
|
// to the JavaScript compiler to build into the snapshot
|
||||||
}
|
let mut build_libs = libs.clone();
|
||||||
|
for (op_lib, _) in op_crate_libs.iter() {
|
||||||
|
build_libs.push(op_lib.to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[op]
|
||||||
struct LoadArgs {
|
fn op_build_info(state: &mut OpState) -> Value {
|
||||||
/// The fully qualified specifier that should be loaded.
|
let build_specifier = "asset:///bootstrap.ts";
|
||||||
specifier: String,
|
let build_libs = state.borrow::<Vec<&str>>();
|
||||||
}
|
json!({
|
||||||
|
"buildSpecifier": build_specifier,
|
||||||
|
"libs": build_libs,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn create_compiler_snapshot(
|
#[op]
|
||||||
snapshot_path: &Path,
|
fn op_cwd() -> String {
|
||||||
files: Vec<PathBuf>,
|
"cache:///".into()
|
||||||
cwd: &Path,
|
}
|
||||||
) {
|
|
||||||
// libs that are being provided by op crates.
|
|
||||||
let mut op_crate_libs = HashMap::new();
|
|
||||||
op_crate_libs.insert("deno.cache", deno_cache::get_declaration());
|
|
||||||
op_crate_libs.insert("deno.console", deno_console::get_declaration());
|
|
||||||
op_crate_libs.insert("deno.url", deno_url::get_declaration());
|
|
||||||
op_crate_libs.insert("deno.web", deno_web::get_declaration());
|
|
||||||
op_crate_libs.insert("deno.fetch", deno_fetch::get_declaration());
|
|
||||||
op_crate_libs.insert("deno.webgpu", deno_webgpu_get_declaration());
|
|
||||||
op_crate_libs.insert("deno.websocket", deno_websocket::get_declaration());
|
|
||||||
op_crate_libs.insert("deno.webstorage", deno_webstorage::get_declaration());
|
|
||||||
op_crate_libs.insert("deno.crypto", deno_crypto::get_declaration());
|
|
||||||
op_crate_libs.insert(
|
|
||||||
"deno.broadcast_channel",
|
|
||||||
deno_broadcast_channel::get_declaration(),
|
|
||||||
);
|
|
||||||
op_crate_libs.insert("deno.net", deno_net::get_declaration());
|
|
||||||
|
|
||||||
// ensure we invalidate the build properly.
|
#[op]
|
||||||
for (_, path) in op_crate_libs.iter() {
|
fn op_exists() -> bool {
|
||||||
println!("cargo:rerun-if-changed={}", path.display());
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
// libs that should be loaded into the isolate before snapshotting.
|
#[op]
|
||||||
let libs = vec![
|
fn op_is_node_file() -> bool {
|
||||||
// Deno custom type libraries
|
false
|
||||||
"deno.window",
|
}
|
||||||
"deno.worker",
|
|
||||||
"deno.shared_globals",
|
|
||||||
"deno.ns",
|
|
||||||
"deno.unstable",
|
|
||||||
// Deno built-in type libraries
|
|
||||||
"es5",
|
|
||||||
"es2015.collection",
|
|
||||||
"es2015.core",
|
|
||||||
"es2015",
|
|
||||||
"es2015.generator",
|
|
||||||
"es2015.iterable",
|
|
||||||
"es2015.promise",
|
|
||||||
"es2015.proxy",
|
|
||||||
"es2015.reflect",
|
|
||||||
"es2015.symbol",
|
|
||||||
"es2015.symbol.wellknown",
|
|
||||||
"es2016.array.include",
|
|
||||||
"es2016",
|
|
||||||
"es2017",
|
|
||||||
"es2017.intl",
|
|
||||||
"es2017.object",
|
|
||||||
"es2017.sharedmemory",
|
|
||||||
"es2017.string",
|
|
||||||
"es2017.typedarrays",
|
|
||||||
"es2018.asyncgenerator",
|
|
||||||
"es2018.asynciterable",
|
|
||||||
"es2018",
|
|
||||||
"es2018.intl",
|
|
||||||
"es2018.promise",
|
|
||||||
"es2018.regexp",
|
|
||||||
"es2019.array",
|
|
||||||
"es2019",
|
|
||||||
"es2019.object",
|
|
||||||
"es2019.string",
|
|
||||||
"es2019.symbol",
|
|
||||||
"es2020.bigint",
|
|
||||||
"es2020",
|
|
||||||
"es2020.date",
|
|
||||||
"es2020.intl",
|
|
||||||
"es2020.number",
|
|
||||||
"es2020.promise",
|
|
||||||
"es2020.sharedmemory",
|
|
||||||
"es2020.string",
|
|
||||||
"es2020.symbol.wellknown",
|
|
||||||
"es2021",
|
|
||||||
"es2021.intl",
|
|
||||||
"es2021.promise",
|
|
||||||
"es2021.string",
|
|
||||||
"es2021.weakref",
|
|
||||||
"es2022",
|
|
||||||
"es2022.array",
|
|
||||||
"es2022.error",
|
|
||||||
"es2022.intl",
|
|
||||||
"es2022.object",
|
|
||||||
"es2022.string",
|
|
||||||
"esnext",
|
|
||||||
"esnext.array",
|
|
||||||
"esnext.intl",
|
|
||||||
];
|
|
||||||
|
|
||||||
let path_dts = cwd.join("dts");
|
#[op]
|
||||||
// ensure we invalidate the build properly.
|
fn op_script_version(
|
||||||
for name in libs.iter() {
|
_state: &mut OpState,
|
||||||
println!(
|
_args: Value,
|
||||||
"cargo:rerun-if-changed={}",
|
) -> Result<Option<String>, AnyError> {
|
||||||
path_dts.join(format!("lib.{}.d.ts", name)).display()
|
Ok(Some("1".to_string()))
|
||||||
);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// create a copy of the vector that includes any op crate libs to be passed
|
#[op]
|
||||||
// to the JavaScript compiler to build into the snapshot
|
// using the same op that is used in `tsc.rs` for loading modules and reading
|
||||||
let mut build_libs = libs.clone();
|
// files, but a slightly different implementation at build time.
|
||||||
for (op_lib, _) in op_crate_libs.iter() {
|
fn op_load(state: &mut OpState, args: LoadArgs) -> Result<Value, AnyError> {
|
||||||
build_libs.push(op_lib.to_owned());
|
let op_crate_libs = state.borrow::<HashMap<&str, PathBuf>>();
|
||||||
}
|
let path_dts = state.borrow::<PathBuf>();
|
||||||
|
let re_asset =
|
||||||
|
Regex::new(r"asset:/{3}lib\.(\S+)\.d\.ts").expect("bad regex");
|
||||||
|
let build_specifier = "asset:///bootstrap.ts";
|
||||||
|
|
||||||
#[op]
|
// we need a basic file to send to tsc to warm it up.
|
||||||
fn op_build_info(state: &mut OpState) -> Value {
|
if args.specifier == build_specifier {
|
||||||
let build_specifier = "asset:///bootstrap.ts";
|
|
||||||
let build_libs = state.borrow::<Vec<&str>>();
|
|
||||||
json!({
|
|
||||||
"buildSpecifier": build_specifier,
|
|
||||||
"libs": build_libs,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[op]
|
|
||||||
fn op_cwd() -> String {
|
|
||||||
"cache:///".into()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[op]
|
|
||||||
fn op_exists() -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
#[op]
|
|
||||||
fn op_is_node_file() -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
#[op]
|
|
||||||
fn op_script_version(
|
|
||||||
_state: &mut OpState,
|
|
||||||
_args: Value,
|
|
||||||
) -> Result<Option<String>, AnyError> {
|
|
||||||
Ok(Some("1".to_string()))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[op]
|
|
||||||
// using the same op that is used in `tsc.rs` for loading modules and reading
|
|
||||||
// files, but a slightly different implementation at build time.
|
|
||||||
fn op_load(state: &mut OpState, args: LoadArgs) -> Result<Value, AnyError> {
|
|
||||||
let op_crate_libs = state.borrow::<HashMap<&str, PathBuf>>();
|
|
||||||
let path_dts = state.borrow::<PathBuf>();
|
|
||||||
let re_asset =
|
|
||||||
Regex::new(r"asset:/{3}lib\.(\S+)\.d\.ts").expect("bad regex");
|
|
||||||
let build_specifier = "asset:///bootstrap.ts";
|
|
||||||
|
|
||||||
// we need a basic file to send to tsc to warm it up.
|
|
||||||
if args.specifier == build_specifier {
|
|
||||||
Ok(json!({
|
|
||||||
"data": r#"console.log("hello deno!");"#,
|
|
||||||
"version": "1",
|
|
||||||
// this corresponds to `ts.ScriptKind.TypeScript`
|
|
||||||
"scriptKind": 3
|
|
||||||
}))
|
|
||||||
// specifiers come across as `asset:///lib.{lib_name}.d.ts` and we need to
|
|
||||||
// parse out just the name so we can lookup the asset.
|
|
||||||
} else if let Some(caps) = re_asset.captures(&args.specifier) {
|
|
||||||
if let Some(lib) = caps.get(1).map(|m| m.as_str()) {
|
|
||||||
// if it comes from an op crate, we were supplied with the path to the
|
|
||||||
// file.
|
|
||||||
let path = if let Some(op_crate_lib) = op_crate_libs.get(lib) {
|
|
||||||
PathBuf::from(op_crate_lib).canonicalize().unwrap()
|
|
||||||
// otherwise we are will generate the path ourself
|
|
||||||
} else {
|
|
||||||
path_dts.join(format!("lib.{}.d.ts", lib))
|
|
||||||
};
|
|
||||||
let data = std::fs::read_to_string(path)?;
|
|
||||||
Ok(json!({
|
Ok(json!({
|
||||||
"data": data,
|
"data": r#"console.log("hello deno!");"#,
|
||||||
"version": "1",
|
"version": "1",
|
||||||
// this corresponds to `ts.ScriptKind.TypeScript`
|
// this corresponds to `ts.ScriptKind.TypeScript`
|
||||||
"scriptKind": 3
|
"scriptKind": 3
|
||||||
}))
|
}))
|
||||||
|
// specifiers come across as `asset:///lib.{lib_name}.d.ts` and we need to
|
||||||
|
// parse out just the name so we can lookup the asset.
|
||||||
|
} else if let Some(caps) = re_asset.captures(&args.specifier) {
|
||||||
|
if let Some(lib) = caps.get(1).map(|m| m.as_str()) {
|
||||||
|
// if it comes from an op crate, we were supplied with the path to the
|
||||||
|
// file.
|
||||||
|
let path = if let Some(op_crate_lib) = op_crate_libs.get(lib) {
|
||||||
|
PathBuf::from(op_crate_lib).canonicalize().unwrap()
|
||||||
|
// otherwise we are will generate the path ourself
|
||||||
|
} else {
|
||||||
|
path_dts.join(format!("lib.{}.d.ts", lib))
|
||||||
|
};
|
||||||
|
let data = std::fs::read_to_string(path)?;
|
||||||
|
Ok(json!({
|
||||||
|
"data": data,
|
||||||
|
"version": "1",
|
||||||
|
// this corresponds to `ts.ScriptKind.TypeScript`
|
||||||
|
"scriptKind": 3
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
Err(custom_error(
|
||||||
|
"InvalidSpecifier",
|
||||||
|
format!("An invalid specifier was requested: {}", args.specifier),
|
||||||
|
))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(custom_error(
|
Err(custom_error(
|
||||||
"InvalidSpecifier",
|
"InvalidSpecifier",
|
||||||
format!("An invalid specifier was requested: {}", args.specifier),
|
format!("An invalid specifier was requested: {}", args.specifier),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Err(custom_error(
|
|
||||||
"InvalidSpecifier",
|
|
||||||
format!("An invalid specifier was requested: {}", args.specifier),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
create_snapshot(CreateSnapshotOptions {
|
||||||
|
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
|
||||||
|
snapshot_path,
|
||||||
|
startup_snapshot: None,
|
||||||
|
extensions: vec![Extension::builder()
|
||||||
|
.ops(vec![
|
||||||
|
op_build_info::decl(),
|
||||||
|
op_cwd::decl(),
|
||||||
|
op_exists::decl(),
|
||||||
|
op_is_node_file::decl(),
|
||||||
|
op_load::decl(),
|
||||||
|
op_script_version::decl(),
|
||||||
|
])
|
||||||
|
.state(move |state| {
|
||||||
|
state.put(op_crate_libs.clone());
|
||||||
|
state.put(build_libs.clone());
|
||||||
|
state.put(path_dts.clone());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
.build()],
|
||||||
|
additional_files: files,
|
||||||
|
compression_cb: Some(Box::new(|vec, snapshot_slice| {
|
||||||
|
vec.extend_from_slice(
|
||||||
|
&zstd::bulk::compress(snapshot_slice, 22)
|
||||||
|
.expect("snapshot compression failed"),
|
||||||
|
);
|
||||||
|
})),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
let js_runtime = JsRuntime::new(RuntimeOptions {
|
|
||||||
will_snapshot: true,
|
|
||||||
extensions: vec![Extension::builder()
|
|
||||||
.ops(vec![
|
|
||||||
op_build_info::decl(),
|
|
||||||
op_cwd::decl(),
|
|
||||||
op_exists::decl(),
|
|
||||||
op_is_node_file::decl(),
|
|
||||||
op_load::decl(),
|
|
||||||
op_script_version::decl(),
|
|
||||||
])
|
|
||||||
.state(move |state| {
|
|
||||||
state.put(op_crate_libs.clone());
|
|
||||||
state.put(build_libs.clone());
|
|
||||||
state.put(path_dts.clone());
|
|
||||||
|
|
||||||
Ok(())
|
pub(crate) fn version() -> String {
|
||||||
})
|
std::fs::read_to_string("tsc/00_typescript.js")
|
||||||
.build()],
|
.unwrap()
|
||||||
..Default::default()
|
.lines()
|
||||||
});
|
.find(|l| l.contains("ts.version = "))
|
||||||
|
.expect(
|
||||||
create_snapshot(js_runtime, snapshot_path, files);
|
"Failed to find the pattern `ts.version = ` in typescript source code",
|
||||||
|
)
|
||||||
|
.chars()
|
||||||
|
.skip_while(|c| !char::is_numeric(*c))
|
||||||
|
.take_while(|c| *c != '"')
|
||||||
|
.collect::<String>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ts_version() -> String {
|
fn create_cli_snapshot(snapshot_path: PathBuf, files: Vec<PathBuf>) {
|
||||||
std::fs::read_to_string("tsc/00_typescript.js")
|
let extensions: Vec<Extension> = vec![
|
||||||
.unwrap()
|
deno_webidl::init(),
|
||||||
.lines()
|
deno_console::init(),
|
||||||
.find(|l| l.contains("ts.version = "))
|
deno_url::init(),
|
||||||
.expect(
|
deno_tls::init(),
|
||||||
"Failed to find the pattern `ts.version = ` in typescript source code",
|
deno_web::init::<Permissions>(
|
||||||
)
|
deno_web::BlobStore::default(),
|
||||||
.chars()
|
Default::default(),
|
||||||
.skip_while(|c| !char::is_numeric(*c))
|
),
|
||||||
.take_while(|c| *c != '"')
|
deno_fetch::init::<Permissions>(Default::default()),
|
||||||
.collect::<String>()
|
deno_cache::init::<SqliteBackedCache>(None),
|
||||||
|
deno_websocket::init::<Permissions>("".to_owned(), None, None),
|
||||||
|
deno_webstorage::init(None),
|
||||||
|
deno_crypto::init(None),
|
||||||
|
deno_webgpu::init(false),
|
||||||
|
deno_broadcast_channel::init(
|
||||||
|
deno_broadcast_channel::InMemoryBroadcastChannel::default(),
|
||||||
|
false, // No --unstable.
|
||||||
|
),
|
||||||
|
deno_node::init::<Permissions>(None), // No --unstable.
|
||||||
|
deno_ffi::init::<Permissions>(false),
|
||||||
|
deno_net::init::<Permissions>(
|
||||||
|
None, false, // No --unstable.
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
deno_napi::init::<Permissions>(false),
|
||||||
|
deno_http::init(),
|
||||||
|
deno_flash::init::<Permissions>(false), // No --unstable
|
||||||
|
];
|
||||||
|
|
||||||
|
create_snapshot(CreateSnapshotOptions {
|
||||||
|
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
|
||||||
|
snapshot_path,
|
||||||
|
startup_snapshot: Some(deno_runtime::js::deno_isolate_init()),
|
||||||
|
extensions,
|
||||||
|
additional_files: files,
|
||||||
|
compression_cb: Some(Box::new(|vec, snapshot_slice| {
|
||||||
|
lzzzz::lz4_hc::compress_to_vec(
|
||||||
|
snapshot_slice,
|
||||||
|
vec,
|
||||||
|
lzzzz::lz4_hc::CLEVEL_MAX,
|
||||||
|
)
|
||||||
|
.expect("snapshot compression failed");
|
||||||
|
})),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn git_commit_hash() -> String {
|
fn git_commit_hash() -> String {
|
||||||
|
@ -386,7 +399,7 @@ fn main() {
|
||||||
println!("cargo:rustc-env=GIT_COMMIT_HASH={}", git_commit_hash());
|
println!("cargo:rustc-env=GIT_COMMIT_HASH={}", git_commit_hash());
|
||||||
println!("cargo:rerun-if-env-changed=GIT_COMMIT_HASH");
|
println!("cargo:rerun-if-env-changed=GIT_COMMIT_HASH");
|
||||||
|
|
||||||
println!("cargo:rustc-env=TS_VERSION={}", ts_version());
|
println!("cargo:rustc-env=TS_VERSION={}", ts::version());
|
||||||
println!("cargo:rerun-if-env-changed=TS_VERSION");
|
println!("cargo:rerun-if-env-changed=TS_VERSION");
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
|
@ -440,11 +453,14 @@ fn main() {
|
||||||
let c = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());
|
let c = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());
|
||||||
let o = PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
let o = PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||||
|
|
||||||
// Main snapshot
|
|
||||||
let compiler_snapshot_path = o.join("COMPILER_SNAPSHOT.bin");
|
let compiler_snapshot_path = o.join("COMPILER_SNAPSHOT.bin");
|
||||||
|
let js_files = get_js_files(env!("CARGO_MANIFEST_DIR"), "tsc");
|
||||||
|
ts::create_compiler_snapshot(compiler_snapshot_path, js_files, &c);
|
||||||
|
|
||||||
let js_files = get_js_files("tsc");
|
let cli_snapshot_path = o.join("CLI_SNAPSHOT.bin");
|
||||||
create_compiler_snapshot(&compiler_snapshot_path, js_files, &c);
|
let mut js_files = get_js_files(env!("CARGO_MANIFEST_DIR"), "js");
|
||||||
|
js_files.push(deno_runtime::js::get_99_main());
|
||||||
|
create_cli_snapshot(cli_snapshot_path, js_files);
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
{
|
{
|
||||||
|
@ -462,17 +478,3 @@ fn deno_webgpu_get_declaration() -> PathBuf {
|
||||||
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
|
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
|
||||||
manifest_dir.join("dts").join("lib.deno_webgpu.d.ts")
|
manifest_dir.join("dts").join("lib.deno_webgpu.d.ts")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_js_files(d: &str) -> Vec<PathBuf> {
|
|
||||||
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
|
|
||||||
let mut js_files = std::fs::read_dir(d)
|
|
||||||
.unwrap()
|
|
||||||
.map(|dir_entry| {
|
|
||||||
let file = dir_entry.unwrap();
|
|
||||||
manifest_dir.join(file.path())
|
|
||||||
})
|
|
||||||
.filter(|path| path.extension().unwrap_or_default() == "js")
|
|
||||||
.collect::<Vec<PathBuf>>();
|
|
||||||
js_files.sort();
|
|
||||||
js_files
|
|
||||||
}
|
|
||||||
|
|
57
cli/js.rs
Normal file
57
cli/js.rs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
use deno_core::Snapshot;
|
||||||
|
use log::debug;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
|
pub static CLI_SNAPSHOT: Lazy<Box<[u8]>> = Lazy::new(
|
||||||
|
#[allow(clippy::uninit_vec)]
|
||||||
|
#[cold]
|
||||||
|
#[inline(never)]
|
||||||
|
|| {
|
||||||
|
static COMPRESSED_CLI_SNAPSHOT: &[u8] =
|
||||||
|
include_bytes!(concat!(env!("OUT_DIR"), "/CLI_SNAPSHOT.bin"));
|
||||||
|
|
||||||
|
let size =
|
||||||
|
u32::from_le_bytes(COMPRESSED_CLI_SNAPSHOT[0..4].try_into().unwrap())
|
||||||
|
as usize;
|
||||||
|
let mut vec = Vec::with_capacity(size);
|
||||||
|
|
||||||
|
// SAFETY: vec is allocated with exact snapshot size (+ alignment)
|
||||||
|
// SAFETY: non zeroed bytes are overwritten with decompressed snapshot
|
||||||
|
unsafe {
|
||||||
|
vec.set_len(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
lzzzz::lz4::decompress(&COMPRESSED_CLI_SNAPSHOT[4..], &mut vec).unwrap();
|
||||||
|
|
||||||
|
vec.into_boxed_slice()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
pub fn deno_isolate_init() -> Snapshot {
|
||||||
|
debug!("Deno isolate init with snapshots.");
|
||||||
|
Snapshot::Static(&CLI_SNAPSHOT)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn runtime_snapshot() {
|
||||||
|
let mut js_runtime = deno_core::JsRuntime::new(deno_core::RuntimeOptions {
|
||||||
|
startup_snapshot: Some(deno_isolate_init()),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
js_runtime
|
||||||
|
.execute_script(
|
||||||
|
"<anon>",
|
||||||
|
r#"
|
||||||
|
if (!(bootstrap.mainRuntime && bootstrap.workerRuntime)) {
|
||||||
|
throw Error("bad");
|
||||||
|
}
|
||||||
|
console.log("we have console.log!!!");
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1397,12 +1397,16 @@
|
||||||
return testFn;
|
return testFn;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.__bootstrap.testing = {
|
window.__bootstrap.internals = {
|
||||||
bench,
|
...window.__bootstrap.internals ?? {},
|
||||||
enableBench,
|
testing: {
|
||||||
enableTest,
|
runTests,
|
||||||
runBenchmarks,
|
runBenchmarks,
|
||||||
runTests,
|
enableTest,
|
||||||
test,
|
enableBench,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
window.__bootstrap.denoNs.bench = bench;
|
||||||
|
window.__bootstrap.denoNs.test = test;
|
||||||
})(this);
|
})(this);
|
|
@ -7,7 +7,6 @@ use super::lsp_custom;
|
||||||
use crate::args::flags_from_vec;
|
use crate::args::flags_from_vec;
|
||||||
use crate::args::DenoSubcommand;
|
use crate::args::DenoSubcommand;
|
||||||
use crate::checksum;
|
use crate::checksum;
|
||||||
use crate::create_main_worker;
|
|
||||||
use crate::lsp::client::Client;
|
use crate::lsp::client::Client;
|
||||||
use crate::lsp::client::TestingNotification;
|
use crate::lsp::client::TestingNotification;
|
||||||
use crate::lsp::config;
|
use crate::lsp::config;
|
||||||
|
@ -16,6 +15,7 @@ use crate::ops;
|
||||||
use crate::proc_state;
|
use crate::proc_state;
|
||||||
use crate::tools::test;
|
use crate::tools::test;
|
||||||
use crate::tools::test::TestEventSender;
|
use crate::tools::test::TestEventSender;
|
||||||
|
use crate::worker::create_main_worker_for_test_or_bench;
|
||||||
|
|
||||||
use deno_core::anyhow::anyhow;
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
@ -154,7 +154,7 @@ async fn test_specifier(
|
||||||
filter: test::TestFilter,
|
filter: test::TestFilter,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
if !token.is_cancelled() {
|
if !token.is_cancelled() {
|
||||||
let mut worker = create_main_worker(
|
let mut worker = create_main_worker_for_test_or_bench(
|
||||||
&ps,
|
&ps,
|
||||||
specifier.clone(),
|
specifier.clone(),
|
||||||
permissions,
|
permissions,
|
||||||
|
|
35
cli/main.rs
35
cli/main.rs
|
@ -18,6 +18,7 @@ mod fs_util;
|
||||||
mod graph_util;
|
mod graph_util;
|
||||||
mod http_cache;
|
mod http_cache;
|
||||||
mod http_util;
|
mod http_util;
|
||||||
|
mod js;
|
||||||
mod lockfile;
|
mod lockfile;
|
||||||
mod logger;
|
mod logger;
|
||||||
mod lsp;
|
mod lsp;
|
||||||
|
@ -289,14 +290,8 @@ async fn eval_command(
|
||||||
resolve_url_or_path(&format!("./$deno$eval.{}", eval_flags.ext))?;
|
resolve_url_or_path(&format!("./$deno$eval.{}", eval_flags.ext))?;
|
||||||
let permissions = Permissions::from_options(&flags.permissions_options())?;
|
let permissions = Permissions::from_options(&flags.permissions_options())?;
|
||||||
let ps = ProcState::build(flags).await?;
|
let ps = ProcState::build(flags).await?;
|
||||||
let mut worker = create_main_worker(
|
let mut worker =
|
||||||
&ps,
|
create_main_worker(&ps, main_module.clone(), permissions).await?;
|
||||||
main_module.clone(),
|
|
||||||
permissions,
|
|
||||||
vec![],
|
|
||||||
Default::default(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
// Create a dummy source file.
|
// Create a dummy source file.
|
||||||
let source_code = if eval_flags.print {
|
let source_code = if eval_flags.print {
|
||||||
format!("console.log({})", eval_flags.code)
|
format!("console.log({})", eval_flags.code)
|
||||||
|
@ -602,8 +597,6 @@ async fn repl_command(
|
||||||
&ps,
|
&ps,
|
||||||
main_module.clone(),
|
main_module.clone(),
|
||||||
Permissions::from_options(&ps.options.permissions_options())?,
|
Permissions::from_options(&ps.options.permissions_options())?,
|
||||||
vec![],
|
|
||||||
Default::default(),
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
worker.setup_repl().await?;
|
worker.setup_repl().await?;
|
||||||
|
@ -623,8 +616,6 @@ async fn run_from_stdin(flags: Flags) -> Result<i32, AnyError> {
|
||||||
&ps.clone(),
|
&ps.clone(),
|
||||||
main_module.clone(),
|
main_module.clone(),
|
||||||
Permissions::from_options(&ps.options.permissions_options())?,
|
Permissions::from_options(&ps.options.permissions_options())?,
|
||||||
vec![],
|
|
||||||
Default::default(),
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
@ -664,14 +655,8 @@ async fn run_with_watch(flags: Flags, script: String) -> Result<i32, AnyError> {
|
||||||
let ps =
|
let ps =
|
||||||
ProcState::build_for_file_watcher((*flags).clone(), sender.clone())
|
ProcState::build_for_file_watcher((*flags).clone(), sender.clone())
|
||||||
.await?;
|
.await?;
|
||||||
let worker = create_main_worker(
|
let worker =
|
||||||
&ps,
|
create_main_worker(&ps, main_module.clone(), permissions).await?;
|
||||||
main_module.clone(),
|
|
||||||
permissions,
|
|
||||||
vec![],
|
|
||||||
Default::default(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
worker.run_for_watcher().await?;
|
worker.run_for_watcher().await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -722,14 +707,8 @@ async fn run_command(
|
||||||
};
|
};
|
||||||
let permissions =
|
let permissions =
|
||||||
Permissions::from_options(&ps.options.permissions_options())?;
|
Permissions::from_options(&ps.options.permissions_options())?;
|
||||||
let mut worker = create_main_worker(
|
let mut worker =
|
||||||
&ps,
|
create_main_worker(&ps, main_module.clone(), permissions).await?;
|
||||||
main_module.clone(),
|
|
||||||
permissions,
|
|
||||||
vec![],
|
|
||||||
Default::default(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let exit_code = worker.run().await?;
|
let exit_code = worker.run().await?;
|
||||||
Ok(exit_code)
|
Ok(exit_code)
|
||||||
|
|
|
@ -287,7 +287,7 @@ pub async fn run(
|
||||||
inspect: ps.options.is_inspecting(),
|
inspect: ps.options.is_inspecting(),
|
||||||
},
|
},
|
||||||
extensions: ops::cli_exts(ps.clone()),
|
extensions: ops::cli_exts(ps.clone()),
|
||||||
startup_snapshot: None,
|
startup_snapshot: Some(crate::js::deno_isolate_init()),
|
||||||
unsafely_ignore_certificate_errors: metadata
|
unsafely_ignore_certificate_errors: metadata
|
||||||
.unsafely_ignore_certificate_errors,
|
.unsafely_ignore_certificate_errors,
|
||||||
root_cert_store: Some(root_cert_store),
|
root_cert_store: Some(root_cert_store),
|
||||||
|
|
|
@ -37,13 +37,13 @@ failing step in failing test ... FAILED ([WILDCARD])
|
||||||
|
|
||||||
nested failure => ./test/steps/failing_steps.ts:[WILDCARD]
|
nested failure => ./test/steps/failing_steps.ts:[WILDCARD]
|
||||||
error: Error: 1 test step failed.
|
error: Error: 1 test step failed.
|
||||||
at runTest (deno:runtime/js/40_testing.js:[WILDCARD])
|
at runTest (deno:cli/js/40_testing.js:[WILDCARD])
|
||||||
at async runTests (deno:runtime/js/40_testing.js:[WILDCARD])
|
at async runTests (deno:cli/js/40_testing.js:[WILDCARD])
|
||||||
|
|
||||||
multiple test step failures => ./test/steps/failing_steps.ts:[WILDCARD]
|
multiple test step failures => ./test/steps/failing_steps.ts:[WILDCARD]
|
||||||
error: Error: 2 test steps failed.
|
error: Error: 2 test steps failed.
|
||||||
at runTest (deno:runtime/js/40_testing.js:[WILDCARD])
|
at runTest (deno:cli/js/40_testing.js:[WILDCARD])
|
||||||
at async runTests (deno:runtime/js/40_testing.js:[WILDCARD])
|
at async runTests (deno:cli/js/40_testing.js:[WILDCARD])
|
||||||
|
|
||||||
failing step in failing test => ./test/steps/failing_steps.ts:[WILDCARD]
|
failing step in failing test => ./test/steps/failing_steps.ts:[WILDCARD]
|
||||||
error: Error: Fail test.
|
error: Error: Fail test.
|
||||||
|
|
|
@ -4,7 +4,6 @@ use crate::args::BenchFlags;
|
||||||
use crate::args::Flags;
|
use crate::args::Flags;
|
||||||
use crate::args::TypeCheckMode;
|
use crate::args::TypeCheckMode;
|
||||||
use crate::colors;
|
use crate::colors;
|
||||||
use crate::create_main_worker;
|
|
||||||
use crate::file_watcher;
|
use crate::file_watcher;
|
||||||
use crate::file_watcher::ResolutionResult;
|
use crate::file_watcher::ResolutionResult;
|
||||||
use crate::fs_util::collect_specifiers;
|
use crate::fs_util::collect_specifiers;
|
||||||
|
@ -15,6 +14,7 @@ use crate::ops;
|
||||||
use crate::proc_state::ProcState;
|
use crate::proc_state::ProcState;
|
||||||
use crate::tools::test::format_test_error;
|
use crate::tools::test::format_test_error;
|
||||||
use crate::tools::test::TestFilter;
|
use crate::tools::test::TestFilter;
|
||||||
|
use crate::worker::create_main_worker_for_test_or_bench;
|
||||||
|
|
||||||
use deno_core::error::generic_error;
|
use deno_core::error::generic_error;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
@ -352,7 +352,7 @@ async fn bench_specifier(
|
||||||
options: BenchSpecifierOptions,
|
options: BenchSpecifierOptions,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
let filter = TestFilter::from_flag(&options.filter);
|
let filter = TestFilter::from_flag(&options.filter);
|
||||||
let mut worker = create_main_worker(
|
let mut worker = create_main_worker_for_test_or_bench(
|
||||||
&ps,
|
&ps,
|
||||||
specifier.clone(),
|
specifier.clone(),
|
||||||
permissions,
|
permissions,
|
||||||
|
|
|
@ -5,7 +5,6 @@ use crate::args::TestFlags;
|
||||||
use crate::args::TypeCheckMode;
|
use crate::args::TypeCheckMode;
|
||||||
use crate::checksum;
|
use crate::checksum;
|
||||||
use crate::colors;
|
use crate::colors;
|
||||||
use crate::create_main_worker;
|
|
||||||
use crate::display;
|
use crate::display;
|
||||||
use crate::file_fetcher::File;
|
use crate::file_fetcher::File;
|
||||||
use crate::file_watcher;
|
use crate::file_watcher;
|
||||||
|
@ -18,6 +17,7 @@ use crate::graph_util::contains_specifier;
|
||||||
use crate::graph_util::graph_valid;
|
use crate::graph_util::graph_valid;
|
||||||
use crate::ops;
|
use crate::ops;
|
||||||
use crate::proc_state::ProcState;
|
use crate::proc_state::ProcState;
|
||||||
|
use crate::worker::create_main_worker_for_test_or_bench;
|
||||||
|
|
||||||
use deno_ast::swc::common::comments::CommentKind;
|
use deno_ast::swc::common::comments::CommentKind;
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
|
@ -715,7 +715,7 @@ async fn test_specifier(
|
||||||
sender: &TestEventSender,
|
sender: &TestEventSender,
|
||||||
options: TestSpecifierOptions,
|
options: TestSpecifierOptions,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
let mut worker = create_main_worker(
|
let mut worker = create_main_worker_for_test_or_bench(
|
||||||
&ps,
|
&ps,
|
||||||
specifier.clone(),
|
specifier.clone(),
|
||||||
permissions,
|
permissions,
|
||||||
|
|
267
cli/worker.rs
267
cli/worker.rs
|
@ -7,6 +7,9 @@ use deno_core::error::AnyError;
|
||||||
use deno_core::futures::task::LocalFutureObj;
|
use deno_core::futures::task::LocalFutureObj;
|
||||||
use deno_core::futures::FutureExt;
|
use deno_core::futures::FutureExt;
|
||||||
use deno_core::located_script_name;
|
use deno_core::located_script_name;
|
||||||
|
use deno_core::serde_json::json;
|
||||||
|
use deno_core::serde_v8;
|
||||||
|
use deno_core::v8;
|
||||||
use deno_core::Extension;
|
use deno_core::Extension;
|
||||||
use deno_core::ModuleId;
|
use deno_core::ModuleId;
|
||||||
use deno_runtime::colors;
|
use deno_runtime::colors;
|
||||||
|
@ -38,6 +41,11 @@ pub struct CliMainWorker {
|
||||||
is_main_cjs: bool,
|
is_main_cjs: bool,
|
||||||
worker: MainWorker,
|
worker: MainWorker,
|
||||||
ps: ProcState,
|
ps: ProcState,
|
||||||
|
|
||||||
|
js_run_tests_callback: Option<v8::Global<v8::Function>>,
|
||||||
|
js_run_benchmarks_callback: Option<v8::Global<v8::Function>>,
|
||||||
|
js_enable_test_callback: Option<v8::Global<v8::Function>>,
|
||||||
|
js_enable_bench_callback: Option<v8::Global<v8::Function>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CliMainWorker {
|
impl CliMainWorker {
|
||||||
|
@ -168,7 +176,7 @@ impl CliMainWorker {
|
||||||
&mut self,
|
&mut self,
|
||||||
mode: TestMode,
|
mode: TestMode,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
self.worker.enable_test();
|
self.enable_test();
|
||||||
|
|
||||||
// Enable op call tracing in core to enable better debugging of op sanitizer
|
// Enable op call tracing in core to enable better debugging of op sanitizer
|
||||||
// failures.
|
// failures.
|
||||||
|
@ -194,10 +202,7 @@ impl CliMainWorker {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.worker.dispatch_load_event(&located_script_name!())?;
|
self.worker.dispatch_load_event(&located_script_name!())?;
|
||||||
self
|
self.run_tests(&self.ps.options.shuffle_tests()).await?;
|
||||||
.worker
|
|
||||||
.run_tests(&self.ps.options.shuffle_tests())
|
|
||||||
.await?;
|
|
||||||
loop {
|
loop {
|
||||||
if !self
|
if !self
|
||||||
.worker
|
.worker
|
||||||
|
@ -223,7 +228,7 @@ impl CliMainWorker {
|
||||||
&mut self,
|
&mut self,
|
||||||
mode: TestMode,
|
mode: TestMode,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
self.worker.enable_test();
|
self.enable_test();
|
||||||
|
|
||||||
self
|
self
|
||||||
.worker
|
.worker
|
||||||
|
@ -239,7 +244,7 @@ impl CliMainWorker {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.worker.dispatch_load_event(&located_script_name!())?;
|
self.worker.dispatch_load_event(&located_script_name!())?;
|
||||||
self.worker.run_tests(&None).await?;
|
self.run_tests(&None).await?;
|
||||||
loop {
|
loop {
|
||||||
if !self
|
if !self
|
||||||
.worker
|
.worker
|
||||||
|
@ -254,13 +259,13 @@ impl CliMainWorker {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run_bench_specifier(&mut self) -> Result<(), AnyError> {
|
pub async fn run_bench_specifier(&mut self) -> Result<(), AnyError> {
|
||||||
self.worker.enable_bench();
|
self.enable_bench();
|
||||||
|
|
||||||
// We execute the module module as a side module so that import.meta.main is not set.
|
// We execute the module module as a side module so that import.meta.main is not set.
|
||||||
self.execute_side_module_possibly_with_npm().await?;
|
self.execute_side_module_possibly_with_npm().await?;
|
||||||
|
|
||||||
self.worker.dispatch_load_event(&located_script_name!())?;
|
self.worker.dispatch_load_event(&located_script_name!())?;
|
||||||
self.worker.run_benchmarks().await?;
|
self.run_benchmarks().await?;
|
||||||
loop {
|
loop {
|
||||||
if !self
|
if !self
|
||||||
.worker
|
.worker
|
||||||
|
@ -340,14 +345,104 @@ impl CliMainWorker {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Run tests declared with `Deno.test()`. Test events will be dispatched
|
||||||
|
/// by calling ops which are currently only implemented in the CLI crate.
|
||||||
|
pub async fn run_tests(
|
||||||
|
&mut self,
|
||||||
|
shuffle: &Option<u64>,
|
||||||
|
) -> Result<(), AnyError> {
|
||||||
|
let promise = {
|
||||||
|
let scope = &mut self.worker.js_runtime.handle_scope();
|
||||||
|
let cb = self.js_run_tests_callback.as_ref().unwrap().open(scope);
|
||||||
|
let this = v8::undefined(scope).into();
|
||||||
|
let options =
|
||||||
|
serde_v8::to_v8(scope, json!({ "shuffle": shuffle })).unwrap();
|
||||||
|
let promise = cb.call(scope, this, &[options]).unwrap();
|
||||||
|
v8::Global::new(scope, promise)
|
||||||
|
};
|
||||||
|
self.worker.js_runtime.resolve_value(promise).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run benches declared with `Deno.bench()`. Bench events will be dispatched
|
||||||
|
/// by calling ops which are currently only implemented in the CLI crate.
|
||||||
|
pub async fn run_benchmarks(&mut self) -> Result<(), AnyError> {
|
||||||
|
let promise = {
|
||||||
|
let scope = &mut self.worker.js_runtime.handle_scope();
|
||||||
|
let cb = self
|
||||||
|
.js_run_benchmarks_callback
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.open(scope);
|
||||||
|
let this = v8::undefined(scope).into();
|
||||||
|
let promise = cb.call(scope, this, &[]).unwrap();
|
||||||
|
v8::Global::new(scope, promise)
|
||||||
|
};
|
||||||
|
self.worker.js_runtime.resolve_value(promise).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enable `Deno.test()`. If this isn't called before executing user code,
|
||||||
|
/// `Deno.test()` calls will noop.
|
||||||
|
pub fn enable_test(&mut self) {
|
||||||
|
let scope = &mut self.worker.js_runtime.handle_scope();
|
||||||
|
let cb = self.js_enable_test_callback.as_ref().unwrap().open(scope);
|
||||||
|
let this = v8::undefined(scope).into();
|
||||||
|
cb.call(scope, this, &[]).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enable `Deno.bench()`. If this isn't called before executing user code,
|
||||||
|
/// `Deno.bench()` calls will noop.
|
||||||
|
pub fn enable_bench(&mut self) {
|
||||||
|
let scope = &mut self.worker.js_runtime.handle_scope();
|
||||||
|
let cb = self.js_enable_bench_callback.as_ref().unwrap().open(scope);
|
||||||
|
let this = v8::undefined(scope).into();
|
||||||
|
cb.call(scope, this, &[]).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_main_worker(
|
pub async fn create_main_worker(
|
||||||
ps: &ProcState,
|
ps: &ProcState,
|
||||||
main_module: ModuleSpecifier,
|
main_module: ModuleSpecifier,
|
||||||
permissions: Permissions,
|
permissions: Permissions,
|
||||||
|
) -> Result<CliMainWorker, AnyError> {
|
||||||
|
create_main_worker_internal(
|
||||||
|
ps,
|
||||||
|
main_module,
|
||||||
|
permissions,
|
||||||
|
vec![],
|
||||||
|
Default::default(),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create_main_worker_for_test_or_bench(
|
||||||
|
ps: &ProcState,
|
||||||
|
main_module: ModuleSpecifier,
|
||||||
|
permissions: Permissions,
|
||||||
|
custom_extensions: Vec<Extension>,
|
||||||
|
stdio: deno_runtime::ops::io::Stdio,
|
||||||
|
) -> Result<CliMainWorker, AnyError> {
|
||||||
|
create_main_worker_internal(
|
||||||
|
ps,
|
||||||
|
main_module,
|
||||||
|
permissions,
|
||||||
|
custom_extensions,
|
||||||
|
stdio,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn create_main_worker_internal(
|
||||||
|
ps: &ProcState,
|
||||||
|
main_module: ModuleSpecifier,
|
||||||
|
permissions: Permissions,
|
||||||
mut custom_extensions: Vec<Extension>,
|
mut custom_extensions: Vec<Extension>,
|
||||||
stdio: deno_runtime::ops::io::Stdio,
|
stdio: deno_runtime::ops::io::Stdio,
|
||||||
|
bench_or_test: bool,
|
||||||
) -> Result<CliMainWorker, AnyError> {
|
) -> Result<CliMainWorker, AnyError> {
|
||||||
let (main_module, is_main_cjs) = if let Ok(package_ref) =
|
let (main_module, is_main_cjs) = if let Ok(package_ref) =
|
||||||
NpmPackageReference::from_specifier(&main_module)
|
NpmPackageReference::from_specifier(&main_module)
|
||||||
|
@ -426,7 +521,7 @@ pub async fn create_main_worker(
|
||||||
inspect: ps.options.is_inspecting(),
|
inspect: ps.options.is_inspecting(),
|
||||||
},
|
},
|
||||||
extensions,
|
extensions,
|
||||||
startup_snapshot: None,
|
startup_snapshot: Some(crate::js::deno_isolate_init()),
|
||||||
unsafely_ignore_certificate_errors: ps
|
unsafely_ignore_certificate_errors: ps
|
||||||
.options
|
.options
|
||||||
.unsafely_ignore_certificate_errors()
|
.unsafely_ignore_certificate_errors()
|
||||||
|
@ -452,16 +547,59 @@ pub async fn create_main_worker(
|
||||||
stdio,
|
stdio,
|
||||||
};
|
};
|
||||||
|
|
||||||
let worker = MainWorker::bootstrap_from_options(
|
let mut worker = MainWorker::bootstrap_from_options(
|
||||||
main_module.clone(),
|
main_module.clone(),
|
||||||
permissions,
|
permissions,
|
||||||
options,
|
options,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let (
|
||||||
|
js_run_tests_callback,
|
||||||
|
js_run_benchmarks_callback,
|
||||||
|
js_enable_test_callback,
|
||||||
|
js_enable_bench_callback,
|
||||||
|
) = if bench_or_test {
|
||||||
|
let scope = &mut worker.js_runtime.handle_scope();
|
||||||
|
let js_run_tests_callback = deno_core::JsRuntime::eval::<v8::Function>(
|
||||||
|
scope,
|
||||||
|
"Deno[Deno.internal].testing.runTests",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let js_run_benchmarks_callback =
|
||||||
|
deno_core::JsRuntime::eval::<v8::Function>(
|
||||||
|
scope,
|
||||||
|
"Deno[Deno.internal].testing.runBenchmarks",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let js_enable_tests_callback = deno_core::JsRuntime::eval::<v8::Function>(
|
||||||
|
scope,
|
||||||
|
"Deno[Deno.internal].testing.enableTest",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let js_enable_bench_callback = deno_core::JsRuntime::eval::<v8::Function>(
|
||||||
|
scope,
|
||||||
|
"Deno[Deno.internal].testing.enableBench",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
(
|
||||||
|
Some(v8::Global::new(scope, js_run_tests_callback)),
|
||||||
|
Some(v8::Global::new(scope, js_run_benchmarks_callback)),
|
||||||
|
Some(v8::Global::new(scope, js_enable_tests_callback)),
|
||||||
|
Some(v8::Global::new(scope, js_enable_bench_callback)),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(None, None, None, None)
|
||||||
|
};
|
||||||
|
|
||||||
Ok(CliMainWorker {
|
Ok(CliMainWorker {
|
||||||
main_module,
|
main_module,
|
||||||
is_main_cjs,
|
is_main_cjs,
|
||||||
worker,
|
worker,
|
||||||
ps: ps.clone(),
|
ps: ps.clone(),
|
||||||
|
js_run_tests_callback,
|
||||||
|
js_run_benchmarks_callback,
|
||||||
|
js_enable_test_callback,
|
||||||
|
js_enable_bench_callback,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,6 +682,7 @@ fn create_web_worker_callback(
|
||||||
inspect: ps.options.is_inspecting(),
|
inspect: ps.options.is_inspecting(),
|
||||||
},
|
},
|
||||||
extensions,
|
extensions,
|
||||||
|
startup_snapshot: Some(crate::js::deno_isolate_init()),
|
||||||
unsafely_ignore_certificate_errors: ps
|
unsafely_ignore_certificate_errors: ps
|
||||||
.options
|
.options
|
||||||
.unsafely_ignore_certificate_errors()
|
.unsafely_ignore_certificate_errors()
|
||||||
|
@ -577,3 +716,109 @@ fn create_web_worker_callback(
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use deno_core::{resolve_url_or_path, FsModuleLoader};
|
||||||
|
use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel;
|
||||||
|
use deno_runtime::deno_web::BlobStore;
|
||||||
|
|
||||||
|
fn create_test_worker() -> MainWorker {
|
||||||
|
let main_module = resolve_url_or_path("./hello.js").unwrap();
|
||||||
|
let permissions = Permissions::default();
|
||||||
|
|
||||||
|
let options = WorkerOptions {
|
||||||
|
bootstrap: BootstrapOptions {
|
||||||
|
args: vec![],
|
||||||
|
cpu_count: 1,
|
||||||
|
debug_flag: false,
|
||||||
|
enable_testing_features: false,
|
||||||
|
locale: deno_core::v8::icu::get_language_tag(),
|
||||||
|
location: None,
|
||||||
|
no_color: true,
|
||||||
|
is_tty: false,
|
||||||
|
runtime_version: "x".to_string(),
|
||||||
|
ts_version: "x".to_string(),
|
||||||
|
unstable: false,
|
||||||
|
user_agent: "x".to_string(),
|
||||||
|
inspect: false,
|
||||||
|
},
|
||||||
|
extensions: vec![],
|
||||||
|
startup_snapshot: Some(crate::js::deno_isolate_init()),
|
||||||
|
unsafely_ignore_certificate_errors: None,
|
||||||
|
root_cert_store: None,
|
||||||
|
seed: None,
|
||||||
|
format_js_error_fn: None,
|
||||||
|
source_map_getter: None,
|
||||||
|
web_worker_preload_module_cb: Arc::new(|_| unreachable!()),
|
||||||
|
web_worker_pre_execute_module_cb: Arc::new(|_| unreachable!()),
|
||||||
|
create_web_worker_cb: Arc::new(|_| unreachable!()),
|
||||||
|
maybe_inspector_server: None,
|
||||||
|
should_break_on_first_statement: false,
|
||||||
|
module_loader: Rc::new(FsModuleLoader),
|
||||||
|
npm_resolver: None,
|
||||||
|
get_error_class_fn: None,
|
||||||
|
cache_storage_dir: None,
|
||||||
|
origin_storage_dir: None,
|
||||||
|
blob_store: BlobStore::default(),
|
||||||
|
broadcast_channel: InMemoryBroadcastChannel::default(),
|
||||||
|
shared_array_buffer_store: None,
|
||||||
|
compiled_wasm_module_store: None,
|
||||||
|
stdio: Default::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
MainWorker::bootstrap_from_options(main_module, permissions, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn execute_mod_esm_imports_a() {
|
||||||
|
let p = test_util::testdata_path().join("runtime/esm_imports_a.js");
|
||||||
|
let module_specifier = resolve_url_or_path(&p.to_string_lossy()).unwrap();
|
||||||
|
let mut worker = create_test_worker();
|
||||||
|
let result = worker.execute_main_module(&module_specifier).await;
|
||||||
|
if let Err(err) = result {
|
||||||
|
eprintln!("execute_mod err {:?}", err);
|
||||||
|
}
|
||||||
|
if let Err(e) = worker.run_event_loop(false).await {
|
||||||
|
panic!("Future got unexpected error: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn execute_mod_circular() {
|
||||||
|
let p = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||||
|
.parent()
|
||||||
|
.unwrap()
|
||||||
|
.join("tests/circular1.js");
|
||||||
|
let module_specifier = resolve_url_or_path(&p.to_string_lossy()).unwrap();
|
||||||
|
let mut worker = create_test_worker();
|
||||||
|
let result = worker.execute_main_module(&module_specifier).await;
|
||||||
|
if let Err(err) = result {
|
||||||
|
eprintln!("execute_mod err {:?}", err);
|
||||||
|
}
|
||||||
|
if let Err(e) = worker.run_event_loop(false).await {
|
||||||
|
panic!("Future got unexpected error: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn execute_mod_resolve_error() {
|
||||||
|
// "foo" is not a valid module specifier so this should return an error.
|
||||||
|
let mut worker = create_test_worker();
|
||||||
|
let module_specifier = resolve_url_or_path("does-not-exist").unwrap();
|
||||||
|
let result = worker.execute_main_module(&module_specifier).await;
|
||||||
|
assert!(result.is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn execute_mod_002_hello() {
|
||||||
|
// This assumes cwd is project root (an assumption made throughout the
|
||||||
|
// tests).
|
||||||
|
let mut worker = create_test_worker();
|
||||||
|
let p = test_util::testdata_path().join("run/001_hello.js");
|
||||||
|
let module_specifier = resolve_url_or_path(&p.to_string_lossy()).unwrap();
|
||||||
|
let result = worker.execute_main_module(&module_specifier).await;
|
||||||
|
assert!(result.is_ok());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ mod ops_builtin_v8;
|
||||||
mod ops_metrics;
|
mod ops_metrics;
|
||||||
mod resources;
|
mod resources;
|
||||||
mod runtime;
|
mod runtime;
|
||||||
|
pub mod snapshot_util;
|
||||||
mod source_map;
|
mod source_map;
|
||||||
|
|
||||||
// Re-exports
|
// Re-exports
|
||||||
|
|
95
core/snapshot_util.rs
Normal file
95
core/snapshot_util.rs
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
use crate::Extension;
|
||||||
|
use crate::JsRuntime;
|
||||||
|
use crate::RuntimeOptions;
|
||||||
|
use crate::Snapshot;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
pub type CompressionCb = dyn Fn(&mut Vec<u8>, &[u8]);
|
||||||
|
|
||||||
|
pub struct CreateSnapshotOptions {
|
||||||
|
pub cargo_manifest_dir: &'static str,
|
||||||
|
pub snapshot_path: PathBuf,
|
||||||
|
pub startup_snapshot: Option<Snapshot>,
|
||||||
|
pub extensions: Vec<Extension>,
|
||||||
|
pub additional_files: Vec<PathBuf>,
|
||||||
|
pub compression_cb: Option<Box<CompressionCb>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_snapshot(create_snapshot_options: CreateSnapshotOptions) {
|
||||||
|
let mut js_runtime = JsRuntime::new(RuntimeOptions {
|
||||||
|
will_snapshot: true,
|
||||||
|
startup_snapshot: create_snapshot_options.startup_snapshot,
|
||||||
|
extensions: create_snapshot_options.extensions,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO(nayeemrmn): https://github.com/rust-lang/cargo/issues/3946 to get the
|
||||||
|
// workspace root.
|
||||||
|
let display_root = Path::new(create_snapshot_options.cargo_manifest_dir)
|
||||||
|
.parent()
|
||||||
|
.unwrap();
|
||||||
|
for file in create_snapshot_options.additional_files {
|
||||||
|
let display_path = file.strip_prefix(display_root).unwrap_or(&file);
|
||||||
|
let display_path_str = display_path.display().to_string();
|
||||||
|
js_runtime
|
||||||
|
.execute_script(
|
||||||
|
&("deno:".to_string() + &display_path_str.replace('\\', "/")),
|
||||||
|
&std::fs::read_to_string(&file).unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let snapshot = js_runtime.snapshot();
|
||||||
|
let snapshot_slice: &[u8] = &snapshot;
|
||||||
|
println!("Snapshot size: {}", snapshot_slice.len());
|
||||||
|
|
||||||
|
let maybe_compressed_snapshot: Box<dyn AsRef<[u8]>> =
|
||||||
|
if let Some(compression_cb) = create_snapshot_options.compression_cb {
|
||||||
|
let mut vec = vec![];
|
||||||
|
|
||||||
|
vec.extend_from_slice(
|
||||||
|
&u32::try_from(snapshot.len())
|
||||||
|
.expect("snapshot larger than 4gb")
|
||||||
|
.to_le_bytes(),
|
||||||
|
);
|
||||||
|
|
||||||
|
(compression_cb)(&mut vec, snapshot_slice);
|
||||||
|
|
||||||
|
println!("Snapshot compressed size: {}", vec.len());
|
||||||
|
|
||||||
|
Box::new(vec)
|
||||||
|
} else {
|
||||||
|
Box::new(snapshot_slice)
|
||||||
|
};
|
||||||
|
|
||||||
|
std::fs::write(
|
||||||
|
&create_snapshot_options.snapshot_path,
|
||||||
|
&*maybe_compressed_snapshot,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
println!(
|
||||||
|
"Snapshot written to: {} ",
|
||||||
|
create_snapshot_options.snapshot_path.display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_js_files(
|
||||||
|
cargo_manifest_dir: &'static str,
|
||||||
|
directory: &str,
|
||||||
|
) -> Vec<PathBuf> {
|
||||||
|
let manifest_dir = Path::new(cargo_manifest_dir);
|
||||||
|
let mut js_files = std::fs::read_dir(directory)
|
||||||
|
.unwrap()
|
||||||
|
.map(|dir_entry| {
|
||||||
|
let file = dir_entry.unwrap();
|
||||||
|
manifest_dir.join(file.path())
|
||||||
|
})
|
||||||
|
.filter(|path| {
|
||||||
|
path.extension().unwrap_or_default() == "js"
|
||||||
|
&& !path.ends_with("99_main.js")
|
||||||
|
})
|
||||||
|
.collect::<Vec<PathBuf>>();
|
||||||
|
js_files.sort();
|
||||||
|
js_files
|
||||||
|
}
|
|
@ -9,63 +9,8 @@ use std::path::PathBuf;
|
||||||
mod not_docs {
|
mod not_docs {
|
||||||
use super::*;
|
use super::*;
|
||||||
use deno_cache::SqliteBackedCache;
|
use deno_cache::SqliteBackedCache;
|
||||||
|
use deno_core::snapshot_util::*;
|
||||||
use deno_core::Extension;
|
use deno_core::Extension;
|
||||||
use deno_core::JsRuntime;
|
|
||||||
use deno_core::RuntimeOptions;
|
|
||||||
|
|
||||||
// TODO(bartlomieju): this module contains a lot of duplicated
|
|
||||||
// logic with `cli/build.rs`, factor out to `deno_core`.
|
|
||||||
fn create_snapshot(
|
|
||||||
mut js_runtime: JsRuntime,
|
|
||||||
snapshot_path: &Path,
|
|
||||||
files: Vec<PathBuf>,
|
|
||||||
) {
|
|
||||||
// TODO(nayeemrmn): https://github.com/rust-lang/cargo/issues/3946 to get the
|
|
||||||
// workspace root.
|
|
||||||
let display_root = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap();
|
|
||||||
for file in files {
|
|
||||||
println!("cargo:rerun-if-changed={}", file.display());
|
|
||||||
let display_path = file.strip_prefix(display_root).unwrap();
|
|
||||||
let display_path_str = display_path.display().to_string();
|
|
||||||
js_runtime
|
|
||||||
.execute_script(
|
|
||||||
&("deno:".to_string() + &display_path_str.replace('\\', "/")),
|
|
||||||
&std::fs::read_to_string(&file).unwrap(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let snapshot = js_runtime.snapshot();
|
|
||||||
let snapshot_slice: &[u8] = &snapshot;
|
|
||||||
println!("Snapshot size: {}", snapshot_slice.len());
|
|
||||||
|
|
||||||
let compressed_snapshot_with_size = {
|
|
||||||
let mut vec = vec![];
|
|
||||||
|
|
||||||
vec.extend_from_slice(
|
|
||||||
&u32::try_from(snapshot.len())
|
|
||||||
.expect("snapshot larger than 4gb")
|
|
||||||
.to_le_bytes(),
|
|
||||||
);
|
|
||||||
|
|
||||||
lzzzz::lz4_hc::compress_to_vec(
|
|
||||||
snapshot_slice,
|
|
||||||
&mut vec,
|
|
||||||
lzzzz::lz4_hc::CLEVEL_MAX,
|
|
||||||
)
|
|
||||||
.expect("snapshot compression failed");
|
|
||||||
|
|
||||||
vec
|
|
||||||
};
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"Snapshot compressed size: {}",
|
|
||||||
compressed_snapshot_with_size.len()
|
|
||||||
);
|
|
||||||
|
|
||||||
std::fs::write(snapshot_path, compressed_snapshot_with_size).unwrap();
|
|
||||||
println!("Snapshot written to: {} ", snapshot_path.display());
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Permissions;
|
struct Permissions;
|
||||||
|
|
||||||
|
@ -174,7 +119,7 @@ mod not_docs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_runtime_snapshot(snapshot_path: &Path, files: Vec<PathBuf>) {
|
fn create_runtime_snapshot(snapshot_path: PathBuf, files: Vec<PathBuf>) {
|
||||||
let extensions: Vec<Extension> = vec![
|
let extensions: Vec<Extension> = vec![
|
||||||
deno_webidl::init(),
|
deno_webidl::init(),
|
||||||
deno_console::init(),
|
deno_console::init(),
|
||||||
|
@ -205,31 +150,26 @@ mod not_docs {
|
||||||
deno_flash::init::<Permissions>(false), // No --unstable
|
deno_flash::init::<Permissions>(false), // No --unstable
|
||||||
];
|
];
|
||||||
|
|
||||||
let js_runtime = JsRuntime::new(RuntimeOptions {
|
create_snapshot(CreateSnapshotOptions {
|
||||||
will_snapshot: true,
|
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
|
||||||
|
snapshot_path,
|
||||||
|
startup_snapshot: None,
|
||||||
extensions,
|
extensions,
|
||||||
..Default::default()
|
additional_files: files,
|
||||||
|
compression_cb: Some(Box::new(|vec, snapshot_slice| {
|
||||||
|
lzzzz::lz4_hc::compress_to_vec(
|
||||||
|
snapshot_slice,
|
||||||
|
vec,
|
||||||
|
lzzzz::lz4_hc::CLEVEL_MAX,
|
||||||
|
)
|
||||||
|
.expect("snapshot compression failed");
|
||||||
|
})),
|
||||||
});
|
});
|
||||||
create_snapshot(js_runtime, snapshot_path, files);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_js_files(d: &str) -> Vec<PathBuf> {
|
|
||||||
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
|
|
||||||
let mut js_files = std::fs::read_dir(d)
|
|
||||||
.unwrap()
|
|
||||||
.map(|dir_entry| {
|
|
||||||
let file = dir_entry.unwrap();
|
|
||||||
manifest_dir.join(file.path())
|
|
||||||
})
|
|
||||||
.filter(|path| path.extension().unwrap_or_default() == "js")
|
|
||||||
.collect::<Vec<PathBuf>>();
|
|
||||||
js_files.sort();
|
|
||||||
js_files
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_snapshot(runtime_snapshot_path: PathBuf) {
|
pub fn build_snapshot(runtime_snapshot_path: PathBuf) {
|
||||||
let js_files = get_js_files("js");
|
let js_files = get_js_files(env!("CARGO_MANIFEST_DIR"), "js");
|
||||||
create_runtime_snapshot(&runtime_snapshot_path, js_files);
|
create_runtime_snapshot(runtime_snapshot_path, js_files);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,7 +182,7 @@ fn main() {
|
||||||
let o = PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
let o = PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||||
|
|
||||||
// Main snapshot
|
// Main snapshot
|
||||||
let runtime_snapshot_path = o.join("CLI_SNAPSHOT.bin");
|
let runtime_snapshot_path = o.join("RUNTIME_SNAPSHOT.bin");
|
||||||
|
|
||||||
// If we're building on docs.rs we just create
|
// If we're building on docs.rs we just create
|
||||||
// and empty snapshot file and return, because `rusty_v8`
|
// and empty snapshot file and return, because `rusty_v8`
|
||||||
|
|
|
@ -2,17 +2,18 @@
|
||||||
use deno_core::Snapshot;
|
use deno_core::Snapshot;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub static CLI_SNAPSHOT: Lazy<Box<[u8]>> = Lazy::new(
|
pub static RUNTIME_SNAPSHOT: Lazy<Box<[u8]>> = Lazy::new(
|
||||||
#[allow(clippy::uninit_vec)]
|
#[allow(clippy::uninit_vec)]
|
||||||
#[cold]
|
#[cold]
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
|| {
|
|| {
|
||||||
static COMPRESSED_CLI_SNAPSHOT: &[u8] =
|
static COMPRESSED_RUNTIME_SNAPSHOT: &[u8] =
|
||||||
include_bytes!(concat!(env!("OUT_DIR"), "/CLI_SNAPSHOT.bin"));
|
include_bytes!(concat!(env!("OUT_DIR"), "/RUNTIME_SNAPSHOT.bin"));
|
||||||
|
|
||||||
let size =
|
let size =
|
||||||
u32::from_le_bytes(COMPRESSED_CLI_SNAPSHOT[0..4].try_into().unwrap())
|
u32::from_le_bytes(COMPRESSED_RUNTIME_SNAPSHOT[0..4].try_into().unwrap())
|
||||||
as usize;
|
as usize;
|
||||||
let mut vec = Vec::with_capacity(size);
|
let mut vec = Vec::with_capacity(size);
|
||||||
|
|
||||||
|
@ -22,7 +23,8 @@ pub static CLI_SNAPSHOT: Lazy<Box<[u8]>> = Lazy::new(
|
||||||
vec.set_len(size);
|
vec.set_len(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
lzzzz::lz4::decompress(&COMPRESSED_CLI_SNAPSHOT[4..], &mut vec).unwrap();
|
lzzzz::lz4::decompress(&COMPRESSED_RUNTIME_SNAPSHOT[4..], &mut vec)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
vec.into_boxed_slice()
|
vec.into_boxed_slice()
|
||||||
},
|
},
|
||||||
|
@ -30,29 +32,11 @@ pub static CLI_SNAPSHOT: Lazy<Box<[u8]>> = Lazy::new(
|
||||||
|
|
||||||
pub fn deno_isolate_init() -> Snapshot {
|
pub fn deno_isolate_init() -> Snapshot {
|
||||||
debug!("Deno isolate init with snapshots.");
|
debug!("Deno isolate init with snapshots.");
|
||||||
Snapshot::Static(&CLI_SNAPSHOT)
|
Snapshot::Static(&RUNTIME_SNAPSHOT)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
pub fn get_99_main() -> PathBuf {
|
||||||
mod tests {
|
let manifest = env!("CARGO_MANIFEST_DIR");
|
||||||
use super::*;
|
let path = PathBuf::from(manifest);
|
||||||
|
path.join("js").join("99_main.js")
|
||||||
#[test]
|
|
||||||
fn cli_snapshot() {
|
|
||||||
let mut js_runtime = deno_core::JsRuntime::new(deno_core::RuntimeOptions {
|
|
||||||
startup_snapshot: Some(deno_isolate_init()),
|
|
||||||
..Default::default()
|
|
||||||
});
|
|
||||||
js_runtime
|
|
||||||
.execute_script(
|
|
||||||
"<anon>",
|
|
||||||
r#"
|
|
||||||
if (!(bootstrap.mainRuntime && bootstrap.workerRuntime)) {
|
|
||||||
throw Error("bad");
|
|
||||||
}
|
|
||||||
console.log("we have console.log!!!");
|
|
||||||
"#,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
|
|
||||||
__bootstrap.denoNs = {
|
__bootstrap.denoNs = {
|
||||||
metrics: core.metrics,
|
metrics: core.metrics,
|
||||||
test: __bootstrap.testing.test,
|
|
||||||
bench: __bootstrap.testing.bench,
|
|
||||||
Process: __bootstrap.process.Process,
|
Process: __bootstrap.process.Process,
|
||||||
run: __bootstrap.process.run,
|
run: __bootstrap.process.run,
|
||||||
isatty: __bootstrap.tty.isatty,
|
isatty: __bootstrap.tty.isatty,
|
||||||
|
|
352
runtime/js/98_global_scope.js
Normal file
352
runtime/js/98_global_scope.js
Normal file
|
@ -0,0 +1,352 @@
|
||||||
|
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
((window) => {
|
||||||
|
const core = Deno.core;
|
||||||
|
const {
|
||||||
|
ObjectDefineProperties,
|
||||||
|
SymbolFor,
|
||||||
|
} = window.__bootstrap.primordials;
|
||||||
|
|
||||||
|
const util = window.__bootstrap.util;
|
||||||
|
const location = window.__bootstrap.location;
|
||||||
|
const event = window.__bootstrap.event;
|
||||||
|
const eventTarget = window.__bootstrap.eventTarget;
|
||||||
|
const timers = window.__bootstrap.timers;
|
||||||
|
const base64 = window.__bootstrap.base64;
|
||||||
|
const encoding = window.__bootstrap.encoding;
|
||||||
|
const Console = window.__bootstrap.console.Console;
|
||||||
|
const caches = window.__bootstrap.caches;
|
||||||
|
const compression = window.__bootstrap.compression;
|
||||||
|
const worker = window.__bootstrap.worker;
|
||||||
|
const performance = window.__bootstrap.performance;
|
||||||
|
const crypto = window.__bootstrap.crypto;
|
||||||
|
const url = window.__bootstrap.url;
|
||||||
|
const urlPattern = window.__bootstrap.urlPattern;
|
||||||
|
const headers = window.__bootstrap.headers;
|
||||||
|
const streams = window.__bootstrap.streams;
|
||||||
|
const fileReader = window.__bootstrap.fileReader;
|
||||||
|
const webgpu = window.__bootstrap.webgpu;
|
||||||
|
const webSocket = window.__bootstrap.webSocket;
|
||||||
|
const broadcastChannel = window.__bootstrap.broadcastChannel;
|
||||||
|
const file = window.__bootstrap.file;
|
||||||
|
const formData = window.__bootstrap.formData;
|
||||||
|
const fetch = window.__bootstrap.fetch;
|
||||||
|
const messagePort = window.__bootstrap.messagePort;
|
||||||
|
const webidl = window.__bootstrap.webidl;
|
||||||
|
const domException = window.__bootstrap.domException;
|
||||||
|
const abortSignal = window.__bootstrap.abortSignal;
|
||||||
|
const globalInterfaces = window.__bootstrap.globalInterfaces;
|
||||||
|
const webStorage = window.__bootstrap.webStorage;
|
||||||
|
const prompt = window.__bootstrap.prompt;
|
||||||
|
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope
|
||||||
|
const windowOrWorkerGlobalScope = {
|
||||||
|
AbortController: util.nonEnumerable(abortSignal.AbortController),
|
||||||
|
AbortSignal: util.nonEnumerable(abortSignal.AbortSignal),
|
||||||
|
Blob: util.nonEnumerable(file.Blob),
|
||||||
|
ByteLengthQueuingStrategy: util.nonEnumerable(
|
||||||
|
streams.ByteLengthQueuingStrategy,
|
||||||
|
),
|
||||||
|
CloseEvent: util.nonEnumerable(event.CloseEvent),
|
||||||
|
CompressionStream: util.nonEnumerable(compression.CompressionStream),
|
||||||
|
CountQueuingStrategy: util.nonEnumerable(
|
||||||
|
streams.CountQueuingStrategy,
|
||||||
|
),
|
||||||
|
CryptoKey: util.nonEnumerable(crypto.CryptoKey),
|
||||||
|
CustomEvent: util.nonEnumerable(event.CustomEvent),
|
||||||
|
DecompressionStream: util.nonEnumerable(compression.DecompressionStream),
|
||||||
|
DOMException: util.nonEnumerable(domException.DOMException),
|
||||||
|
ErrorEvent: util.nonEnumerable(event.ErrorEvent),
|
||||||
|
Event: util.nonEnumerable(event.Event),
|
||||||
|
EventTarget: util.nonEnumerable(eventTarget.EventTarget),
|
||||||
|
File: util.nonEnumerable(file.File),
|
||||||
|
FileReader: util.nonEnumerable(fileReader.FileReader),
|
||||||
|
FormData: util.nonEnumerable(formData.FormData),
|
||||||
|
Headers: util.nonEnumerable(headers.Headers),
|
||||||
|
MessageEvent: util.nonEnumerable(event.MessageEvent),
|
||||||
|
Performance: util.nonEnumerable(performance.Performance),
|
||||||
|
PerformanceEntry: util.nonEnumerable(performance.PerformanceEntry),
|
||||||
|
PerformanceMark: util.nonEnumerable(performance.PerformanceMark),
|
||||||
|
PerformanceMeasure: util.nonEnumerable(performance.PerformanceMeasure),
|
||||||
|
PromiseRejectionEvent: util.nonEnumerable(event.PromiseRejectionEvent),
|
||||||
|
ProgressEvent: util.nonEnumerable(event.ProgressEvent),
|
||||||
|
ReadableStream: util.nonEnumerable(streams.ReadableStream),
|
||||||
|
ReadableStreamDefaultReader: util.nonEnumerable(
|
||||||
|
streams.ReadableStreamDefaultReader,
|
||||||
|
),
|
||||||
|
Request: util.nonEnumerable(fetch.Request),
|
||||||
|
Response: util.nonEnumerable(fetch.Response),
|
||||||
|
TextDecoder: util.nonEnumerable(encoding.TextDecoder),
|
||||||
|
TextEncoder: util.nonEnumerable(encoding.TextEncoder),
|
||||||
|
TextDecoderStream: util.nonEnumerable(encoding.TextDecoderStream),
|
||||||
|
TextEncoderStream: util.nonEnumerable(encoding.TextEncoderStream),
|
||||||
|
TransformStream: util.nonEnumerable(streams.TransformStream),
|
||||||
|
URL: util.nonEnumerable(url.URL),
|
||||||
|
URLPattern: util.nonEnumerable(urlPattern.URLPattern),
|
||||||
|
URLSearchParams: util.nonEnumerable(url.URLSearchParams),
|
||||||
|
WebSocket: util.nonEnumerable(webSocket.WebSocket),
|
||||||
|
MessageChannel: util.nonEnumerable(messagePort.MessageChannel),
|
||||||
|
MessagePort: util.nonEnumerable(messagePort.MessagePort),
|
||||||
|
Worker: util.nonEnumerable(worker.Worker),
|
||||||
|
WritableStream: util.nonEnumerable(streams.WritableStream),
|
||||||
|
WritableStreamDefaultWriter: util.nonEnumerable(
|
||||||
|
streams.WritableStreamDefaultWriter,
|
||||||
|
),
|
||||||
|
WritableStreamDefaultController: util.nonEnumerable(
|
||||||
|
streams.WritableStreamDefaultController,
|
||||||
|
),
|
||||||
|
ReadableByteStreamController: util.nonEnumerable(
|
||||||
|
streams.ReadableByteStreamController,
|
||||||
|
),
|
||||||
|
ReadableStreamBYOBReader: util.nonEnumerable(
|
||||||
|
streams.ReadableStreamBYOBReader,
|
||||||
|
),
|
||||||
|
ReadableStreamBYOBRequest: util.nonEnumerable(
|
||||||
|
streams.ReadableStreamBYOBRequest,
|
||||||
|
),
|
||||||
|
ReadableStreamDefaultController: util.nonEnumerable(
|
||||||
|
streams.ReadableStreamDefaultController,
|
||||||
|
),
|
||||||
|
TransformStreamDefaultController: util.nonEnumerable(
|
||||||
|
streams.TransformStreamDefaultController,
|
||||||
|
),
|
||||||
|
atob: util.writable(base64.atob),
|
||||||
|
btoa: util.writable(base64.btoa),
|
||||||
|
clearInterval: util.writable(timers.clearInterval),
|
||||||
|
clearTimeout: util.writable(timers.clearTimeout),
|
||||||
|
caches: {
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
get: caches.cacheStorage,
|
||||||
|
},
|
||||||
|
CacheStorage: util.nonEnumerable(caches.CacheStorage),
|
||||||
|
Cache: util.nonEnumerable(caches.Cache),
|
||||||
|
console: util.nonEnumerable(
|
||||||
|
new Console((msg, level) => core.print(msg, level > 1)),
|
||||||
|
),
|
||||||
|
crypto: util.readOnly(crypto.crypto),
|
||||||
|
Crypto: util.nonEnumerable(crypto.Crypto),
|
||||||
|
SubtleCrypto: util.nonEnumerable(crypto.SubtleCrypto),
|
||||||
|
fetch: util.writable(fetch.fetch),
|
||||||
|
performance: util.writable(performance.performance),
|
||||||
|
reportError: util.writable(event.reportError),
|
||||||
|
setInterval: util.writable(timers.setInterval),
|
||||||
|
setTimeout: util.writable(timers.setTimeout),
|
||||||
|
structuredClone: util.writable(messagePort.structuredClone),
|
||||||
|
// Branding as a WebIDL object
|
||||||
|
[webidl.brand]: util.nonEnumerable(webidl.brand),
|
||||||
|
};
|
||||||
|
|
||||||
|
const unstableWindowOrWorkerGlobalScope = {
|
||||||
|
BroadcastChannel: util.nonEnumerable(broadcastChannel.BroadcastChannel),
|
||||||
|
WebSocketStream: util.nonEnumerable(webSocket.WebSocketStream),
|
||||||
|
|
||||||
|
GPU: util.nonEnumerable(webgpu.GPU),
|
||||||
|
GPUAdapter: util.nonEnumerable(webgpu.GPUAdapter),
|
||||||
|
GPUSupportedLimits: util.nonEnumerable(webgpu.GPUSupportedLimits),
|
||||||
|
GPUSupportedFeatures: util.nonEnumerable(webgpu.GPUSupportedFeatures),
|
||||||
|
GPUDevice: util.nonEnumerable(webgpu.GPUDevice),
|
||||||
|
GPUQueue: util.nonEnumerable(webgpu.GPUQueue),
|
||||||
|
GPUBuffer: util.nonEnumerable(webgpu.GPUBuffer),
|
||||||
|
GPUBufferUsage: util.nonEnumerable(webgpu.GPUBufferUsage),
|
||||||
|
GPUMapMode: util.nonEnumerable(webgpu.GPUMapMode),
|
||||||
|
GPUTexture: util.nonEnumerable(webgpu.GPUTexture),
|
||||||
|
GPUTextureUsage: util.nonEnumerable(webgpu.GPUTextureUsage),
|
||||||
|
GPUTextureView: util.nonEnumerable(webgpu.GPUTextureView),
|
||||||
|
GPUSampler: util.nonEnumerable(webgpu.GPUSampler),
|
||||||
|
GPUBindGroupLayout: util.nonEnumerable(webgpu.GPUBindGroupLayout),
|
||||||
|
GPUPipelineLayout: util.nonEnumerable(webgpu.GPUPipelineLayout),
|
||||||
|
GPUBindGroup: util.nonEnumerable(webgpu.GPUBindGroup),
|
||||||
|
GPUShaderModule: util.nonEnumerable(webgpu.GPUShaderModule),
|
||||||
|
GPUShaderStage: util.nonEnumerable(webgpu.GPUShaderStage),
|
||||||
|
GPUComputePipeline: util.nonEnumerable(webgpu.GPUComputePipeline),
|
||||||
|
GPURenderPipeline: util.nonEnumerable(webgpu.GPURenderPipeline),
|
||||||
|
GPUColorWrite: util.nonEnumerable(webgpu.GPUColorWrite),
|
||||||
|
GPUCommandEncoder: util.nonEnumerable(webgpu.GPUCommandEncoder),
|
||||||
|
GPURenderPassEncoder: util.nonEnumerable(webgpu.GPURenderPassEncoder),
|
||||||
|
GPUComputePassEncoder: util.nonEnumerable(webgpu.GPUComputePassEncoder),
|
||||||
|
GPUCommandBuffer: util.nonEnumerable(webgpu.GPUCommandBuffer),
|
||||||
|
GPURenderBundleEncoder: util.nonEnumerable(webgpu.GPURenderBundleEncoder),
|
||||||
|
GPURenderBundle: util.nonEnumerable(webgpu.GPURenderBundle),
|
||||||
|
GPUQuerySet: util.nonEnumerable(webgpu.GPUQuerySet),
|
||||||
|
GPUOutOfMemoryError: util.nonEnumerable(webgpu.GPUOutOfMemoryError),
|
||||||
|
GPUValidationError: util.nonEnumerable(webgpu.GPUValidationError),
|
||||||
|
};
|
||||||
|
|
||||||
|
class Navigator {
|
||||||
|
constructor() {
|
||||||
|
webidl.illegalConstructor();
|
||||||
|
}
|
||||||
|
|
||||||
|
[SymbolFor("Deno.privateCustomInspect")](inspect) {
|
||||||
|
return `${this.constructor.name} ${inspect({})}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const navigator = webidl.createBranded(Navigator);
|
||||||
|
|
||||||
|
let numCpus, userAgent, language;
|
||||||
|
|
||||||
|
function setNumCpus(val) {
|
||||||
|
numCpus = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setUserAgent(val) {
|
||||||
|
userAgent = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLanguage(val) {
|
||||||
|
language = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectDefineProperties(Navigator.prototype, {
|
||||||
|
gpu: {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
get() {
|
||||||
|
webidl.assertBranded(this, NavigatorPrototype);
|
||||||
|
return webgpu.gpu;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
hardwareConcurrency: {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
get() {
|
||||||
|
webidl.assertBranded(this, NavigatorPrototype);
|
||||||
|
return numCpus;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
userAgent: {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
get() {
|
||||||
|
webidl.assertBranded(this, NavigatorPrototype);
|
||||||
|
return userAgent;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
language: {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
get() {
|
||||||
|
webidl.assertBranded(this, NavigatorPrototype);
|
||||||
|
return language;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
languages: {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
get() {
|
||||||
|
webidl.assertBranded(this, NavigatorPrototype);
|
||||||
|
return [language];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const NavigatorPrototype = Navigator.prototype;
|
||||||
|
|
||||||
|
class WorkerNavigator {
|
||||||
|
constructor() {
|
||||||
|
webidl.illegalConstructor();
|
||||||
|
}
|
||||||
|
|
||||||
|
[SymbolFor("Deno.privateCustomInspect")](inspect) {
|
||||||
|
return `${this.constructor.name} ${inspect({})}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const workerNavigator = webidl.createBranded(WorkerNavigator);
|
||||||
|
|
||||||
|
ObjectDefineProperties(WorkerNavigator.prototype, {
|
||||||
|
gpu: {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
get() {
|
||||||
|
webidl.assertBranded(this, WorkerNavigatorPrototype);
|
||||||
|
return webgpu.gpu;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
hardwareConcurrency: {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
get() {
|
||||||
|
webidl.assertBranded(this, WorkerNavigatorPrototype);
|
||||||
|
return numCpus;
|
||||||
|
},
|
||||||
|
language: {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
get() {
|
||||||
|
webidl.assertBranded(this, WorkerNavigatorPrototype);
|
||||||
|
return language;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
languages: {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
get() {
|
||||||
|
webidl.assertBranded(this, WorkerNavigatorPrototype);
|
||||||
|
return [language];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const WorkerNavigatorPrototype = WorkerNavigator.prototype;
|
||||||
|
|
||||||
|
const mainRuntimeGlobalProperties = {
|
||||||
|
Location: location.locationConstructorDescriptor,
|
||||||
|
location: location.locationDescriptor,
|
||||||
|
Window: globalInterfaces.windowConstructorDescriptor,
|
||||||
|
window: util.readOnly(globalThis),
|
||||||
|
self: util.writable(globalThis),
|
||||||
|
Navigator: util.nonEnumerable(Navigator),
|
||||||
|
navigator: {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
get: () => navigator,
|
||||||
|
},
|
||||||
|
alert: util.writable(prompt.alert),
|
||||||
|
confirm: util.writable(prompt.confirm),
|
||||||
|
prompt: util.writable(prompt.prompt),
|
||||||
|
localStorage: {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
get: webStorage.localStorage,
|
||||||
|
// Makes this reassignable to make astro work
|
||||||
|
set: () => {},
|
||||||
|
},
|
||||||
|
sessionStorage: {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
get: webStorage.sessionStorage,
|
||||||
|
// Makes this reassignable to make astro work
|
||||||
|
set: () => {},
|
||||||
|
},
|
||||||
|
Storage: util.nonEnumerable(webStorage.Storage),
|
||||||
|
};
|
||||||
|
|
||||||
|
const workerRuntimeGlobalProperties = {
|
||||||
|
WorkerLocation: location.workerLocationConstructorDescriptor,
|
||||||
|
location: location.workerLocationDescriptor,
|
||||||
|
WorkerGlobalScope: globalInterfaces.workerGlobalScopeConstructorDescriptor,
|
||||||
|
DedicatedWorkerGlobalScope:
|
||||||
|
globalInterfaces.dedicatedWorkerGlobalScopeConstructorDescriptor,
|
||||||
|
WorkerNavigator: util.nonEnumerable(WorkerNavigator),
|
||||||
|
navigator: {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
get: () => workerNavigator,
|
||||||
|
},
|
||||||
|
self: util.readOnly(globalThis),
|
||||||
|
};
|
||||||
|
|
||||||
|
window.__bootstrap.globalScope = {
|
||||||
|
windowOrWorkerGlobalScope,
|
||||||
|
unstableWindowOrWorkerGlobalScope,
|
||||||
|
mainRuntimeGlobalProperties,
|
||||||
|
workerRuntimeGlobalProperties,
|
||||||
|
|
||||||
|
setNumCpus,
|
||||||
|
setUserAgent,
|
||||||
|
setLanguage,
|
||||||
|
};
|
||||||
|
})(this);
|
|
@ -41,48 +41,37 @@ delete Intl.v8BreakIterator;
|
||||||
const util = window.__bootstrap.util;
|
const util = window.__bootstrap.util;
|
||||||
const event = window.__bootstrap.event;
|
const event = window.__bootstrap.event;
|
||||||
const eventTarget = window.__bootstrap.eventTarget;
|
const eventTarget = window.__bootstrap.eventTarget;
|
||||||
const globalInterfaces = window.__bootstrap.globalInterfaces;
|
|
||||||
const location = window.__bootstrap.location;
|
const location = window.__bootstrap.location;
|
||||||
const build = window.__bootstrap.build;
|
const build = window.__bootstrap.build;
|
||||||
const version = window.__bootstrap.version;
|
const version = window.__bootstrap.version;
|
||||||
const os = window.__bootstrap.os;
|
const os = window.__bootstrap.os;
|
||||||
const timers = window.__bootstrap.timers;
|
const timers = window.__bootstrap.timers;
|
||||||
const base64 = window.__bootstrap.base64;
|
|
||||||
const encoding = window.__bootstrap.encoding;
|
|
||||||
const colors = window.__bootstrap.colors;
|
const colors = window.__bootstrap.colors;
|
||||||
const Console = window.__bootstrap.console.Console;
|
|
||||||
const caches = window.__bootstrap.caches;
|
|
||||||
const inspectArgs = window.__bootstrap.console.inspectArgs;
|
const inspectArgs = window.__bootstrap.console.inspectArgs;
|
||||||
const quoteString = window.__bootstrap.console.quoteString;
|
const quoteString = window.__bootstrap.console.quoteString;
|
||||||
const compression = window.__bootstrap.compression;
|
|
||||||
const worker = window.__bootstrap.worker;
|
|
||||||
const internals = window.__bootstrap.internals;
|
const internals = window.__bootstrap.internals;
|
||||||
const performance = window.__bootstrap.performance;
|
const performance = window.__bootstrap.performance;
|
||||||
const net = window.__bootstrap.net;
|
const net = window.__bootstrap.net;
|
||||||
const crypto = window.__bootstrap.crypto;
|
|
||||||
const url = window.__bootstrap.url;
|
const url = window.__bootstrap.url;
|
||||||
const urlPattern = window.__bootstrap.urlPattern;
|
|
||||||
const headers = window.__bootstrap.headers;
|
|
||||||
const streams = window.__bootstrap.streams;
|
|
||||||
const fileReader = window.__bootstrap.fileReader;
|
|
||||||
const webgpu = window.__bootstrap.webgpu;
|
|
||||||
const webSocket = window.__bootstrap.webSocket;
|
|
||||||
const webStorage = window.__bootstrap.webStorage;
|
|
||||||
const broadcastChannel = window.__bootstrap.broadcastChannel;
|
|
||||||
const file = window.__bootstrap.file;
|
|
||||||
const formData = window.__bootstrap.formData;
|
|
||||||
const fetch = window.__bootstrap.fetch;
|
const fetch = window.__bootstrap.fetch;
|
||||||
const prompt = window.__bootstrap.prompt;
|
|
||||||
const messagePort = window.__bootstrap.messagePort;
|
const messagePort = window.__bootstrap.messagePort;
|
||||||
const denoNs = window.__bootstrap.denoNs;
|
const denoNs = window.__bootstrap.denoNs;
|
||||||
const denoNsUnstable = window.__bootstrap.denoNsUnstable;
|
const denoNsUnstable = window.__bootstrap.denoNsUnstable;
|
||||||
const errors = window.__bootstrap.errors.errors;
|
const errors = window.__bootstrap.errors.errors;
|
||||||
const webidl = window.__bootstrap.webidl;
|
const webidl = window.__bootstrap.webidl;
|
||||||
const domException = window.__bootstrap.domException;
|
const domException = window.__bootstrap.domException;
|
||||||
const abortSignal = window.__bootstrap.abortSignal;
|
|
||||||
const { defineEventHandler, reportException } = window.__bootstrap.event;
|
const { defineEventHandler, reportException } = window.__bootstrap.event;
|
||||||
const { deserializeJsMessageData, serializeJsMessageData } =
|
const { deserializeJsMessageData, serializeJsMessageData } =
|
||||||
window.__bootstrap.messagePort;
|
window.__bootstrap.messagePort;
|
||||||
|
const {
|
||||||
|
windowOrWorkerGlobalScope,
|
||||||
|
unstableWindowOrWorkerGlobalScope,
|
||||||
|
workerRuntimeGlobalProperties,
|
||||||
|
mainRuntimeGlobalProperties,
|
||||||
|
setNumCpus,
|
||||||
|
setUserAgent,
|
||||||
|
setLanguage,
|
||||||
|
} = window.__bootstrap.globalScope;
|
||||||
|
|
||||||
let windowIsClosing = false;
|
let windowIsClosing = false;
|
||||||
|
|
||||||
|
@ -326,298 +315,6 @@ delete Intl.v8BreakIterator;
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Navigator {
|
|
||||||
constructor() {
|
|
||||||
webidl.illegalConstructor();
|
|
||||||
}
|
|
||||||
|
|
||||||
[SymbolFor("Deno.privateCustomInspect")](inspect) {
|
|
||||||
return `${this.constructor.name} ${inspect({})}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const navigator = webidl.createBranded(Navigator);
|
|
||||||
|
|
||||||
let numCpus, userAgent, language;
|
|
||||||
|
|
||||||
ObjectDefineProperties(Navigator.prototype, {
|
|
||||||
gpu: {
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
get() {
|
|
||||||
webidl.assertBranded(this, NavigatorPrototype);
|
|
||||||
return webgpu.gpu;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
hardwareConcurrency: {
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
get() {
|
|
||||||
webidl.assertBranded(this, NavigatorPrototype);
|
|
||||||
return numCpus;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
userAgent: {
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
get() {
|
|
||||||
webidl.assertBranded(this, NavigatorPrototype);
|
|
||||||
return userAgent;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
language: {
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
get() {
|
|
||||||
webidl.assertBranded(this, NavigatorPrototype);
|
|
||||||
return language;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
languages: {
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
get() {
|
|
||||||
webidl.assertBranded(this, NavigatorPrototype);
|
|
||||||
return [language];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const NavigatorPrototype = Navigator.prototype;
|
|
||||||
|
|
||||||
class WorkerNavigator {
|
|
||||||
constructor() {
|
|
||||||
webidl.illegalConstructor();
|
|
||||||
}
|
|
||||||
|
|
||||||
[SymbolFor("Deno.privateCustomInspect")](inspect) {
|
|
||||||
return `${this.constructor.name} ${inspect({})}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const workerNavigator = webidl.createBranded(WorkerNavigator);
|
|
||||||
|
|
||||||
ObjectDefineProperties(WorkerNavigator.prototype, {
|
|
||||||
gpu: {
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
get() {
|
|
||||||
webidl.assertBranded(this, WorkerNavigatorPrototype);
|
|
||||||
return webgpu.gpu;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
hardwareConcurrency: {
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
get() {
|
|
||||||
webidl.assertBranded(this, WorkerNavigatorPrototype);
|
|
||||||
return numCpus;
|
|
||||||
},
|
|
||||||
language: {
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
get() {
|
|
||||||
webidl.assertBranded(this, WorkerNavigatorPrototype);
|
|
||||||
return language;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
languages: {
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
get() {
|
|
||||||
webidl.assertBranded(this, WorkerNavigatorPrototype);
|
|
||||||
return [language];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const WorkerNavigatorPrototype = WorkerNavigator.prototype;
|
|
||||||
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope
|
|
||||||
const windowOrWorkerGlobalScope = {
|
|
||||||
AbortController: util.nonEnumerable(abortSignal.AbortController),
|
|
||||||
AbortSignal: util.nonEnumerable(abortSignal.AbortSignal),
|
|
||||||
Blob: util.nonEnumerable(file.Blob),
|
|
||||||
ByteLengthQueuingStrategy: util.nonEnumerable(
|
|
||||||
streams.ByteLengthQueuingStrategy,
|
|
||||||
),
|
|
||||||
CloseEvent: util.nonEnumerable(event.CloseEvent),
|
|
||||||
CompressionStream: util.nonEnumerable(compression.CompressionStream),
|
|
||||||
CountQueuingStrategy: util.nonEnumerable(
|
|
||||||
streams.CountQueuingStrategy,
|
|
||||||
),
|
|
||||||
CryptoKey: util.nonEnumerable(crypto.CryptoKey),
|
|
||||||
CustomEvent: util.nonEnumerable(event.CustomEvent),
|
|
||||||
DecompressionStream: util.nonEnumerable(compression.DecompressionStream),
|
|
||||||
DOMException: util.nonEnumerable(domException.DOMException),
|
|
||||||
ErrorEvent: util.nonEnumerable(event.ErrorEvent),
|
|
||||||
Event: util.nonEnumerable(event.Event),
|
|
||||||
EventTarget: util.nonEnumerable(eventTarget.EventTarget),
|
|
||||||
File: util.nonEnumerable(file.File),
|
|
||||||
FileReader: util.nonEnumerable(fileReader.FileReader),
|
|
||||||
FormData: util.nonEnumerable(formData.FormData),
|
|
||||||
Headers: util.nonEnumerable(headers.Headers),
|
|
||||||
MessageEvent: util.nonEnumerable(event.MessageEvent),
|
|
||||||
Performance: util.nonEnumerable(performance.Performance),
|
|
||||||
PerformanceEntry: util.nonEnumerable(performance.PerformanceEntry),
|
|
||||||
PerformanceMark: util.nonEnumerable(performance.PerformanceMark),
|
|
||||||
PerformanceMeasure: util.nonEnumerable(performance.PerformanceMeasure),
|
|
||||||
PromiseRejectionEvent: util.nonEnumerable(event.PromiseRejectionEvent),
|
|
||||||
ProgressEvent: util.nonEnumerable(event.ProgressEvent),
|
|
||||||
ReadableStream: util.nonEnumerable(streams.ReadableStream),
|
|
||||||
ReadableStreamDefaultReader: util.nonEnumerable(
|
|
||||||
streams.ReadableStreamDefaultReader,
|
|
||||||
),
|
|
||||||
Request: util.nonEnumerable(fetch.Request),
|
|
||||||
Response: util.nonEnumerable(fetch.Response),
|
|
||||||
TextDecoder: util.nonEnumerable(encoding.TextDecoder),
|
|
||||||
TextEncoder: util.nonEnumerable(encoding.TextEncoder),
|
|
||||||
TextDecoderStream: util.nonEnumerable(encoding.TextDecoderStream),
|
|
||||||
TextEncoderStream: util.nonEnumerable(encoding.TextEncoderStream),
|
|
||||||
TransformStream: util.nonEnumerable(streams.TransformStream),
|
|
||||||
URL: util.nonEnumerable(url.URL),
|
|
||||||
URLPattern: util.nonEnumerable(urlPattern.URLPattern),
|
|
||||||
URLSearchParams: util.nonEnumerable(url.URLSearchParams),
|
|
||||||
WebSocket: util.nonEnumerable(webSocket.WebSocket),
|
|
||||||
MessageChannel: util.nonEnumerable(messagePort.MessageChannel),
|
|
||||||
MessagePort: util.nonEnumerable(messagePort.MessagePort),
|
|
||||||
Worker: util.nonEnumerable(worker.Worker),
|
|
||||||
WritableStream: util.nonEnumerable(streams.WritableStream),
|
|
||||||
WritableStreamDefaultWriter: util.nonEnumerable(
|
|
||||||
streams.WritableStreamDefaultWriter,
|
|
||||||
),
|
|
||||||
WritableStreamDefaultController: util.nonEnumerable(
|
|
||||||
streams.WritableStreamDefaultController,
|
|
||||||
),
|
|
||||||
ReadableByteStreamController: util.nonEnumerable(
|
|
||||||
streams.ReadableByteStreamController,
|
|
||||||
),
|
|
||||||
ReadableStreamBYOBReader: util.nonEnumerable(
|
|
||||||
streams.ReadableStreamBYOBReader,
|
|
||||||
),
|
|
||||||
ReadableStreamBYOBRequest: util.nonEnumerable(
|
|
||||||
streams.ReadableStreamBYOBRequest,
|
|
||||||
),
|
|
||||||
ReadableStreamDefaultController: util.nonEnumerable(
|
|
||||||
streams.ReadableStreamDefaultController,
|
|
||||||
),
|
|
||||||
TransformStreamDefaultController: util.nonEnumerable(
|
|
||||||
streams.TransformStreamDefaultController,
|
|
||||||
),
|
|
||||||
atob: util.writable(base64.atob),
|
|
||||||
btoa: util.writable(base64.btoa),
|
|
||||||
clearInterval: util.writable(timers.clearInterval),
|
|
||||||
clearTimeout: util.writable(timers.clearTimeout),
|
|
||||||
caches: {
|
|
||||||
enumerable: true,
|
|
||||||
configurable: true,
|
|
||||||
get: caches.cacheStorage,
|
|
||||||
},
|
|
||||||
CacheStorage: util.nonEnumerable(caches.CacheStorage),
|
|
||||||
Cache: util.nonEnumerable(caches.Cache),
|
|
||||||
console: util.nonEnumerable(
|
|
||||||
new Console((msg, level) => core.print(msg, level > 1)),
|
|
||||||
),
|
|
||||||
crypto: util.readOnly(crypto.crypto),
|
|
||||||
Crypto: util.nonEnumerable(crypto.Crypto),
|
|
||||||
SubtleCrypto: util.nonEnumerable(crypto.SubtleCrypto),
|
|
||||||
fetch: util.writable(fetch.fetch),
|
|
||||||
performance: util.writable(performance.performance),
|
|
||||||
reportError: util.writable(event.reportError),
|
|
||||||
setInterval: util.writable(timers.setInterval),
|
|
||||||
setTimeout: util.writable(timers.setTimeout),
|
|
||||||
structuredClone: util.writable(messagePort.structuredClone),
|
|
||||||
// Branding as a WebIDL object
|
|
||||||
[webidl.brand]: util.nonEnumerable(webidl.brand),
|
|
||||||
};
|
|
||||||
|
|
||||||
const unstableWindowOrWorkerGlobalScope = {
|
|
||||||
BroadcastChannel: util.nonEnumerable(broadcastChannel.BroadcastChannel),
|
|
||||||
WebSocketStream: util.nonEnumerable(webSocket.WebSocketStream),
|
|
||||||
|
|
||||||
GPU: util.nonEnumerable(webgpu.GPU),
|
|
||||||
GPUAdapter: util.nonEnumerable(webgpu.GPUAdapter),
|
|
||||||
GPUSupportedLimits: util.nonEnumerable(webgpu.GPUSupportedLimits),
|
|
||||||
GPUSupportedFeatures: util.nonEnumerable(webgpu.GPUSupportedFeatures),
|
|
||||||
GPUDevice: util.nonEnumerable(webgpu.GPUDevice),
|
|
||||||
GPUQueue: util.nonEnumerable(webgpu.GPUQueue),
|
|
||||||
GPUBuffer: util.nonEnumerable(webgpu.GPUBuffer),
|
|
||||||
GPUBufferUsage: util.nonEnumerable(webgpu.GPUBufferUsage),
|
|
||||||
GPUMapMode: util.nonEnumerable(webgpu.GPUMapMode),
|
|
||||||
GPUTexture: util.nonEnumerable(webgpu.GPUTexture),
|
|
||||||
GPUTextureUsage: util.nonEnumerable(webgpu.GPUTextureUsage),
|
|
||||||
GPUTextureView: util.nonEnumerable(webgpu.GPUTextureView),
|
|
||||||
GPUSampler: util.nonEnumerable(webgpu.GPUSampler),
|
|
||||||
GPUBindGroupLayout: util.nonEnumerable(webgpu.GPUBindGroupLayout),
|
|
||||||
GPUPipelineLayout: util.nonEnumerable(webgpu.GPUPipelineLayout),
|
|
||||||
GPUBindGroup: util.nonEnumerable(webgpu.GPUBindGroup),
|
|
||||||
GPUShaderModule: util.nonEnumerable(webgpu.GPUShaderModule),
|
|
||||||
GPUShaderStage: util.nonEnumerable(webgpu.GPUShaderStage),
|
|
||||||
GPUComputePipeline: util.nonEnumerable(webgpu.GPUComputePipeline),
|
|
||||||
GPURenderPipeline: util.nonEnumerable(webgpu.GPURenderPipeline),
|
|
||||||
GPUColorWrite: util.nonEnumerable(webgpu.GPUColorWrite),
|
|
||||||
GPUCommandEncoder: util.nonEnumerable(webgpu.GPUCommandEncoder),
|
|
||||||
GPURenderPassEncoder: util.nonEnumerable(webgpu.GPURenderPassEncoder),
|
|
||||||
GPUComputePassEncoder: util.nonEnumerable(webgpu.GPUComputePassEncoder),
|
|
||||||
GPUCommandBuffer: util.nonEnumerable(webgpu.GPUCommandBuffer),
|
|
||||||
GPURenderBundleEncoder: util.nonEnumerable(webgpu.GPURenderBundleEncoder),
|
|
||||||
GPURenderBundle: util.nonEnumerable(webgpu.GPURenderBundle),
|
|
||||||
GPUQuerySet: util.nonEnumerable(webgpu.GPUQuerySet),
|
|
||||||
GPUOutOfMemoryError: util.nonEnumerable(webgpu.GPUOutOfMemoryError),
|
|
||||||
GPUValidationError: util.nonEnumerable(webgpu.GPUValidationError),
|
|
||||||
};
|
|
||||||
|
|
||||||
const mainRuntimeGlobalProperties = {
|
|
||||||
Location: location.locationConstructorDescriptor,
|
|
||||||
location: location.locationDescriptor,
|
|
||||||
Window: globalInterfaces.windowConstructorDescriptor,
|
|
||||||
window: util.readOnly(globalThis),
|
|
||||||
self: util.writable(globalThis),
|
|
||||||
Navigator: util.nonEnumerable(Navigator),
|
|
||||||
navigator: {
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
get: () => navigator,
|
|
||||||
},
|
|
||||||
close: util.writable(windowClose),
|
|
||||||
closed: util.getterOnly(() => windowIsClosing),
|
|
||||||
alert: util.writable(prompt.alert),
|
|
||||||
confirm: util.writable(prompt.confirm),
|
|
||||||
prompt: util.writable(prompt.prompt),
|
|
||||||
localStorage: {
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
get: webStorage.localStorage,
|
|
||||||
// Makes this reassignable to make astro work
|
|
||||||
set: () => {},
|
|
||||||
},
|
|
||||||
sessionStorage: {
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
get: webStorage.sessionStorage,
|
|
||||||
// Makes this reassignable to make astro work
|
|
||||||
set: () => {},
|
|
||||||
},
|
|
||||||
Storage: util.nonEnumerable(webStorage.Storage),
|
|
||||||
};
|
|
||||||
|
|
||||||
const workerRuntimeGlobalProperties = {
|
|
||||||
WorkerLocation: location.workerLocationConstructorDescriptor,
|
|
||||||
location: location.workerLocationDescriptor,
|
|
||||||
WorkerGlobalScope: globalInterfaces.workerGlobalScopeConstructorDescriptor,
|
|
||||||
DedicatedWorkerGlobalScope:
|
|
||||||
globalInterfaces.dedicatedWorkerGlobalScopeConstructorDescriptor,
|
|
||||||
WorkerNavigator: util.nonEnumerable(WorkerNavigator),
|
|
||||||
navigator: {
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
get: () => workerNavigator,
|
|
||||||
},
|
|
||||||
self: util.readOnly(globalThis),
|
|
||||||
// TODO(bartlomieju): should be readonly?
|
|
||||||
close: util.nonEnumerable(workerClose),
|
|
||||||
postMessage: util.writable(postMessage),
|
|
||||||
};
|
|
||||||
|
|
||||||
const pendingRejections = [];
|
const pendingRejections = [];
|
||||||
const pendingRejectionsReasons = new SafeWeakMap();
|
const pendingRejectionsReasons = new SafeWeakMap();
|
||||||
|
|
||||||
|
@ -726,6 +423,10 @@ delete Intl.v8BreakIterator;
|
||||||
ObjectDefineProperties(globalThis, unstableWindowOrWorkerGlobalScope);
|
ObjectDefineProperties(globalThis, unstableWindowOrWorkerGlobalScope);
|
||||||
}
|
}
|
||||||
ObjectDefineProperties(globalThis, mainRuntimeGlobalProperties);
|
ObjectDefineProperties(globalThis, mainRuntimeGlobalProperties);
|
||||||
|
ObjectDefineProperties(globalThis, {
|
||||||
|
close: util.writable(windowClose),
|
||||||
|
closed: util.getterOnly(() => windowIsClosing),
|
||||||
|
});
|
||||||
ObjectSetPrototypeOf(globalThis, Window.prototype);
|
ObjectSetPrototypeOf(globalThis, Window.prototype);
|
||||||
|
|
||||||
if (runtimeOptions.inspectFlag) {
|
if (runtimeOptions.inspectFlag) {
|
||||||
|
@ -754,9 +455,9 @@ delete Intl.v8BreakIterator;
|
||||||
|
|
||||||
runtimeStart(runtimeOptions);
|
runtimeStart(runtimeOptions);
|
||||||
|
|
||||||
numCpus = runtimeOptions.cpuCount;
|
setNumCpus(runtimeOptions.cpuCount);
|
||||||
userAgent = runtimeOptions.userAgent;
|
setUserAgent(runtimeOptions.userAgent);
|
||||||
language = runtimeOptions.locale;
|
setLanguage(runtimeOptions.locale);
|
||||||
|
|
||||||
const internalSymbol = Symbol("Deno.internal");
|
const internalSymbol = Symbol("Deno.internal");
|
||||||
|
|
||||||
|
@ -849,7 +550,12 @@ delete Intl.v8BreakIterator;
|
||||||
ObjectDefineProperties(globalThis, unstableWindowOrWorkerGlobalScope);
|
ObjectDefineProperties(globalThis, unstableWindowOrWorkerGlobalScope);
|
||||||
}
|
}
|
||||||
ObjectDefineProperties(globalThis, workerRuntimeGlobalProperties);
|
ObjectDefineProperties(globalThis, workerRuntimeGlobalProperties);
|
||||||
ObjectDefineProperties(globalThis, { name: util.writable(name) });
|
ObjectDefineProperties(globalThis, {
|
||||||
|
name: util.writable(name),
|
||||||
|
// TODO(bartlomieju): should be readonly?
|
||||||
|
close: util.nonEnumerable(workerClose),
|
||||||
|
postMessage: util.writable(postMessage),
|
||||||
|
});
|
||||||
if (runtimeOptions.enableTestingFeaturesFlag) {
|
if (runtimeOptions.enableTestingFeaturesFlag) {
|
||||||
ObjectDefineProperty(
|
ObjectDefineProperty(
|
||||||
globalThis,
|
globalThis,
|
||||||
|
@ -882,8 +588,9 @@ delete Intl.v8BreakIterator;
|
||||||
);
|
);
|
||||||
|
|
||||||
location.setLocationHref(runtimeOptions.location);
|
location.setLocationHref(runtimeOptions.location);
|
||||||
numCpus = runtimeOptions.cpuCount;
|
|
||||||
language = runtimeOptions.locale;
|
setNumCpus(runtimeOptions.cpuCount);
|
||||||
|
setLanguage(runtimeOptions.locale);
|
||||||
|
|
||||||
globalThis.pollForMessages = pollForMessages;
|
globalThis.pollForMessages = pollForMessages;
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ pub use deno_core;
|
||||||
pub use deno_crypto;
|
pub use deno_crypto;
|
||||||
pub use deno_fetch;
|
pub use deno_fetch;
|
||||||
pub use deno_ffi;
|
pub use deno_ffi;
|
||||||
|
pub use deno_flash;
|
||||||
pub use deno_http;
|
pub use deno_http;
|
||||||
pub use deno_napi;
|
pub use deno_napi;
|
||||||
pub use deno_net;
|
pub use deno_net;
|
||||||
|
|
|
@ -17,7 +17,6 @@ use deno_core::futures::channel::mpsc;
|
||||||
use deno_core::futures::future::poll_fn;
|
use deno_core::futures::future::poll_fn;
|
||||||
use deno_core::futures::stream::StreamExt;
|
use deno_core::futures::stream::StreamExt;
|
||||||
use deno_core::futures::task::AtomicWaker;
|
use deno_core::futures::task::AtomicWaker;
|
||||||
use deno_core::located_script_name;
|
|
||||||
use deno_core::serde::Deserialize;
|
use deno_core::serde::Deserialize;
|
||||||
use deno_core::serde::Serialize;
|
use deno_core::serde::Serialize;
|
||||||
use deno_core::serde_json::json;
|
use deno_core::serde_json::json;
|
||||||
|
@ -33,6 +32,7 @@ use deno_core::ModuleSpecifier;
|
||||||
use deno_core::RuntimeOptions;
|
use deno_core::RuntimeOptions;
|
||||||
use deno_core::SharedArrayBufferStore;
|
use deno_core::SharedArrayBufferStore;
|
||||||
use deno_core::SourceMapGetter;
|
use deno_core::SourceMapGetter;
|
||||||
|
use deno_core::{located_script_name, Snapshot};
|
||||||
use deno_node::RequireNpmResolver;
|
use deno_node::RequireNpmResolver;
|
||||||
use deno_tls::rustls::RootCertStore;
|
use deno_tls::rustls::RootCertStore;
|
||||||
use deno_web::create_entangled_message_port;
|
use deno_web::create_entangled_message_port;
|
||||||
|
@ -322,6 +322,7 @@ pub struct WebWorker {
|
||||||
pub struct WebWorkerOptions {
|
pub struct WebWorkerOptions {
|
||||||
pub bootstrap: BootstrapOptions,
|
pub bootstrap: BootstrapOptions,
|
||||||
pub extensions: Vec<Extension>,
|
pub extensions: Vec<Extension>,
|
||||||
|
pub startup_snapshot: Option<Snapshot>,
|
||||||
pub unsafely_ignore_certificate_errors: Option<Vec<String>>,
|
pub unsafely_ignore_certificate_errors: Option<Vec<String>>,
|
||||||
pub root_cert_store: Option<RootCertStore>,
|
pub root_cert_store: Option<RootCertStore>,
|
||||||
pub seed: Option<u64>,
|
pub seed: Option<u64>,
|
||||||
|
@ -451,7 +452,11 @@ impl WebWorker {
|
||||||
|
|
||||||
let mut js_runtime = JsRuntime::new(RuntimeOptions {
|
let mut js_runtime = JsRuntime::new(RuntimeOptions {
|
||||||
module_loader: Some(options.module_loader.clone()),
|
module_loader: Some(options.module_loader.clone()),
|
||||||
startup_snapshot: Some(js::deno_isolate_init()),
|
startup_snapshot: Some(
|
||||||
|
options
|
||||||
|
.startup_snapshot
|
||||||
|
.unwrap_or_else(js::deno_isolate_init),
|
||||||
|
),
|
||||||
source_map_getter: options.source_map_getter,
|
source_map_getter: options.source_map_getter,
|
||||||
get_error_class_fn: options.get_error_class_fn,
|
get_error_class_fn: options.get_error_class_fn,
|
||||||
shared_array_buffer_store: options.shared_array_buffer_store.clone(),
|
shared_array_buffer_store: options.shared_array_buffer_store.clone(),
|
||||||
|
|
|
@ -13,9 +13,6 @@ use deno_core::error::AnyError;
|
||||||
use deno_core::error::JsError;
|
use deno_core::error::JsError;
|
||||||
use deno_core::futures::Future;
|
use deno_core::futures::Future;
|
||||||
use deno_core::located_script_name;
|
use deno_core::located_script_name;
|
||||||
use deno_core::serde_json::json;
|
|
||||||
use deno_core::serde_v8;
|
|
||||||
use deno_core::v8;
|
|
||||||
use deno_core::CompiledWasmModuleStore;
|
use deno_core::CompiledWasmModuleStore;
|
||||||
use deno_core::Extension;
|
use deno_core::Extension;
|
||||||
use deno_core::FsModuleLoader;
|
use deno_core::FsModuleLoader;
|
||||||
|
@ -66,10 +63,6 @@ pub struct MainWorker {
|
||||||
pub js_runtime: JsRuntime,
|
pub js_runtime: JsRuntime,
|
||||||
should_break_on_first_statement: bool,
|
should_break_on_first_statement: bool,
|
||||||
exit_code: ExitCode,
|
exit_code: ExitCode,
|
||||||
js_run_tests_callback: v8::Global<v8::Function>,
|
|
||||||
js_run_benchmarks_callback: v8::Global<v8::Function>,
|
|
||||||
js_enable_test_callback: v8::Global<v8::Function>,
|
|
||||||
js_enable_bench_callback: v8::Global<v8::Function>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WorkerOptions {
|
pub struct WorkerOptions {
|
||||||
|
@ -99,15 +92,6 @@ pub struct WorkerOptions {
|
||||||
pub stdio: Stdio,
|
pub stdio: Stdio,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn grab_cb(
|
|
||||||
scope: &mut v8::HandleScope,
|
|
||||||
path: &str,
|
|
||||||
) -> v8::Global<v8::Function> {
|
|
||||||
let cb = JsRuntime::eval::<v8::Function>(scope, path)
|
|
||||||
.unwrap_or_else(|| panic!("{} must be defined", path));
|
|
||||||
v8::Global::new(scope, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for WorkerOptions {
|
impl Default for WorkerOptions {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -267,29 +251,10 @@ impl MainWorker {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (
|
|
||||||
js_run_tests_callback,
|
|
||||||
js_run_benchmarks_callback,
|
|
||||||
js_enable_test_callback,
|
|
||||||
js_enable_bench_callback,
|
|
||||||
) = {
|
|
||||||
let scope = &mut js_runtime.handle_scope();
|
|
||||||
(
|
|
||||||
grab_cb(scope, "__bootstrap.testing.runTests"),
|
|
||||||
grab_cb(scope, "__bootstrap.testing.runBenchmarks"),
|
|
||||||
grab_cb(scope, "__bootstrap.testing.enableTest"),
|
|
||||||
grab_cb(scope, "__bootstrap.testing.enableBench"),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
js_runtime,
|
js_runtime,
|
||||||
should_break_on_first_statement: options.should_break_on_first_statement,
|
should_break_on_first_statement: options.should_break_on_first_statement,
|
||||||
exit_code,
|
exit_code,
|
||||||
js_run_tests_callback,
|
|
||||||
js_run_benchmarks_callback,
|
|
||||||
js_enable_test_callback,
|
|
||||||
js_enable_bench_callback,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,65 +342,6 @@ impl MainWorker {
|
||||||
self.evaluate_module(id).await
|
self.evaluate_module(id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run tests declared with `Deno.test()`. Test events will be dispatched
|
|
||||||
/// by calling ops which are currently only implemented in the CLI crate.
|
|
||||||
// TODO(nayeemrmn): Move testing ops to deno_runtime and redesign/unhide.
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub async fn run_tests(
|
|
||||||
&mut self,
|
|
||||||
shuffle: &Option<u64>,
|
|
||||||
) -> Result<(), AnyError> {
|
|
||||||
let promise = {
|
|
||||||
let scope = &mut self.js_runtime.handle_scope();
|
|
||||||
let cb = self.js_run_tests_callback.open(scope);
|
|
||||||
let this = v8::undefined(scope).into();
|
|
||||||
let options =
|
|
||||||
serde_v8::to_v8(scope, json!({ "shuffle": shuffle })).unwrap();
|
|
||||||
let promise = cb.call(scope, this, &[options]).unwrap();
|
|
||||||
v8::Global::new(scope, promise)
|
|
||||||
};
|
|
||||||
self.js_runtime.resolve_value(promise).await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Run benches declared with `Deno.bench()`. Bench events will be dispatched
|
|
||||||
/// by calling ops which are currently only implemented in the CLI crate.
|
|
||||||
// TODO(nayeemrmn): Move benchmark ops to deno_runtime and redesign/unhide.
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub async fn run_benchmarks(&mut self) -> Result<(), AnyError> {
|
|
||||||
let promise = {
|
|
||||||
let scope = &mut self.js_runtime.handle_scope();
|
|
||||||
let cb = self.js_run_benchmarks_callback.open(scope);
|
|
||||||
let this = v8::undefined(scope).into();
|
|
||||||
let promise = cb.call(scope, this, &[]).unwrap();
|
|
||||||
v8::Global::new(scope, promise)
|
|
||||||
};
|
|
||||||
self.js_runtime.resolve_value(promise).await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Enable `Deno.test()`. If this isn't called before executing user code,
|
|
||||||
/// `Deno.test()` calls will noop.
|
|
||||||
// TODO(nayeemrmn): Move testing ops to deno_runtime and redesign/unhide.
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn enable_test(&mut self) {
|
|
||||||
let scope = &mut self.js_runtime.handle_scope();
|
|
||||||
let cb = self.js_enable_test_callback.open(scope);
|
|
||||||
let this = v8::undefined(scope).into();
|
|
||||||
cb.call(scope, this, &[]).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Enable `Deno.bench()`. If this isn't called before executing user code,
|
|
||||||
/// `Deno.bench()` calls will noop.
|
|
||||||
// TODO(nayeemrmn): Move benchmark ops to deno_runtime and redesign/unhide.
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn enable_bench(&mut self) {
|
|
||||||
let scope = &mut self.js_runtime.handle_scope();
|
|
||||||
let cb = self.js_enable_bench_callback.open(scope);
|
|
||||||
let this = v8::undefined(scope).into();
|
|
||||||
cb.call(scope, this, &[]).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn wait_for_inspector_session(&mut self) {
|
fn wait_for_inspector_session(&mut self) {
|
||||||
if self.should_break_on_first_statement {
|
if self.should_break_on_first_statement {
|
||||||
self
|
self
|
||||||
|
@ -542,107 +448,3 @@ impl MainWorker {
|
||||||
Ok(local_value.is_false())
|
Ok(local_value.is_false())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use deno_core::resolve_url_or_path;
|
|
||||||
|
|
||||||
fn create_test_worker() -> MainWorker {
|
|
||||||
let main_module = resolve_url_or_path("./hello.js").unwrap();
|
|
||||||
let permissions = Permissions::default();
|
|
||||||
|
|
||||||
let options = WorkerOptions {
|
|
||||||
bootstrap: BootstrapOptions {
|
|
||||||
args: vec![],
|
|
||||||
cpu_count: 1,
|
|
||||||
debug_flag: false,
|
|
||||||
enable_testing_features: false,
|
|
||||||
locale: deno_core::v8::icu::get_language_tag(),
|
|
||||||
location: None,
|
|
||||||
no_color: true,
|
|
||||||
is_tty: false,
|
|
||||||
runtime_version: "x".to_string(),
|
|
||||||
ts_version: "x".to_string(),
|
|
||||||
unstable: false,
|
|
||||||
user_agent: "x".to_string(),
|
|
||||||
inspect: false,
|
|
||||||
},
|
|
||||||
extensions: vec![],
|
|
||||||
startup_snapshot: None,
|
|
||||||
unsafely_ignore_certificate_errors: None,
|
|
||||||
root_cert_store: None,
|
|
||||||
seed: None,
|
|
||||||
format_js_error_fn: None,
|
|
||||||
source_map_getter: None,
|
|
||||||
web_worker_preload_module_cb: Arc::new(|_| unreachable!()),
|
|
||||||
web_worker_pre_execute_module_cb: Arc::new(|_| unreachable!()),
|
|
||||||
create_web_worker_cb: Arc::new(|_| unreachable!()),
|
|
||||||
maybe_inspector_server: None,
|
|
||||||
should_break_on_first_statement: false,
|
|
||||||
module_loader: Rc::new(FsModuleLoader),
|
|
||||||
npm_resolver: None,
|
|
||||||
get_error_class_fn: None,
|
|
||||||
cache_storage_dir: None,
|
|
||||||
origin_storage_dir: None,
|
|
||||||
blob_store: BlobStore::default(),
|
|
||||||
broadcast_channel: InMemoryBroadcastChannel::default(),
|
|
||||||
shared_array_buffer_store: None,
|
|
||||||
compiled_wasm_module_store: None,
|
|
||||||
stdio: Default::default(),
|
|
||||||
};
|
|
||||||
|
|
||||||
MainWorker::bootstrap_from_options(main_module, permissions, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn execute_mod_esm_imports_a() {
|
|
||||||
let p = test_util::testdata_path().join("runtime/esm_imports_a.js");
|
|
||||||
let module_specifier = resolve_url_or_path(&p.to_string_lossy()).unwrap();
|
|
||||||
let mut worker = create_test_worker();
|
|
||||||
let result = worker.execute_main_module(&module_specifier).await;
|
|
||||||
if let Err(err) = result {
|
|
||||||
eprintln!("execute_mod err {:?}", err);
|
|
||||||
}
|
|
||||||
if let Err(e) = worker.run_event_loop(false).await {
|
|
||||||
panic!("Future got unexpected error: {:?}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn execute_mod_circular() {
|
|
||||||
let p = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
|
||||||
.parent()
|
|
||||||
.unwrap()
|
|
||||||
.join("tests/circular1.js");
|
|
||||||
let module_specifier = resolve_url_or_path(&p.to_string_lossy()).unwrap();
|
|
||||||
let mut worker = create_test_worker();
|
|
||||||
let result = worker.execute_main_module(&module_specifier).await;
|
|
||||||
if let Err(err) = result {
|
|
||||||
eprintln!("execute_mod err {:?}", err);
|
|
||||||
}
|
|
||||||
if let Err(e) = worker.run_event_loop(false).await {
|
|
||||||
panic!("Future got unexpected error: {:?}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn execute_mod_resolve_error() {
|
|
||||||
// "foo" is not a valid module specifier so this should return an error.
|
|
||||||
let mut worker = create_test_worker();
|
|
||||||
let module_specifier = resolve_url_or_path("does-not-exist").unwrap();
|
|
||||||
let result = worker.execute_main_module(&module_specifier).await;
|
|
||||||
assert!(result.is_err());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn execute_mod_002_hello() {
|
|
||||||
// This assumes cwd is project root (an assumption made throughout the
|
|
||||||
// tests).
|
|
||||||
let mut worker = create_test_worker();
|
|
||||||
let p = test_util::testdata_path().join("run/001_hello.js");
|
|
||||||
let module_specifier = resolve_url_or_path(&p.to_string_lossy()).unwrap();
|
|
||||||
let result = worker.execute_main_module(&module_specifier).await;
|
|
||||||
assert!(result.is_ok());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue