summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2020-05-07 20:43:27 +0200
committerGitHub <noreply@github.com>2020-05-07 20:43:27 +0200
commit2b66b8a03e4f81cc158be40d07534f26fa762c2b (patch)
treebdeb6b1e6737bd839c87e2d6d178da42d9004ca4 /cli
parent93cf3bd5341d5985201ea0905280082d5a3310f9 (diff)
BREAKING: Remove support for .wasm imports (#5135)
Importing .wasm files is non-standardized therefore deciding to support current functionality past 1.0 release is risky. Besides that .wasm import posed many challenges in our codebase due to complex interactions with TS compiler which spawned thread for each encountered .wasm import. This commit removes: - cli/compilers/wasm.rs - cli/compilers/wasm_wrap.js - two integration tests related to .wasm imports
Diffstat (limited to 'cli')
-rw-r--r--cli/compilers/mod.rs2
-rw-r--r--cli/compilers/ts.rs2
-rw-r--r--cli/compilers/wasm.rs185
-rw-r--r--cli/compilers/wasm_wrap.js20
-rw-r--r--cli/global_state.rs10
-rw-r--r--cli/js.rs2
-rw-r--r--cli/js/compiler.ts49
-rw-r--r--cli/js/globals.ts1
-rw-r--r--cli/ops/compiler.rs17
-rw-r--r--cli/tests/051_wasm_import.ts22
-rw-r--r--cli/tests/051_wasm_import.ts.out1
-rw-r--r--cli/tests/051_wasm_import/remote.ts3
-rw-r--r--cli/tests/051_wasm_import/simple.wasmbin226 -> 0 bytes
-rw-r--r--cli/tests/051_wasm_import/simple.wat31
-rw-r--r--cli/tests/051_wasm_import/wasm-dep.js17
-rw-r--r--cli/tests/055_import_wasm_via_network.ts2
-rw-r--r--cli/tests/055_import_wasm_via_network.ts.out5
-rw-r--r--cli/tests/055_import_wasm_via_network.wasmbin97 -> 0 bytes
-rw-r--r--cli/tests/integration_tests.rs12
19 files changed, 5 insertions, 376 deletions
diff --git a/cli/compilers/mod.rs b/cli/compilers/mod.rs
index f773e2de6..bc3bfade2 100644
--- a/cli/compilers/mod.rs
+++ b/cli/compilers/mod.rs
@@ -6,14 +6,12 @@ use futures::Future;
mod compiler_worker;
mod js;
mod ts;
-mod wasm;
pub use js::JsCompiler;
pub use ts::runtime_compile;
pub use ts::runtime_transpile;
pub use ts::TargetLib;
pub use ts::TsCompiler;
-pub use wasm::WasmCompiler;
pub type CompilationResultFuture = dyn Future<Output = JsonResult>;
diff --git a/cli/compilers/ts.rs b/cli/compilers/ts.rs
index db4313927..832d5e6df 100644
--- a/cli/compilers/ts.rs
+++ b/cli/compilers/ts.rs
@@ -691,8 +691,6 @@ impl TsCompiler {
}
}
-// TODO(bartlomieju): exactly same function is in `wasm.rs` - only difference
-// it created WasmCompiler instead of TsCompiler - deduplicate
async fn execute_in_thread(
global_state: GlobalState,
req: Buf,
diff --git a/cli/compilers/wasm.rs b/cli/compilers/wasm.rs
deleted file mode 100644
index ed5603584..000000000
--- a/cli/compilers/wasm.rs
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use super::compiler_worker::CompilerWorker;
-use crate::compilers::CompiledModule;
-use crate::file_fetcher::SourceFile;
-use crate::global_state::GlobalState;
-use crate::startup_data;
-use crate::state::*;
-use crate::tokio_util;
-use crate::web_worker::WebWorkerHandle;
-use crate::worker::WorkerEvent;
-use deno_core::Buf;
-use deno_core::ErrBox;
-use deno_core::ModuleSpecifier;
-use serde_derive::Deserialize;
-use std::collections::HashMap;
-use std::sync::atomic::Ordering;
-use std::sync::{Arc, Mutex};
-use url::Url;
-
-// TODO(ry) The entire concept of spawning a thread, sending data to JS,
-// compiling WASM there, and moving the data back into the calling thread is
-// completelly wrong. V8 has native facilities for getting this information.
-// We might be lacking bindings for this currently in rusty_v8 but ultimately
-// this "compiler" should be calling into rusty_v8 directly, not spawning
-// threads.
-
-// TODO(kevinkassimo): This is a hack to encode/decode data as base64 string.
-// (Since Deno namespace might not be available, Deno.read can fail).
-// Binary data is already available through source_file.source_code.
-// If this is proven too wasteful in practice, refactor this.
-
-// Ref: https://webassembly.github.io/esm-integration/js-api/index.html#esm-integration
-// https://github.com/nodejs/node/blob/35ec01097b2a397ad0a22aac536fe07514876e21/lib/internal/modules/esm/translators.js#L190-L210
-
-// Dynamically construct JS wrapper with custom static imports and named exports.
-// Boots up an internal worker to resolve imports/exports through query from V8.
-
-static WASM_WRAP: &str = include_str!("./wasm_wrap.js");
-
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-struct WasmModuleInfo {
- import_list: Vec<String>,
- export_list: Vec<String>,
-}
-
-#[derive(Default)]
-pub struct WasmCompiler {
- cache: Arc<Mutex<HashMap<Url, CompiledModule>>>,
-}
-
-impl WasmCompiler {
- /// Create a new V8 worker with snapshot of WASM compiler and setup compiler's runtime.
- fn setup_worker(global_state: GlobalState) -> CompilerWorker {
- let entry_point =
- ModuleSpecifier::resolve_url_or_path("./__$deno$wasm_compiler.ts")
- .unwrap();
- let worker_state =
- State::new(global_state.clone(), None, entry_point, DebugType::Internal)
- .expect("Unable to create worker state");
-
- // Count how many times we start the compiler worker.
- global_state.compiler_starts.fetch_add(1, Ordering::SeqCst);
-
- let mut worker = CompilerWorker::new(
- "WASM".to_string(),
- startup_data::compiler_isolate_init(),
- worker_state,
- );
- worker.execute("bootstrap.wasmCompilerRuntime()").unwrap();
- worker
- }
-
- pub async fn compile(
- &self,
- global_state: GlobalState,
- source_file: &SourceFile,
- ) -> Result<CompiledModule, ErrBox> {
- let cache = self.cache.clone();
- let cache_ = self.cache.clone();
- let source_file = source_file.clone();
-
- let maybe_cached = { cache.lock().unwrap().get(&source_file.url).cloned() };
- if let Some(m) = maybe_cached {
- return Ok(m);
- }
- debug!(">>>>> wasm_compile START");
- let base64_data = base64::encode(&source_file.source_code);
- let url = source_file.url.clone();
- let req_msg = serde_json::to_string(&base64_data)
- .unwrap()
- .into_boxed_str()
- .into_boxed_bytes();
- let msg = execute_in_thread(global_state.clone(), req_msg).await?;
- debug!("Received message from worker");
- let module_info: WasmModuleInfo = serde_json::from_slice(&msg).unwrap();
- debug!("WASM module info: {:#?}", &module_info);
- let code = wrap_wasm_code(
- &base64_data,
- &module_info.import_list,
- &module_info.export_list,
- );
- debug!("Generated code: {}", &code);
- let module = CompiledModule {
- code,
- name: url.to_string(),
- };
- {
- cache_.lock().unwrap().insert(url.clone(), module.clone());
- }
- debug!("<<<<< wasm_compile END");
- Ok(module)
- }
-}
-
-async fn execute_in_thread(
- global_state: GlobalState,
- req: Buf,
-) -> Result<Buf, ErrBox> {
- let (handle_sender, handle_receiver) =
- std::sync::mpsc::sync_channel::<Result<WebWorkerHandle, ErrBox>>(1);
- let builder =
- std::thread::Builder::new().name("deno-wasm-compiler".to_string());
- let join_handle = builder.spawn(move || {
- let worker = WasmCompiler::setup_worker(global_state);
- handle_sender.send(Ok(worker.thread_safe_handle())).unwrap();
- drop(handle_sender);
- tokio_util::run_basic(worker).expect("Panic in event loop");
- })?;
- let handle = handle_receiver.recv().unwrap()?;
- handle.post_message(req)?;
- let event = handle.get_event().await.expect("Compiler didn't respond");
- let buf = match event {
- WorkerEvent::Message(buf) => Ok(buf),
- WorkerEvent::Error(error) => Err(error),
- WorkerEvent::TerminalError(error) => Err(error),
- }?;
- // Shutdown worker and wait for thread to finish
- handle.terminate();
- join_handle.join().unwrap();
- Ok(buf)
-}
-
-fn build_single_import(index: usize, origin: &str) -> String {
- let origin_json = serde_json::to_string(origin).unwrap();
- format!(
- r#"import * as m{} from {};
-importObject[{}] = m{};
-"#,
- index, &origin_json, &origin_json, index
- )
-}
-
-fn build_imports(imports: &[String]) -> String {
- let mut code = String::from("");
- for (index, origin) in imports.iter().enumerate() {
- code.push_str(&build_single_import(index, origin));
- }
- code
-}
-
-fn build_single_export(name: &str) -> String {
- format!("export const {} = instance.exports.{};\n", name, name)
-}
-
-fn build_exports(exports: &[String]) -> String {
- let mut code = String::from("");
- for e in exports {
- code.push_str(&build_single_export(e));
- }
- code
-}
-
-fn wrap_wasm_code(
- base64_data: &str,
- imports: &[String],
- exports: &[String],
-) -> String {
- let imports_code = build_imports(imports);
- let exports_code = build_exports(exports);
- String::from(WASM_WRAP)
- .replace("//IMPORTS\n", &imports_code)
- .replace("//EXPORTS\n", &exports_code)
- .replace("BASE64_DATA", base64_data)
-}
diff --git a/cli/compilers/wasm_wrap.js b/cli/compilers/wasm_wrap.js
deleted file mode 100644
index 98892b8e0..000000000
--- a/cli/compilers/wasm_wrap.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// @ts-nocheck
-const importObject = Object.create(null);
-//IMPORTS
-
-function base64ToUint8Array(data) {
- const binString = window.atob(data);
- const size = binString.length;
- const bytes = new Uint8Array(size);
- for (let i = 0; i < size; i++) {
- bytes[i] = binString.charCodeAt(i);
- }
- return bytes;
-}
-
-const buffer = base64ToUint8Array("BASE64_DATA");
-const compiled = await WebAssembly.compile(buffer);
-
-const instance = new WebAssembly.Instance(compiled, importObject);
-
-//EXPORTS
diff --git a/cli/global_state.rs b/cli/global_state.rs
index dbea5f827..460203364 100644
--- a/cli/global_state.rs
+++ b/cli/global_state.rs
@@ -3,7 +3,6 @@ use crate::compilers::CompiledModule;
use crate::compilers::JsCompiler;
use crate::compilers::TargetLib;
use crate::compilers::TsCompiler;
-use crate::compilers::WasmCompiler;
use crate::deno_dir;
use crate::file_fetcher::SourceFileFetcher;
use crate::flags;
@@ -36,7 +35,6 @@ pub struct GlobalStateInner {
pub file_fetcher: SourceFileFetcher,
pub js_compiler: JsCompiler,
pub ts_compiler: TsCompiler,
- pub wasm_compiler: WasmCompiler,
pub lockfile: Option<Mutex<Lockfile>>,
pub compiler_starts: AtomicUsize,
compile_lock: AsyncMutex<()>,
@@ -87,7 +85,6 @@ impl GlobalState {
file_fetcher,
ts_compiler,
js_compiler: JsCompiler {},
- wasm_compiler: WasmCompiler::default(),
lockfile,
compiler_starts: AtomicUsize::new(0),
compile_lock: AsyncMutex::new(()),
@@ -116,12 +113,6 @@ impl GlobalState {
let compile_lock = self.compile_lock.lock().await;
let compiled_module = match out.media_type {
- msg::MediaType::Json | msg::MediaType::Unknown => {
- state1.js_compiler.compile(out).await
- }
- msg::MediaType::Wasm => {
- state1.wasm_compiler.compile(state1.clone(), &out).await
- }
msg::MediaType::TypeScript
| msg::MediaType::TSX
| msg::MediaType::JSX => {
@@ -152,6 +143,7 @@ impl GlobalState {
state1.js_compiler.compile(out).await
}
}
+ _ => state1.js_compiler.compile(out).await,
}?;
drop(compile_lock);
diff --git a/cli/js.rs b/cli/js.rs
index 2985d2568..2b499987f 100644
--- a/cli/js.rs
+++ b/cli/js.rs
@@ -50,7 +50,7 @@ fn compiler_snapshot() {
deno_core::js_check(isolate.execute(
"<anon>",
r#"
- if (!(bootstrap.tsCompilerRuntime && bootstrap.wasmCompilerRuntime)) {
+ if (!(bootstrap.tsCompilerRuntime)) {
throw Error("bad");
}
console.log(`ts version: ${ts.version}`);
diff --git a/cli/js/compiler.ts b/cli/js/compiler.ts
index 0c1f8dcc9..146529edd 100644
--- a/cli/js/compiler.ts
+++ b/cli/js/compiler.ts
@@ -4,10 +4,9 @@
// This module is the entry point for "compiler" isolate, ie. the one
// that is created when Deno needs to compile TS/WASM to JS.
//
-// It provides a two functions that should be called by Rust:
+// It provides a single functions that should be called by Rust:
// - `bootstrapTsCompilerRuntime`
-// - `bootstrapWasmCompilerRuntime`
-// Either of these functions must be called when creating isolate
+// This functions must be called when creating isolate
// to properly setup runtime.
// NOTE: this import has side effects!
@@ -22,7 +21,6 @@ import { sendAsync, sendSync } from "./ops/dispatch_json.ts";
import { bootstrapWorkerRuntime } from "./runtime_worker.ts";
import { assert, log } from "./util.ts";
import * as util from "./util.ts";
-import { atob } from "./web/text_encoding.ts";
import { TextDecoder, TextEncoder } from "./web/text_encoding.ts";
import { core } from "./core.ts";
@@ -1123,16 +1121,6 @@ function commonPath(paths: string[], sep = "/"): string {
return prefix.endsWith(sep) ? prefix : `${prefix}${sep}`;
}
-function base64ToUint8Array(data: string): Uint8Array {
- const binString = atob(data);
- const size = binString.length;
- const bytes = new Uint8Array(size);
- for (let i = 0; i < size; i++) {
- bytes[i] = binString.charCodeAt(i);
- }
- return bytes;
-}
-
let rootExports: string[] | undefined;
function normalizeUrl(rootName: string): string {
@@ -1585,43 +1573,11 @@ async function tsCompilerOnMessage({
// Currently Rust shuts down worker after single request
}
-async function wasmCompilerOnMessage({
- data: binary,
-}: {
- data: string;
-}): Promise<void> {
- const buffer = base64ToUint8Array(binary);
- // @ts-ignore
- const compiled = await WebAssembly.compile(buffer);
-
- util.log(">>> WASM compile start");
-
- const importList = Array.from(
- // @ts-ignore
- new Set(WebAssembly.Module.imports(compiled).map(({ module }) => module))
- );
- const exportList = Array.from(
- // @ts-ignore
- new Set(WebAssembly.Module.exports(compiled).map(({ name }) => name))
- );
-
- globalThis.postMessage({ importList, exportList });
-
- util.log("<<< WASM compile end");
-
- // Currently Rust shuts down worker after single request
-}
-
function bootstrapTsCompilerRuntime(): void {
bootstrapWorkerRuntime("TS", false);
globalThis.onmessage = tsCompilerOnMessage;
}
-function bootstrapWasmCompilerRuntime(): void {
- bootstrapWorkerRuntime("WASM", false);
- globalThis.onmessage = wasmCompilerOnMessage;
-}
-
// Removes the `__proto__` for security reasons. This intentionally makes
// Deno non compliant with ECMA-262 Annex B.2.2.1
//
@@ -1632,7 +1588,6 @@ Object.defineProperties(globalThis, {
bootstrap: {
value: {
...globalThis.bootstrap,
- wasmCompilerRuntime: bootstrapWasmCompilerRuntime,
tsCompilerRuntime: bootstrapTsCompilerRuntime,
},
configurable: true,
diff --git a/cli/js/globals.ts b/cli/js/globals.ts
index 89f6075a3..5a04ec443 100644
--- a/cli/js/globals.ts
+++ b/cli/js/globals.ts
@@ -147,7 +147,6 @@ declare global {
workerRuntime: ((name: string) => Promise<void> | void) | undefined;
// Assigned to `self` global - compiler
tsCompilerRuntime: (() => void) | undefined;
- wasmCompilerRuntime: (() => void) | undefined;
};
var onerror:
diff --git a/cli/ops/compiler.rs b/cli/ops/compiler.rs
index d93a0edf4..83b6d944c 100644
--- a/cli/ops/compiler.rs
+++ b/cli/ops/compiler.rs
@@ -3,7 +3,6 @@ use super::dispatch_json::Deserialize;
use super::dispatch_json::JsonOp;
use super::dispatch_json::Value;
use crate::futures::future::try_join_all;
-use crate::msg;
use crate::op_error::OpError;
use crate::state::State;
use deno_core::CoreIsolate;
@@ -125,21 +124,7 @@ fn op_fetch_source_files(
}
_ => f,
};
- // Special handling of WASM and JSON files:
- // compile them into JS first!
- // This allows TS to do correct export types as well as bundles.
- let source_code = match file.media_type {
- msg::MediaType::Wasm => {
- global_state
- .wasm_compiler
- .compile(global_state.clone(), &file)
- .await
- .map_err(|e| OpError::other(e.to_string()))?
- .code
- }
- _ => String::from_utf8(file.source_code)
- .map_err(|_| OpError::invalid_utf8())?,
- };
+ let source_code = String::from_utf8(file.source_code).map_err(|_| OpError::invalid_utf8())?;
Ok::<_, OpError>(json!({
"url": file.url.to_string(),
"filename": file.filename.to_str().unwrap(),
diff --git a/cli/tests/051_wasm_import.ts b/cli/tests/051_wasm_import.ts
deleted file mode 100644
index 7000657c3..000000000
--- a/cli/tests/051_wasm_import.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { add, addImported, addRemote } from "./051_wasm_import/simple.wasm";
-import { state } from "./051_wasm_import/wasm-dep.js";
-
-function assertEquals(actual: unknown, expected: unknown, msg?: string): void {
- if (actual !== expected) {
- throw new Error(msg);
- }
-}
-
-assertEquals(state, "WASM Start Executed", "Incorrect state");
-
-assertEquals(add(10, 20), 30, "Incorrect add");
-
-assertEquals(addImported(0), 42, "Incorrect addImported");
-
-assertEquals(state, "WASM JS Function Executed", "Incorrect state");
-
-assertEquals(addImported(1), 43, "Incorrect addImported");
-
-assertEquals(addRemote(1), 2020, "Incorrect addRemote");
-
-console.log("Passed");
diff --git a/cli/tests/051_wasm_import.ts.out b/cli/tests/051_wasm_import.ts.out
deleted file mode 100644
index 863339fb8..000000000
--- a/cli/tests/051_wasm_import.ts.out
+++ /dev/null
@@ -1 +0,0 @@
-Passed
diff --git a/cli/tests/051_wasm_import/remote.ts b/cli/tests/051_wasm_import/remote.ts
deleted file mode 100644
index 761a5248e..000000000
--- a/cli/tests/051_wasm_import/remote.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export function jsRemoteFn(): number {
- return 2019;
-}
diff --git a/cli/tests/051_wasm_import/simple.wasm b/cli/tests/051_wasm_import/simple.wasm
deleted file mode 100644
index 8e544fe30..000000000
--- a/cli/tests/051_wasm_import/simple.wasm
+++ /dev/null
Binary files differ
diff --git a/cli/tests/051_wasm_import/simple.wat b/cli/tests/051_wasm_import/simple.wat
deleted file mode 100644
index 5e73db97b..000000000
--- a/cli/tests/051_wasm_import/simple.wat
+++ /dev/null
@@ -1,31 +0,0 @@
-;; From https://github.com/nodejs/node/blob/bbc254db5db672643aad89a436a4938412a5704e/test/fixtures/es-modules/simple.wat
-;; MIT Licensed
-;; $ wat2wasm simple.wat -o simple.wasm
-
-(module
- (import "./wasm-dep.js" "jsFn" (func $jsFn (result i32)))
- (import "./wasm-dep.js" "jsInitFn" (func $jsInitFn))
- (import "http://127.0.0.1:4545/cli/tests/051_wasm_import/remote.ts" "jsRemoteFn" (func $jsRemoteFn (result i32)))
- (export "add" (func $add))
- (export "addImported" (func $addImported))
- (export "addRemote" (func $addRemote))
- (start $startFn)
- (func $startFn
- call $jsInitFn
- )
- (func $add (param $a i32) (param $b i32) (result i32)
- local.get $a
- local.get $b
- i32.add
- )
- (func $addImported (param $a i32) (result i32)
- local.get $a
- call $jsFn
- i32.add
- )
- (func $addRemote (param $a i32) (result i32)
- local.get $a
- call $jsRemoteFn
- i32.add
- )
-)
diff --git a/cli/tests/051_wasm_import/wasm-dep.js b/cli/tests/051_wasm_import/wasm-dep.js
deleted file mode 100644
index 70b16348b..000000000
--- a/cli/tests/051_wasm_import/wasm-dep.js
+++ /dev/null
@@ -1,17 +0,0 @@
-function assertEquals(actual, expected, msg) {
- if (actual !== expected) {
- throw new Error(msg || "");
- }
-}
-
-export function jsFn() {
- state = "WASM JS Function Executed";
- return 42;
-}
-
-export let state = "JS Function Executed";
-
-export function jsInitFn() {
- assertEquals(state, "JS Function Executed", "Incorrect state");
- state = "WASM Start Executed";
-}
diff --git a/cli/tests/055_import_wasm_via_network.ts b/cli/tests/055_import_wasm_via_network.ts
deleted file mode 100644
index 70d80365e..000000000
--- a/cli/tests/055_import_wasm_via_network.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-import * as wasm from "./055_import_wasm_via_network.wasm";
-console.log(wasm);
diff --git a/cli/tests/055_import_wasm_via_network.ts.out b/cli/tests/055_import_wasm_via_network.ts.out
deleted file mode 100644
index c43c192fb..000000000
--- a/cli/tests/055_import_wasm_via_network.ts.out
+++ /dev/null
@@ -1,5 +0,0 @@
-Module {
- add_one: [Function: 0],
- memory: WebAssembly.Memory {},
- Symbol(Symbol.toStringTag): "Module"
-}
diff --git a/cli/tests/055_import_wasm_via_network.wasm b/cli/tests/055_import_wasm_via_network.wasm
deleted file mode 100644
index fb6d3e471..000000000
--- a/cli/tests/055_import_wasm_via_network.wasm
+++ /dev/null
Binary files differ
diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs
index b549dc6d0..bbd437623 100644
--- a/cli/tests/integration_tests.rs
+++ b/cli/tests/integration_tests.rs
@@ -1143,12 +1143,6 @@ itest_ignore!(_049_info_flag_script_jsx {
http_server: true,
});
-itest!(_051_wasm_import {
- args: "run --reload --allow-net --allow-read 051_wasm_import.ts",
- output: "051_wasm_import.ts.out",
- http_server: true,
-});
-
// TODO(ry) Re-enable flaky test https://github.com/denoland/deno/issues/4049
itest_ignore!(_052_no_remote_flag {
args:
@@ -1165,12 +1159,6 @@ itest!(_054_info_local_imports {
exit_code: 0,
});
-itest!(_055_import_wasm_via_network {
- args: "run --reload http://127.0.0.1:4545/cli/tests/055_import_wasm_via_network.ts",
- output: "055_import_wasm_via_network.ts.out",
- http_server: true,
-});
-
itest!(_056_make_temp_file_write_perm {
args:
"run --allow-read --allow-write=./subdir/ 056_make_temp_file_write_perm.ts",