From 91b606aaae23bcb790b55adc5fe70a182a37d564 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Tue, 25 Feb 2020 09:14:27 -0500 Subject: [PATCH] Clean up how we use opIds (#4118) --- cli/build.rs | 53 ++++++-------------- cli/js/chmod.ts | 5 +- cli/js/chown.ts | 5 +- cli/js/compiler_api.ts | 13 ++--- cli/js/compiler_imports.ts | 5 +- cli/js/compiler_util.ts | 24 ++------- cli/js/copy_file.ts | 5 +- cli/js/dir.ts | 5 +- cli/js/dispatch.ts | 85 +------------------------------- cli/js/dispatch_json.ts | 9 +++- cli/js/dispatch_json_test.ts | 6 ++- cli/js/dispatch_minimal_test.ts | 7 +-- cli/js/error_stack.ts | 3 +- cli/js/fetch.ts | 3 +- cli/js/files.ts | 36 ++++++++++---- cli/js/format_error.ts | 5 +- cli/js/fs_events.ts | 5 +- cli/js/get_random_values.ts | 3 +- cli/js/link.ts | 5 +- cli/js/make_temp.ts | 9 ++-- cli/js/metrics.ts | 3 +- cli/js/mkdir.ts | 5 +- cli/js/net.ts | 13 +++-- cli/js/os.ts | 21 ++++---- cli/js/performance.ts | 3 +- cli/js/permissions.ts | 7 ++- cli/js/plugins.ts | 3 +- cli/js/process.ts | 7 ++- cli/js/read_dir.ts | 5 +- cli/js/read_link.ts | 5 +- cli/js/realpath.ts | 5 +- cli/js/remove.ts | 5 +- cli/js/rename.ts | 5 +- cli/js/repl.ts | 5 +- cli/js/resources.ts | 3 +- cli/js/runtime.ts | 14 +++--- cli/js/runtime_worker.ts | 5 +- cli/js/signals.ts | 7 ++- cli/js/stat.ts | 9 ++-- cli/js/symlink.ts | 5 +- cli/js/timers.ts | 5 +- cli/js/tls.ts | 7 ++- cli/js/truncate.ts | 5 +- cli/js/url_test.ts | 6 +++ cli/js/utime.ts | 5 +- cli/js/workers.ts | 9 ++-- cli/ops/compiler.rs | 40 +++------------ cli/ops/errors.rs | 14 ++---- cli/ops/fetch.rs | 3 +- cli/ops/files.rs | 7 ++- cli/ops/fs.rs | 43 +++++++--------- cli/ops/fs_events.rs | 11 +---- cli/ops/io.rs | 77 ++++++++++------------------- cli/ops/net.rs | 41 +++++++-------- cli/ops/os.rs | 24 ++++----- cli/ops/permissions.rs | 13 +++-- cli/ops/plugins.rs | 2 +- cli/ops/process.rs | 10 ++-- cli/ops/random.rs | 5 +- cli/ops/repl.rs | 11 +---- cli/ops/resources.rs | 3 +- cli/ops/runtime.rs | 5 +- cli/ops/runtime_compiler.rs | 5 +- cli/ops/signal.rs | 16 ++---- cli/ops/timers.rs | 12 ++--- cli/ops/tls.rs | 32 ++++-------- cli/ops/web_worker.rs | 4 +- cli/ops/worker_host.rs | 18 +++---- cli/state.rs | 11 +++++ core/bindings.rs | 13 +++-- core/ops.rs | 1 - deno_typescript/compiler_main.js | 11 ++--- deno_typescript/lib.rs | 51 ++++++++++++++----- deno_typescript/ops.rs | 10 ++-- 74 files changed, 367 insertions(+), 589 deletions(-) diff --git a/cli/build.rs b/cli/build.rs index a94f3925b4..98fc8dbc08 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -1,38 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. use deno_core::include_crate_modules; -use deno_core::CoreOp; use deno_core::Isolate; -use deno_core::Op; use deno_core::StartupData; -use deno_core::ZeroCopyBuf; use std::collections::HashMap; use std::env; use std::path::PathBuf; -fn op_fetch_asset( - custom_assets: HashMap, -) -> impl Fn(&[u8], Option) -> CoreOp { - move |control: &[u8], zero_copy_buf: Option| -> CoreOp { - assert!(zero_copy_buf.is_none()); // zero_copy_buf unused in this op. - let name = std::str::from_utf8(control).unwrap(); - - let asset_code = if let Some(source_code) = deno_typescript::get_asset(name) - { - source_code.to_string() - } else if let Some(asset_path) = custom_assets.clone().get(name) { - let source_code_vec = - std::fs::read(&asset_path).expect("Asset not found"); - let source_code = std::str::from_utf8(&source_code_vec).unwrap(); - source_code.to_string() - } else { - panic!("op_fetch_asset bad asset {}", name) - }; - - let vec = asset_code.into_bytes(); - Op::Sync(vec.into_boxed_slice()) - } -} - fn main() { // Don't build V8 if "cargo doc" is being run. This is to support docs.rs. if env::var_os("RUSTDOCFLAGS").is_some() { @@ -89,6 +62,17 @@ fn main() { let root_names = vec![c.join("js/compiler.ts")]; let bundle_path = o.join("COMPILER_SNAPSHOT.js"); let snapshot_path = o.join("COMPILER_SNAPSHOT.bin"); + + let main_module_name = deno_typescript::compile_bundle( + &bundle_path, + root_names, + Some(extern_crate_modules), + ) + .expect("Bundle compilation failed"); + assert!(bundle_path.exists()); + + let runtime_isolate = &mut Isolate::new(StartupData::None, true); + let mut custom_libs: HashMap = HashMap::new(); custom_libs.insert( "lib.deno.window.d.ts".to_string(), @@ -106,17 +90,10 @@ fn main() { "lib.deno.ns.d.ts".to_string(), c.join("js/lib.deno.ns.d.ts"), ); - - let main_module_name = deno_typescript::compile_bundle( - &bundle_path, - root_names, - Some(extern_crate_modules), - ) - .expect("Bundle compilation failed"); - assert!(bundle_path.exists()); - - let runtime_isolate = &mut Isolate::new(StartupData::None, true); - runtime_isolate.register_op("fetch_asset", op_fetch_asset(custom_libs)); + runtime_isolate.register_op( + "op_fetch_asset", + deno_typescript::op_fetch_asset(custom_libs), + ); deno_typescript::mksnapshot_bundle_ts( runtime_isolate, diff --git a/cli/js/chmod.ts b/cli/js/chmod.ts index 722a9054cc..22bd8c40e3 100644 --- a/cli/js/chmod.ts +++ b/cli/js/chmod.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; /** Changes the permission of a specific file/directory of specified path * synchronously. @@ -8,7 +7,7 @@ import * as dispatch from "./dispatch.ts"; * Deno.chmodSync("/path/to/file", 0o666); */ export function chmodSync(path: string, mode: number): void { - sendSync(dispatch.OP_CHMOD, { path, mode }); + sendSync("op_chmod", { path, mode }); } /** Changes the permission of a specific file/directory of specified path. @@ -16,5 +15,5 @@ export function chmodSync(path: string, mode: number): void { * await Deno.chmod("/path/to/file", 0o666); */ export async function chmod(path: string, mode: number): Promise { - await sendAsync(dispatch.OP_CHMOD, { path, mode }); + await sendAsync("op_chmod", { path, mode }); } diff --git a/cli/js/chown.ts b/cli/js/chown.ts index 373d075b0c..d56be3dc2b 100644 --- a/cli/js/chown.ts +++ b/cli/js/chown.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; /** * Change owner of a regular file or directory synchronously. Unix only at the moment. @@ -9,7 +8,7 @@ import * as dispatch from "./dispatch.ts"; * @param gid group id of the new owner */ export function chownSync(path: string, uid: number, gid: number): void { - sendSync(dispatch.OP_CHOWN, { path, uid, gid }); + sendSync("op_chown", { path, uid, gid }); } /** @@ -23,5 +22,5 @@ export async function chown( uid: number, gid: number ): Promise { - await sendAsync(dispatch.OP_CHOWN, { path, uid, gid }); + await sendAsync("op_chown", { path, uid, gid }); } diff --git a/cli/js/compiler_api.ts b/cli/js/compiler_api.ts index d397ca5685..33748d2b8a 100644 --- a/cli/js/compiler_api.ts +++ b/cli/js/compiler_api.ts @@ -4,7 +4,6 @@ // compiler within Deno. import { DiagnosticItem } from "./diagnostics.ts"; -import * as dispatch from "./dispatch.ts"; import { sendAsync } from "./dispatch_json.ts"; import * as util from "./util.ts"; @@ -296,9 +295,7 @@ export function transpileOnly( sources, options: options ? JSON.stringify(options) : undefined }; - return sendAsync(dispatch.OP_TRANSPILE, payload).then(result => - JSON.parse(result) - ); + return sendAsync("op_transpile", payload).then(result => JSON.parse(result)); } /** Takes a root module name, any optionally a record set of sources. Resolves @@ -344,9 +341,7 @@ export function compile( sources: !!sources, options }); - return sendAsync(dispatch.OP_COMPILE, payload).then(result => - JSON.parse(result) - ); + return sendAsync("op_compile", payload).then(result => JSON.parse(result)); } /** Takes a root module name, and optionally a record set of sources. Resolves @@ -393,7 +388,5 @@ export function bundle( sources: !!sources, options }); - return sendAsync(dispatch.OP_COMPILE, payload).then(result => - JSON.parse(result) - ); + return sendAsync("op_compile", payload).then(result => JSON.parse(result)); } diff --git a/cli/js/compiler_imports.ts b/cli/js/compiler_imports.ts index 09b2d4ba14..6e8a6585df 100644 --- a/cli/js/compiler_imports.ts +++ b/cli/js/compiler_imports.ts @@ -6,7 +6,6 @@ import { SourceFileJson } from "./compiler_sourcefile.ts"; import { cwd } from "./dir.ts"; -import * as dispatch from "./dispatch.ts"; import { sendAsync, sendSync } from "./dispatch_json.ts"; import { assert } from "./util.ts"; import * as util from "./util.ts"; @@ -68,7 +67,7 @@ export function resolveModules( referrer?: string ): string[] { util.log("compiler_imports::resolveModules", { specifiers, referrer }); - return sendSync(dispatch.OP_RESOLVE_MODULES, { specifiers, referrer }); + return sendSync("op_resolve_modules", { specifiers, referrer }); } /** Ops to Rust to fetch modules meta data. */ @@ -77,7 +76,7 @@ function fetchSourceFiles( referrer?: string ): Promise { util.log("compiler_imports::fetchSourceFiles", { specifiers, referrer }); - return sendAsync(dispatch.OP_FETCH_SOURCE_FILES, { + return sendAsync("op_fetch_source_files", { specifiers, referrer }); diff --git a/cli/js/compiler_util.ts b/cli/js/compiler_util.ts index 6da38ab3be..8a043d7d18 100644 --- a/cli/js/compiler_util.ts +++ b/cli/js/compiler_util.ts @@ -6,7 +6,6 @@ import { buildBundle } from "./compiler_bundler.ts"; import { ConfigureResponse, Host } from "./compiler_host.ts"; import { SourceFile } from "./compiler_sourcefile.ts"; import { sendSync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; import { TextDecoder, TextEncoder } from "./text_encoding.ts"; import { core } from "./core.ts"; import * as util from "./util.ts"; @@ -71,7 +70,7 @@ function cache( if (emittedFileName.endsWith(".map")) { // Source Map - sendSync(dispatch.OP_CACHE, { + sendSync("op_cache", { extension: ".map", moduleId, contents @@ -81,7 +80,7 @@ function cache( emittedFileName.endsWith(".json") ) { // Compiled JavaScript - sendSync(dispatch.OP_CACHE, { + sendSync("op_cache", { extension: ".js", moduleId, contents @@ -91,30 +90,15 @@ function cache( } } -let OP_FETCH_ASSET: number; const encoder = new TextEncoder(); const decoder = new TextDecoder(); /** Retrieve an asset from Rust. */ export function getAsset(name: string): string { - // this path should only be called for assets that are lazily loaded at - // runtime - if (dispatch.OP_FETCH_ASSET) { - util.log("compiler_util::getAsset", name); - return sendSync(dispatch.OP_FETCH_ASSET, { name }).sourceCode; - } - - // this path should only be taken during snapshotting - if (!OP_FETCH_ASSET) { - const ops = core.ops(); - const opFetchAsset = ops["fetch_asset"]; - assert(opFetchAsset, "OP_FETCH_ASSET is not registered"); - OP_FETCH_ASSET = opFetchAsset; - } - + const opId = core.ops()["op_fetch_asset"]; // We really don't want to depend on JSON dispatch during snapshotting, so // this op exchanges strings with Rust as raw byte arrays. - const sourceCodeBytes = core.dispatch(OP_FETCH_ASSET, encoder.encode(name)); + const sourceCodeBytes = core.dispatch(opId, encoder.encode(name)); return decoder.decode(sourceCodeBytes!); } diff --git a/cli/js/copy_file.ts b/cli/js/copy_file.ts index 538a7a0ba6..8ab013aab7 100644 --- a/cli/js/copy_file.ts +++ b/cli/js/copy_file.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; /** Copies the contents of a file to another by name synchronously. * Creates a new file if target does not exists, and if target exists, @@ -12,7 +11,7 @@ import * as dispatch from "./dispatch.ts"; * Deno.copyFileSync("from.txt", "to.txt"); */ export function copyFileSync(from: string, to: string): void { - sendSync(dispatch.OP_COPY_FILE, { from, to }); + sendSync("op_copy_file", { from, to }); } /** Copies the contents of a file to another by name. @@ -26,5 +25,5 @@ export function copyFileSync(from: string, to: string): void { * await Deno.copyFile("from.txt", "to.txt"); */ export async function copyFile(from: string, to: string): Promise { - await sendAsync(dispatch.OP_COPY_FILE, { from, to }); + await sendAsync("op_copy_file", { from, to }); } diff --git a/cli/js/dir.ts b/cli/js/dir.ts index d9758570ef..eea2ef6910 100644 --- a/cli/js/dir.ts +++ b/cli/js/dir.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; /** * `cwd()` Return a string representing the current working directory. @@ -10,7 +9,7 @@ import * as dispatch from "./dispatch.ts"; * throws `NotFound` exception if directory not available */ export function cwd(): string { - return sendSync(dispatch.OP_CWD); + return sendSync("op_cwd"); } /** @@ -18,5 +17,5 @@ export function cwd(): string { * throws `NotFound` exception if directory not available */ export function chdir(directory: string): void { - sendSync(dispatch.OP_CHDIR, { directory }); + sendSync("op_chdir", { directory }); } diff --git a/cli/js/dispatch.ts b/cli/js/dispatch.ts index 1b7e234632..db10db8ca1 100644 --- a/cli/js/dispatch.ts +++ b/cli/js/dispatch.ts @@ -3,87 +3,6 @@ import * as minimal from "./dispatch_minimal.ts"; import * as json from "./dispatch_json.ts"; import { AsyncHandler } from "./plugins.ts"; -// These consts are shared with Rust. Update with care. -export let OP_READ: number; -export let OP_WRITE: number; -export let OP_EXIT: number; -export let OP_IS_TTY: number; -export let OP_ENV: number; -export let OP_EXEC_PATH: number; -export let OP_UTIME: number; -export let OP_SET_ENV: number; -export let OP_GET_ENV: number; -export let OP_GET_DIR: number; -export let OP_START: number; -export let OP_APPLY_SOURCE_MAP: number; -export let OP_FORMAT_ERROR: number; -export let OP_FORMAT_DIAGNOSTIC: number; -export let OP_CACHE: number; -export let OP_RESOLVE_MODULES: number; -export let OP_FETCH_ASSET: number; -export let OP_FETCH_SOURCE_FILES: number; -export let OP_OPEN: number; -export let OP_CLOSE: number; -export let OP_SEEK: number; -export let OP_FETCH: number; -export let OP_METRICS: number; -export let OP_REPL_START: number; -export let OP_REPL_READLINE: number; -export let OP_ACCEPT: number; -export let OP_ACCEPT_TLS: number; -export let OP_RECEIVE: number; -export let OP_SEND: number; -export let OP_CONNECT: number; -export let OP_SHUTDOWN: number; -export let OP_LISTEN: number; -export let OP_LISTEN_TLS: number; -export let OP_RESOURCES: number; -export let OP_GET_RANDOM_VALUES: number; -export let OP_GLOBAL_TIMER_STOP: number; -export let OP_GLOBAL_TIMER: number; -export let OP_NOW: number; -export let OP_QUERY_PERMISSION: number; -export let OP_REVOKE_PERMISSION: number; -export let OP_REQUEST_PERMISSION: number; -export let OP_CREATE_WORKER: number; -export let OP_HOST_POST_MESSAGE: number; -export let OP_HOST_TERMINATE_WORKER: number; -export let OP_HOST_GET_MESSAGE: number; -export let OP_WORKER_POST_MESSAGE: number; -export let OP_WORKER_CLOSE: number; -export let OP_RUN: number; -export let OP_RUN_STATUS: number; -export let OP_KILL: number; -export let OP_CHDIR: number; -export let OP_MKDIR: number; -export let OP_CHMOD: number; -export let OP_CHOWN: number; -export let OP_REMOVE: number; -export let OP_COPY_FILE: number; -export let OP_STAT: number; -export let OP_REALPATH: number; -export let OP_READ_DIR: number; -export let OP_RENAME: number; -export let OP_LINK: number; -export let OP_SYMLINK: number; -export let OP_READ_LINK: number; -export let OP_TRUNCATE: number; -export let OP_MAKE_TEMP_DIR: number; -export let OP_MAKE_TEMP_FILE: number; -export let OP_CWD: number; -export let OP_CONNECT_TLS: number; -export let OP_HOSTNAME: number; -export let OP_OPEN_PLUGIN: number; -export let OP_FS_EVENTS_OPEN: number; -export let OP_FS_EVENTS_POLL: number; -export let OP_COMPILE: number; -export let OP_TRANSPILE: number; -export let OP_SIGNAL_BIND: number; -export let OP_SIGNAL_UNBIND: number; -export let OP_SIGNAL_POLL: number; -export let OP_LOADAVG: number; -export let OP_OS_RELEASE: number; - const PLUGIN_ASYNC_HANDLER_MAP: Map = new Map(); export function setPluginAsyncHandler( @@ -95,8 +14,8 @@ export function setPluginAsyncHandler( export function getAsyncHandler(opName: string): (msg: Uint8Array) => void { switch (opName) { - case "OP_WRITE": - case "OP_READ": + case "op_write": + case "op_read": return minimal.asyncMsgFromRust; default: return json.asyncMsgFromRust; diff --git a/cli/js/dispatch_json.ts b/cli/js/dispatch_json.ts index b0859e1ba3..12c2d88214 100644 --- a/cli/js/dispatch_json.ts +++ b/cli/js/dispatch_json.ts @@ -2,6 +2,7 @@ import * as util from "./util.ts"; import { TextEncoder, TextDecoder } from "./text_encoding.ts"; import { core } from "./core.ts"; +import { OPS_CACHE } from "./runtime.ts"; import { ErrorKind, constructError } from "./errors.ts"; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -54,10 +55,12 @@ export function asyncMsgFromRust(resUi8: Uint8Array): void { } export function sendSync( - opId: number, + opName: string, args: object = {}, zeroCopy?: Uint8Array ): Ok { + const opId = OPS_CACHE[opName]; + util.log("sendSync", opName, opId); const argsUi8 = encode(args); const resUi8 = core.dispatch(opId, argsUi8, zeroCopy); util.assert(resUi8 != null); @@ -68,10 +71,12 @@ export function sendSync( } export async function sendAsync( - opId: number, + opName: string, args: object = {}, zeroCopy?: Uint8Array ): Promise { + const opId = OPS_CACHE[opName]; + util.log("sendAsync", opName, opId); const promiseId = nextPromiseId(); args = Object.assign(args, { promiseId }); const promise = util.createResolvable(); diff --git a/cli/js/dispatch_json_test.ts b/cli/js/dispatch_json_test.ts index 90f93746ef..50efeb360a 100644 --- a/cli/js/dispatch_json_test.ts +++ b/cli/js/dispatch_json_test.ts @@ -1,7 +1,7 @@ import { + assert, test, testPerm, - assert, assertMatch, unreachable } from "./test_util.ts"; @@ -24,7 +24,9 @@ testPerm({ read: true }, async function sendAsyncStackTrace(): Promise { test(async function malformedJsonControlBuffer(): Promise { // @ts-ignore - const res = Deno.core.send(10, new Uint8Array([1, 2, 3, 4, 5])); + const opId = Deno.core.ops()["op_open"]; + // @ts-ignore + const res = Deno.core.send(opId, new Uint8Array([1, 2, 3, 4, 5])); const resText = new TextDecoder().decode(res); // eslint-disable-next-line @typescript-eslint/no-explicit-any const resJson = JSON.parse(resText) as any; diff --git a/cli/js/dispatch_minimal_test.ts b/cli/js/dispatch_minimal_test.ts index 75381204f9..2ae3fceeb0 100644 --- a/cli/js/dispatch_minimal_test.ts +++ b/cli/js/dispatch_minimal_test.ts @@ -1,8 +1,8 @@ import { - test, assert, assertEquals, assertMatch, + test, unreachable } from "./test_util.ts"; @@ -16,8 +16,9 @@ const readErrorStackPattern = new RegExp( test(async function sendAsyncStackTrace(): Promise { const buf = new Uint8Array(10); + const rid = 10; try { - await Deno.read(10, buf); + await Deno.read(rid, buf); unreachable(); } catch (error) { assertMatch(error.stack, readErrorStackPattern); @@ -26,7 +27,7 @@ test(async function sendAsyncStackTrace(): Promise { test(async function malformedMinimalControlBuffer(): Promise { // @ts-ignore - const readOpId = Deno.core.ops()["read"]; + const readOpId = Deno.core.ops()["op_read"]; // @ts-ignore const res = Deno.core.send(readOpId, new Uint8Array([1, 2, 3, 4, 5])); const header = res.slice(0, 12); diff --git a/cli/js/error_stack.ts b/cli/js/error_stack.ts index 7f19773bd2..ff15cee60f 100644 --- a/cli/js/error_stack.ts +++ b/cli/js/error_stack.ts @@ -1,7 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. // Some of the code here is adapted directly from V8 and licensed under a BSD // style license available here: https://github.com/v8/v8/blob/24886f2d1c565287d33d71e4109a53bf0b54b75c/LICENSE.v8 -import * as dispatch from "./dispatch.ts"; import { sendSync } from "./dispatch_json.ts"; import { assert } from "./util.ts"; import { exposeForTest } from "./internals.ts"; @@ -44,7 +43,7 @@ export function applySourceMap(location: Location): Location { const { filename, line, column } = location; // On this side, line/column are 1 based, but in the source maps, they are // 0 based, so we have to convert back and forth - const res = sendSync(dispatch.OP_APPLY_SOURCE_MAP, { + const res = sendSync("op_apply_source_map", { filename, line: line - 1, column: column - 1 diff --git a/cli/js/fetch.ts b/cli/js/fetch.ts index 43a23cb59c..2f493c02ea 100644 --- a/cli/js/fetch.ts +++ b/cli/js/fetch.ts @@ -15,7 +15,6 @@ import { Buffer } from "./buffer.ts"; import { FormData } from "./form_data.ts"; import { URL } from "./url.ts"; import { URLSearchParams } from "./url_search_params.ts"; -import * as dispatch from "./dispatch.ts"; import { sendAsync } from "./dispatch_json.ts"; function getHeaderValueParams(value: string): Map { @@ -469,7 +468,7 @@ async function sendFetchReq( headers: headerArray }; - return (await sendAsync(dispatch.OP_FETCH, args, zeroCopy)) as FetchResponse; + return (await sendAsync("op_fetch", args, zeroCopy)) as FetchResponse; } /** Fetch a resource from the network. */ diff --git a/cli/js/files.ts b/cli/js/files.ts index c966b9fa04..903564cd15 100644 --- a/cli/js/files.ts +++ b/cli/js/files.ts @@ -11,11 +11,15 @@ import { SyncSeeker } from "./io.ts"; import { sendAsyncMinimal, sendSyncMinimal } from "./dispatch_minimal.ts"; -import * as dispatch from "./dispatch.ts"; import { sendSync as sendSyncJson, sendAsync as sendAsyncJson } from "./dispatch_json.ts"; +import { OPS_CACHE } from "./runtime.ts"; + +// This is done because read/write are extremely performance sensitive. +let OP_READ = -1; +let OP_WRITE = -1; /** Open a file and return an instance of the `File` object * synchronously. @@ -44,7 +48,7 @@ export function openSync( options = modeOrOptions; } - const rid = sendSyncJson(dispatch.OP_OPEN, { filename, options, mode }); + const rid = sendSyncJson("op_open", { filename, options, mode }); return new File(rid); } @@ -78,7 +82,7 @@ export async function open( options = modeOrOptions; } - const rid = await sendAsyncJson(dispatch.OP_OPEN, { + const rid = await sendAsyncJson("op_open", { filename, options, mode @@ -118,7 +122,10 @@ export function readSync(rid: number, p: Uint8Array): number | EOF { if (p.length == 0) { return 0; } - const nread = sendSyncMinimal(dispatch.OP_READ, rid, p); + if (OP_READ < 0) { + OP_READ = OPS_CACHE["op_read"]; + } + const nread = sendSyncMinimal(OP_READ, rid, p); if (nread < 0) { throw new Error("read error"); } else if (nread == 0) { @@ -141,7 +148,10 @@ export async function read(rid: number, p: Uint8Array): Promise { if (p.length == 0) { return 0; } - const nread = await sendAsyncMinimal(dispatch.OP_READ, rid, p); + if (OP_READ < 0) { + OP_READ = OPS_CACHE["op_read"]; + } + const nread = await sendAsyncMinimal(OP_READ, rid, p); if (nread < 0) { throw new Error("read error"); } else if (nread == 0) { @@ -161,7 +171,10 @@ export async function read(rid: number, p: Uint8Array): Promise { * Deno.writeSync(file.rid, data); */ export function writeSync(rid: number, p: Uint8Array): number { - const result = sendSyncMinimal(dispatch.OP_WRITE, rid, p); + if (OP_WRITE < 0) { + OP_WRITE = OPS_CACHE["op_write"]; + } + const result = sendSyncMinimal(OP_WRITE, rid, p); if (result < 0) { throw new Error("write error"); } else { @@ -180,7 +193,10 @@ export function writeSync(rid: number, p: Uint8Array): number { * */ export async function write(rid: number, p: Uint8Array): Promise { - const result = await sendAsyncMinimal(dispatch.OP_WRITE, rid, p); + if (OP_WRITE < 0) { + OP_WRITE = OPS_CACHE["op_write"]; + } + const result = await sendAsyncMinimal(OP_WRITE, rid, p); if (result < 0) { throw new Error("write error"); } else { @@ -194,7 +210,7 @@ export async function write(rid: number, p: Uint8Array): Promise { * Deno.seekSync(file.rid, 0, 0); */ export function seekSync(rid: number, offset: number, whence: SeekMode): void { - sendSyncJson(dispatch.OP_SEEK, { rid, offset, whence }); + sendSyncJson("op_seek", { rid, offset, whence }); } /** Seek a file ID to the given offset under mode given by `whence`. @@ -207,12 +223,12 @@ export async function seek( offset: number, whence: SeekMode ): Promise { - await sendAsyncJson(dispatch.OP_SEEK, { rid, offset, whence }); + await sendAsyncJson("op_seek", { rid, offset, whence }); } /** Close the file ID. */ export function close(rid: number): void { - sendSyncJson(dispatch.OP_CLOSE, { rid }); + sendSyncJson("op_close", { rid }); } /** The Deno abstraction for reading and writing files. */ diff --git a/cli/js/format_error.ts b/cli/js/format_error.ts index 63250473b1..21c4bcfa86 100644 --- a/cli/js/format_error.ts +++ b/cli/js/format_error.ts @@ -1,11 +1,10 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { DiagnosticItem } from "./diagnostics.ts"; -import * as dispatch from "./dispatch.ts"; import { sendSync } from "./dispatch_json.ts"; // TODO(bartlomieju): move to `repl.ts`? export function formatError(errString: string): string { - const res = sendSync(dispatch.OP_FORMAT_ERROR, { error: errString }); + const res = sendSync("op_format_error", { error: errString }); return res.error; } @@ -14,5 +13,5 @@ export function formatError(errString: string): string { * @param items An array of diagnostic items to format */ export function formatDiagnostics(items: DiagnosticItem[]): string { - return sendSync(dispatch.OP_FORMAT_DIAGNOSTIC, { items }); + return sendSync("op_format_diagnostic", { items }); } diff --git a/cli/js/fs_events.ts b/cli/js/fs_events.ts index a4deff48a0..b549b3d4d6 100644 --- a/cli/js/fs_events.ts +++ b/cli/js/fs_events.ts @@ -1,6 +1,5 @@ // Copyright 2019 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; import { close } from "./files.ts"; export interface FsEvent { @@ -13,11 +12,11 @@ class FsEvents implements AsyncIterableIterator { constructor(paths: string[], options: { recursive: boolean }) { const { recursive } = options; - this.rid = sendSync(dispatch.OP_FS_EVENTS_OPEN, { recursive, paths }); + this.rid = sendSync("op_fs_events_open", { recursive, paths }); } async next(): Promise> { - return await sendAsync(dispatch.OP_FS_EVENTS_POLL, { + return await sendAsync("op_fs_events_poll", { rid: this.rid }); } diff --git a/cli/js/get_random_values.ts b/cli/js/get_random_values.ts index e8b61b268c..7991737025 100644 --- a/cli/js/get_random_values.ts +++ b/cli/js/get_random_values.ts @@ -1,5 +1,4 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import * as dispatch from "./dispatch.ts"; import { sendSync } from "./dispatch_json.ts"; import { assert } from "./util.ts"; @@ -26,6 +25,6 @@ export function getRandomValues< typedArray.byteOffset, typedArray.byteLength ); - sendSync(dispatch.OP_GET_RANDOM_VALUES, {}, ui8); + sendSync("op_get_random_values", {}, ui8); return typedArray; } diff --git a/cli/js/link.ts b/cli/js/link.ts index dc04d717a3..4d66d1cf95 100644 --- a/cli/js/link.ts +++ b/cli/js/link.ts @@ -1,13 +1,12 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; /** Synchronously creates `newname` as a hard link to `oldname`. * * Deno.linkSync("old/name", "new/name"); */ export function linkSync(oldname: string, newname: string): void { - sendSync(dispatch.OP_LINK, { oldname, newname }); + sendSync("op_link", { oldname, newname }); } /** Creates `newname` as a hard link to `oldname`. @@ -15,5 +14,5 @@ export function linkSync(oldname: string, newname: string): void { * await Deno.link("old/name", "new/name"); */ export async function link(oldname: string, newname: string): Promise { - await sendAsync(dispatch.OP_LINK, { oldname, newname }); + await sendAsync("op_link", { oldname, newname }); } diff --git a/cli/js/make_temp.ts b/cli/js/make_temp.ts index 8b15ab1848..7b00383882 100644 --- a/cli/js/make_temp.ts +++ b/cli/js/make_temp.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; export interface MakeTempOptions { dir?: string; @@ -14,7 +13,7 @@ export interface MakeTempOptions { * const tempDirName1 = Deno.makeTempDirSync({ prefix: 'my_temp' }); */ export function makeTempDirSync(options: MakeTempOptions = {}): string { - return sendSync(dispatch.OP_MAKE_TEMP_DIR, options); + return sendSync("op_make_temp_dir", options); } /** makeTempDir creates a new temporary directory in the directory `dir`, its @@ -31,7 +30,7 @@ export function makeTempDirSync(options: MakeTempOptions = {}): string { export async function makeTempDir( options: MakeTempOptions = {} ): Promise { - return await sendAsync(dispatch.OP_MAKE_TEMP_DIR, options); + return await sendAsync("op_make_temp_dir", options); } /** makeTempFileSync is the synchronous version of `makeTempFile`. @@ -40,7 +39,7 @@ export async function makeTempDir( * const tempFileName1 = Deno.makeTempFileSync({ prefix: 'my_temp' }); */ export function makeTempFileSync(options: MakeTempOptions = {}): string { - return sendSync(dispatch.OP_MAKE_TEMP_FILE, options); + return sendSync("op_make_temp_file", options); } /** makeTempFile creates a new temporary file in the directory `dir`, its @@ -57,5 +56,5 @@ export function makeTempFileSync(options: MakeTempOptions = {}): string { export async function makeTempFile( options: MakeTempOptions = {} ): Promise { - return await sendAsync(dispatch.OP_MAKE_TEMP_FILE, options); + return await sendAsync("op_make_temp_file", options); } diff --git a/cli/js/metrics.ts b/cli/js/metrics.ts index 90c99ff890..b735dc6b34 100644 --- a/cli/js/metrics.ts +++ b/cli/js/metrics.ts @@ -1,5 +1,4 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import * as dispatch from "./dispatch.ts"; import { sendSync } from "./dispatch_json.ts"; export interface Metrics { @@ -24,5 +23,5 @@ export interface Metrics { * └──────────────────┴────────┘ */ export function metrics(): Metrics { - return sendSync(dispatch.OP_METRICS); + return sendSync("op_metrics"); } diff --git a/cli/js/mkdir.ts b/cli/js/mkdir.ts index 836b785cfe..532d2b73c2 100644 --- a/cli/js/mkdir.ts +++ b/cli/js/mkdir.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; // TODO(ry) The complexity in argument parsing is to support deprecated forms of // mkdir and mkdirSync. @@ -45,7 +44,7 @@ export function mkdirSync( optionsOrRecursive?: MkdirOption | boolean, mode?: number ): void { - sendSync(dispatch.OP_MKDIR, mkdirArgs(path, optionsOrRecursive, mode)); + sendSync("op_mkdir", mkdirArgs(path, optionsOrRecursive, mode)); } /** Creates a new directory with the specified path. @@ -62,5 +61,5 @@ export async function mkdir( optionsOrRecursive?: MkdirOption | boolean, mode?: number ): Promise { - await sendAsync(dispatch.OP_MKDIR, mkdirArgs(path, optionsOrRecursive, mode)); + await sendAsync("op_mkdir", mkdirArgs(path, optionsOrRecursive, mode)); } diff --git a/cli/js/net.ts b/cli/js/net.ts index 9d82a3a3fe..e03175b575 100644 --- a/cli/js/net.ts +++ b/cli/js/net.ts @@ -1,7 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { EOF, Reader, Writer, Closer } from "./io.ts"; import { read, write, close } from "./files.ts"; -import * as dispatch from "./dispatch.ts"; import { sendSync, sendAsync } from "./dispatch_json.ts"; export type Transport = "tcp" | "udp"; @@ -72,7 +71,7 @@ export enum ShutdownMode { * Deno.shutdown(conn.rid, Deno.ShutdownMode.Write); */ export function shutdown(rid: number, how: ShutdownMode): void { - sendSync(dispatch.OP_SHUTDOWN, { rid, how }); + sendSync("op_shutdown", { rid, how }); } export class ConnImpl implements Conn { @@ -117,7 +116,7 @@ export class ListenerImpl implements Listener { ) {} async accept(): Promise { - const res = await sendAsync(dispatch.OP_ACCEPT, { rid: this.rid }); + const res = await sendAsync("op_accept", { rid: this.rid }); return new ConnImpl(res.rid, res.remoteAddr, res.localAddr); } @@ -152,7 +151,7 @@ export async function recvfrom( rid: number, p: Uint8Array ): Promise<[number, Addr]> { - const { size, remoteAddr } = await sendAsync(dispatch.OP_RECEIVE, { rid }, p); + const { size, remoteAddr } = await sendAsync("op_receive", { rid }, p); return [size, remoteAddr]; } @@ -175,7 +174,7 @@ export class UDPConnImpl implements UDPConn { const remote = { hostname: "127.0.0.1", transport: "udp", ...addr }; if (remote.transport !== "udp") throw Error("Remote transport must be UDP"); const args = { ...remote, rid: this.rid }; - await sendAsync(dispatch.OP_SEND, args, p); + await sendAsync("op_send", args, p); } close(): void { @@ -253,7 +252,7 @@ export function listen( export function listen(options: ListenOptions & { transport: "udp" }): UDPConn; export function listen(options: ListenOptions): Listener | UDPConn { const args = { ...listenDefaults, ...options }; - const res = sendSync(dispatch.OP_LISTEN, args); + const res = sendSync("op_listen", args); if (args.transport === "tcp") { return new ListenerImpl(res.rid, res.localAddr); @@ -289,6 +288,6 @@ const connectDefaults = { hostname: "127.0.0.1", transport: "tcp" }; */ export async function connect(options: ConnectOptions): Promise { options = Object.assign(connectDefaults, options); - const res = await sendAsync(dispatch.OP_CONNECT, options); + const res = await sendAsync("op_connect", options); return new ConnImpl(res.rid, res.remoteAddr!, res.localAddr!); } diff --git a/cli/js/os.ts b/cli/js/os.ts index 7458ee469c..2a68ff8d33 100644 --- a/cli/js/os.ts +++ b/cli/js/os.ts @@ -1,5 +1,4 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import * as dispatch from "./dispatch.ts"; import { sendSync } from "./dispatch_json.ts"; import { errors } from "./errors.ts"; import * as util from "./util.ts"; @@ -9,7 +8,7 @@ import * as util from "./util.ts"; * console.log(Deno.isTTY().stdout); */ export function isTTY(): { stdin: boolean; stdout: boolean; stderr: boolean } { - return sendSync(dispatch.OP_IS_TTY); + return sendSync("op_is_tty"); } /** Get the loadavg. * Requires the `--allow-env` flag. @@ -17,7 +16,7 @@ export function isTTY(): { stdin: boolean; stdout: boolean; stderr: boolean } { * console.log(Deno.loadavg()); */ export function loadavg(): number[] { - return sendSync(dispatch.OP_LOADAVG); + return sendSync("op_loadavg"); } /** Get the hostname. @@ -26,7 +25,7 @@ export function loadavg(): number[] { * console.log(Deno.hostname()); */ export function hostname(): string { - return sendSync(dispatch.OP_HOSTNAME); + return sendSync("op_hostname"); } /** Get OS release. @@ -35,21 +34,21 @@ export function hostname(): string { * console.log(Deno.osRelease()); */ export function osRelease(): string { - return sendSync(dispatch.OP_OS_RELEASE); + return sendSync("op_os_release"); } /** Exit the Deno process with optional exit code. */ export function exit(code = 0): never { - sendSync(dispatch.OP_EXIT, { code }); + sendSync("op_exit", { code }); return util.unreachable(); } function setEnv(key: string, value: string): void { - sendSync(dispatch.OP_SET_ENV, { key, value }); + sendSync("op_set_env", { key, value }); } function getEnv(key: string): string | undefined { - return sendSync(dispatch.OP_GET_ENV, { key })[0]; + return sendSync("op_get_env", { key })[0]; } /** Returns a snapshot of the environment variables at invocation. Mutating a @@ -72,7 +71,7 @@ export function env( if (key) { return getEnv(key); } - const env = sendSync(dispatch.OP_ENV); + const env = sendSync("op_env"); return new Proxy(env, { set(obj, prop: string, value: string): boolean { setEnv(prop, value); @@ -208,7 +207,7 @@ type DirKind = */ export function dir(kind: DirKind): string | null { try { - return sendSync(dispatch.OP_GET_DIR, { kind }); + return sendSync("op_get_dir", { kind }); } catch (error) { if (error instanceof errors.PermissionDenied) { throw error; @@ -222,5 +221,5 @@ export function dir(kind: DirKind): string | null { * Requires the `--allow-env` flag. */ export function execPath(): string { - return sendSync(dispatch.OP_EXEC_PATH); + return sendSync("op_exec_path"); } diff --git a/cli/js/performance.ts b/cli/js/performance.ts index 37cca35ab2..981be64d4b 100644 --- a/cli/js/performance.ts +++ b/cli/js/performance.ts @@ -1,5 +1,4 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import * as dispatch from "./dispatch.ts"; import { sendSync } from "./dispatch_json.ts"; interface NowResponse { @@ -16,7 +15,7 @@ export class Performance { * console.log(`${t} ms since start!`); */ now(): number { - const res = sendSync(dispatch.OP_NOW) as NowResponse; + const res = sendSync("op_now") as NowResponse; return res.seconds * 1e3 + res.subsecNanos / 1e6; } } diff --git a/cli/js/permissions.ts b/cli/js/permissions.ts index 229f8de8bd..d414dd1ef9 100644 --- a/cli/js/permissions.ts +++ b/cli/js/permissions.ts @@ -1,5 +1,4 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import * as dispatch from "./dispatch.ts"; import { sendSync } from "./dispatch_json.ts"; /** Permissions as granted by the caller @@ -61,7 +60,7 @@ export class Permissions { * } */ async query(desc: PermissionDescriptor): Promise { - const { state } = sendSync(dispatch.OP_QUERY_PERMISSION, desc); + const { state } = sendSync("op_query_permission", desc); return new PermissionStatus(state); } @@ -70,7 +69,7 @@ export class Permissions { * assert(status.state !== "granted") */ async revoke(desc: PermissionDescriptor): Promise { - const { state } = sendSync(dispatch.OP_REVOKE_PERMISSION, desc); + const { state } = sendSync("op_revoke_permission", desc); return new PermissionStatus(state); } @@ -83,7 +82,7 @@ export class Permissions { * } */ async request(desc: PermissionDescriptor): Promise { - const { state } = sendSync(dispatch.OP_REQUEST_PERMISSION, desc); + const { state } = sendSync("op_request_permission", desc); return new PermissionStatus(state); } } diff --git a/cli/js/plugins.ts b/cli/js/plugins.ts index 4d2072c79f..44a3083bbc 100644 --- a/cli/js/plugins.ts +++ b/cli/js/plugins.ts @@ -1,5 +1,4 @@ import { sendSync } from "./dispatch_json.ts"; -import { OP_OPEN_PLUGIN } from "./dispatch.ts"; import { core } from "./core.ts"; export interface AsyncHandler { @@ -59,7 +58,7 @@ interface OpenPluginResponse { } export function openPlugin(filename: string): Plugin { - const response: OpenPluginResponse = sendSync(OP_OPEN_PLUGIN, { + const response: OpenPluginResponse = sendSync("op_open_plugin", { filename }); return new PluginImpl(response.rid, response.ops); diff --git a/cli/js/process.ts b/cli/js/process.ts index 5267763c1e..4c8685cae9 100644 --- a/cli/js/process.ts +++ b/cli/js/process.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; import { File, close } from "./files.ts"; import { ReadCloser, WriteCloser } from "./io.ts"; import { readAll } from "./buffer.ts"; @@ -38,7 +37,7 @@ interface RunStatusResponse { } async function runStatus(rid: number): Promise { - const res = (await sendAsync(dispatch.OP_RUN_STATUS, { + const res = (await sendAsync("op_run_status", { rid })) as RunStatusResponse; @@ -57,7 +56,7 @@ async function runStatus(rid: number): Promise { * Requires the `--allow-run` flag. */ export function kill(pid: number, signo: number): void { - sendSync(dispatch.OP_KILL, { pid, signo }); + sendSync("op_kill", { pid, signo }); } export class Process { @@ -220,7 +219,7 @@ export function run(opt: RunOptions): Process { stderrRid }; - const res = sendSync(dispatch.OP_RUN, req) as RunResponse; + const res = sendSync("op_run", req) as RunResponse; return new Process(res); } diff --git a/cli/js/read_dir.ts b/cli/js/read_dir.ts index ba64190329..948bad0448 100644 --- a/cli/js/read_dir.ts +++ b/cli/js/read_dir.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; import { FileInfo, FileInfoImpl } from "./file_info.ts"; import { StatResponse } from "./stat.ts"; @@ -22,7 +21,7 @@ function res(response: ReadDirResponse): FileInfo[] { * const files = Deno.readDirSync("/"); */ export function readDirSync(path: string): FileInfo[] { - return res(sendSync(dispatch.OP_READ_DIR, { path })); + return res(sendSync("op_read_dir", { path })); } /** Reads the directory given by path and returns a list of file info. @@ -30,5 +29,5 @@ export function readDirSync(path: string): FileInfo[] { * const files = await Deno.readDir("/"); */ export async function readDir(path: string): Promise { - return res(await sendAsync(dispatch.OP_READ_DIR, { path })); + return res(await sendAsync("op_read_dir", { path })); } diff --git a/cli/js/read_link.ts b/cli/js/read_link.ts index acd2d91893..5432bedf7a 100644 --- a/cli/js/read_link.ts +++ b/cli/js/read_link.ts @@ -1,13 +1,12 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; /** Returns the destination of the named symbolic link synchronously. * * const targetPath = Deno.readlinkSync("symlink/path"); */ export function readlinkSync(name: string): string { - return sendSync(dispatch.OP_READ_LINK, { name }); + return sendSync("op_read_link", { name }); } /** Returns the destination of the named symbolic link. @@ -15,5 +14,5 @@ export function readlinkSync(name: string): string { * const targetPath = await Deno.readlink("symlink/path"); */ export async function readlink(name: string): Promise { - return await sendAsync(dispatch.OP_READ_LINK, { name }); + return await sendAsync("op_read_link", { name }); } diff --git a/cli/js/realpath.ts b/cli/js/realpath.ts index 502ced3b85..c425049f4c 100644 --- a/cli/js/realpath.ts +++ b/cli/js/realpath.ts @@ -1,13 +1,12 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; /** Returns absolute normalized path with symbolic links resolved synchronously. * * const realPath = Deno.realpathSync("./some/path"); */ export function realpathSync(path: string): string { - return sendSync(dispatch.OP_REALPATH, { path }); + return sendSync("op_realpath", { path }); } /** Returns absolute normalized path with symbolic links resolved. @@ -15,5 +14,5 @@ export function realpathSync(path: string): string { * const realPath = await Deno.realpath("./some/path"); */ export async function realpath(path: string): Promise { - return await sendAsync(dispatch.OP_REALPATH, { path }); + return await sendAsync("op_realpath", { path }); } diff --git a/cli/js/remove.ts b/cli/js/remove.ts index f4b1bfe19a..53ceb825bf 100644 --- a/cli/js/remove.ts +++ b/cli/js/remove.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; export interface RemoveOption { recursive?: boolean; @@ -14,7 +13,7 @@ export interface RemoveOption { * Deno.removeSync("/path/to/dir/or/file", {recursive: false}); */ export function removeSync(path: string, options: RemoveOption = {}): void { - sendSync(dispatch.OP_REMOVE, { path, recursive: !!options.recursive }); + sendSync("op_remove", { path, recursive: !!options.recursive }); } /** Removes the named file, directory or symlink. Would throw error if @@ -28,5 +27,5 @@ export async function remove( path: string, options: RemoveOption = {} ): Promise { - await sendAsync(dispatch.OP_REMOVE, { path, recursive: !!options.recursive }); + await sendAsync("op_remove", { path, recursive: !!options.recursive }); } diff --git a/cli/js/rename.ts b/cli/js/rename.ts index 6c0b5d95da..a689061a22 100644 --- a/cli/js/rename.ts +++ b/cli/js/rename.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; /** Synchronously renames (moves) `oldpath` to `newpath`. If `newpath` already * exists and is not a directory, `renameSync()` replaces it. OS-specific @@ -10,7 +9,7 @@ import * as dispatch from "./dispatch.ts"; * Deno.renameSync("old/path", "new/path"); */ export function renameSync(oldpath: string, newpath: string): void { - sendSync(dispatch.OP_RENAME, { oldpath, newpath }); + sendSync("op_rename", { oldpath, newpath }); } /** Renames (moves) `oldpath` to `newpath`. If `newpath` already exists and is @@ -20,5 +19,5 @@ export function renameSync(oldpath: string, newpath: string): void { * await Deno.rename("old/path", "new/path"); */ export async function rename(oldpath: string, newpath: string): Promise { - await sendAsync(dispatch.OP_RENAME, { oldpath, newpath }); + await sendAsync("op_rename", { oldpath, newpath }); } diff --git a/cli/js/repl.ts b/cli/js/repl.ts index 813f0cb219..6e4f2545a2 100644 --- a/cli/js/repl.ts +++ b/cli/js/repl.ts @@ -4,7 +4,6 @@ import { exit } from "./os.ts"; import { core } from "./core.ts"; import { formatError } from "./format_error.ts"; import { stringifyArgs } from "./console.ts"; -import * as dispatch from "./dispatch.ts"; import { sendSync, sendAsync } from "./dispatch_json.ts"; /** @@ -44,12 +43,12 @@ const replCommands = { }; function startRepl(historyFile: string): number { - return sendSync(dispatch.OP_REPL_START, { historyFile }); + return sendSync("op_repl_start", { historyFile }); } // @internal export async function readline(rid: number, prompt: string): Promise { - return sendAsync(dispatch.OP_REPL_READLINE, { rid, prompt }); + return sendAsync("op_repl_readline", { rid, prompt }); } // Error messages that allow users to continue input diff --git a/cli/js/resources.ts b/cli/js/resources.ts index e24c1da671..4c2de1fc3f 100644 --- a/cli/js/resources.ts +++ b/cli/js/resources.ts @@ -1,5 +1,4 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import * as dispatch from "./dispatch.ts"; import { sendSync } from "./dispatch_json.ts"; export interface ResourceMap { @@ -10,7 +9,7 @@ export interface ResourceMap { * representation. */ export function resources(): ResourceMap { - const res = sendSync(dispatch.OP_RESOURCES) as Array<[number, string]>; + const res = sendSync("op_resources") as Array<[number, string]>; const resources: ResourceMap = {}; for (const resourceTuple of res) { resources[resourceTuple[0]] = resourceTuple[1]; diff --git a/cli/js/runtime.ts b/cli/js/runtime.ts index 53ce5fcee8..8149c065c6 100644 --- a/cli/js/runtime.ts +++ b/cli/js/runtime.ts @@ -28,16 +28,14 @@ interface Start { arch: Arch; } +export let OPS_CACHE: { [name: string]: number }; + // TODO(bartlomieju): temporary solution, must be fixed when moving // dispatches to separate crates export function initOps(): void { - const ops = core.ops(); - for (const [name, opId] of Object.entries(ops)) { - const opName = `OP_${name.toUpperCase()}`; - // Assign op ids to actual variables - // TODO(ry) This type casting is gross and should be fixed. - ((dispatch as unknown) as { [key: string]: number })[opName] = opId; - core.setAsyncHandler(opId, dispatch.getAsyncHandler(opName)); + OPS_CACHE = core.ops(); + for (const [name, opId] of Object.entries(OPS_CACHE)) { + core.setAsyncHandler(opId, dispatch.getAsyncHandler(name)); } } @@ -51,7 +49,7 @@ export function start(preserveDenoNamespace = true, source?: string): Start { // First we send an empty `Start` message to let the privileged side know we // are ready. The response should be a `StartRes` message containing the CLI // args and other info. - const s = sendSync(dispatch.OP_START); + const s = sendSync("op_start"); setVersions(s.denoVersion, s.v8Version, s.tsVersion); setBuildInfo(s.os, s.arch); diff --git a/cli/js/runtime_worker.ts b/cli/js/runtime_worker.ts index a9ed8b9249..cdc7d52dd1 100644 --- a/cli/js/runtime_worker.ts +++ b/cli/js/runtime_worker.ts @@ -16,7 +16,6 @@ import { windowOrWorkerGlobalScopeProperties, eventTargetProperties } from "./globals.ts"; -import * as dispatch from "./dispatch.ts"; import { sendSync } from "./dispatch_json.ts"; import { log } from "./util.ts"; import { TextEncoder } from "./text_encoding.ts"; @@ -32,7 +31,7 @@ export const onerror: (e: { data: any }) => void = (): void => {}; export function postMessage(data: any): void { const dataJson = JSON.stringify(data); const dataIntArray = encoder.encode(dataJson); - sendSync(dispatch.OP_WORKER_POST_MESSAGE, {}, dataIntArray); + sendSync("op_worker_post_message", {}, dataIntArray); } let isClosing = false; @@ -44,7 +43,7 @@ export function close(): void { } isClosing = true; - sendSync(dispatch.OP_WORKER_CLOSE); + sendSync("op_worker_close"); } export async function workerMessageRecvCallback(data: string): Promise { diff --git a/cli/js/signals.ts b/cli/js/signals.ts index 9f47313d41..b798688887 100644 --- a/cli/js/signals.ts +++ b/cli/js/signals.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { Signal } from "./process.ts"; -import * as dispatch from "./dispatch.ts"; import { sendSync, sendAsync } from "./dispatch_json.ts"; import { build } from "./build.ts"; @@ -106,13 +105,13 @@ export class SignalStream /** The flag, which is true when the stream is disposed. */ private disposed = false; constructor(signo: number) { - this.rid = sendSync(dispatch.OP_SIGNAL_BIND, { signo }).rid; + this.rid = sendSync("op_signal_bind", { signo }).rid; this.loop(); } private async pollSignal(): Promise { return ( - await sendAsync(dispatch.OP_SIGNAL_POLL, { + await sendAsync("op_signal_poll", { rid: this.rid }) ).done; @@ -144,6 +143,6 @@ export class SignalStream throw new Error("The stream has already been disposed."); } this.disposed = true; - sendSync(dispatch.OP_SIGNAL_UNBIND, { rid: this.rid }); + sendSync("op_signal_unbind", { rid: this.rid }); } } diff --git a/cli/js/stat.ts b/cli/js/stat.ts index b271702636..1fd28e8930 100644 --- a/cli/js/stat.ts +++ b/cli/js/stat.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; import { FileInfo, FileInfoImpl } from "./file_info.ts"; export interface StatResponse { @@ -30,7 +29,7 @@ export interface StatResponse { * assert(fileInfo.isFile()); */ export async function lstat(filename: string): Promise { - const res = (await sendAsync(dispatch.OP_STAT, { + const res = (await sendAsync("op_stat", { filename, lstat: true })) as StatResponse; @@ -45,7 +44,7 @@ export async function lstat(filename: string): Promise { * assert(fileInfo.isFile()); */ export function lstatSync(filename: string): FileInfo { - const res = sendSync(dispatch.OP_STAT, { + const res = sendSync("op_stat", { filename, lstat: true }) as StatResponse; @@ -59,7 +58,7 @@ export function lstatSync(filename: string): FileInfo { * assert(fileInfo.isFile()); */ export async function stat(filename: string): Promise { - const res = (await sendAsync(dispatch.OP_STAT, { + const res = (await sendAsync("op_stat", { filename, lstat: false })) as StatResponse; @@ -73,7 +72,7 @@ export async function stat(filename: string): Promise { * assert(fileInfo.isFile()); */ export function statSync(filename: string): FileInfo { - const res = sendSync(dispatch.OP_STAT, { + const res = sendSync("op_stat", { filename, lstat: false }) as StatResponse; diff --git a/cli/js/symlink.ts b/cli/js/symlink.ts index 79a79c72c9..de4d8a7293 100644 --- a/cli/js/symlink.ts +++ b/cli/js/symlink.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; import * as util from "./util.ts"; import { build } from "./build.ts"; @@ -18,7 +17,7 @@ export function symlinkSync( if (build.os === "win" && type) { return util.notImplemented(); } - sendSync(dispatch.OP_SYMLINK, { oldname, newname }); + sendSync("op_symlink", { oldname, newname }); } /** Creates `newname` as a symbolic link to `oldname`. The type argument can be @@ -35,5 +34,5 @@ export async function symlink( if (build.os === "win" && type) { return util.notImplemented(); } - await sendAsync(dispatch.OP_SYMLINK, { oldname, newname }); + await sendAsync("op_symlink", { oldname, newname }); } diff --git a/cli/js/timers.ts b/cli/js/timers.ts index da8fc7a228..a92896efd6 100644 --- a/cli/js/timers.ts +++ b/cli/js/timers.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { assert } from "./util.ts"; -import * as dispatch from "./dispatch.ts"; import { sendSync, sendAsync } from "./dispatch_json.ts"; import { RBTree } from "./rbtree.ts"; @@ -27,7 +26,7 @@ const dueTree = new RBTree((a, b) => a.due - b.due); function clearGlobalTimeout(): void { globalTimeoutDue = null; - sendSync(dispatch.OP_GLOBAL_TIMER_STOP); + sendSync("op_global_timer_stop"); } let pendingEvents = 0; @@ -44,7 +43,7 @@ async function setGlobalTimeout(due: number, now: number): Promise { // Send message to the backend. globalTimeoutDue = due; pendingEvents++; - await sendAsync(dispatch.OP_GLOBAL_TIMER, { timeout }); + await sendAsync("op_global_timer", { timeout }); pendingEvents--; // eslint-disable-next-line @typescript-eslint/no-use-before-define fireTimers(); diff --git a/cli/js/tls.ts b/cli/js/tls.ts index b8815831b4..2780956a16 100644 --- a/cli/js/tls.ts +++ b/cli/js/tls.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendAsync, sendSync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; import { Listener, Transport, Conn, ConnImpl, ListenerImpl } from "./net.ts"; // TODO(ry) There are many configuration options to add... @@ -18,13 +17,13 @@ const connectTLSDefaults = { hostname: "127.0.0.1", transport: "tcp" }; */ export async function connectTLS(options: ConnectTLSOptions): Promise { options = Object.assign(connectTLSDefaults, options); - const res = await sendAsync(dispatch.OP_CONNECT_TLS, options); + const res = await sendAsync("op_connect_tls", options); return new ConnImpl(res.rid, res.remoteAddr!, res.localAddr!); } class TLSListenerImpl extends ListenerImpl { async accept(): Promise { - const res = await sendAsync(dispatch.OP_ACCEPT_TLS, { rid: this.rid }); + const res = await sendAsync("op_accept_tls", { rid: this.rid }); return new ConnImpl(res.rid, res.remoteAddr, res.localAddr); } } @@ -53,7 +52,7 @@ export interface ListenTLSOptions { export function listenTLS(options: ListenTLSOptions): Listener { const hostname = options.hostname || "0.0.0.0"; const transport = options.transport || "tcp"; - const res = sendSync(dispatch.OP_LISTEN_TLS, { + const res = sendSync("op_listen_tls", { hostname, port: options.port, transport, diff --git a/cli/js/truncate.ts b/cli/js/truncate.ts index bd572e75ab..17c08674ca 100644 --- a/cli/js/truncate.ts +++ b/cli/js/truncate.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "./dispatch_json.ts"; -import * as dispatch from "./dispatch.ts"; function coerceLen(len?: number): number { if (!len) { @@ -20,7 +19,7 @@ function coerceLen(len?: number): number { * Deno.truncateSync("hello.txt", 10); */ export function truncateSync(name: string, len?: number): void { - sendSync(dispatch.OP_TRUNCATE, { name, len: coerceLen(len) }); + sendSync("op_truncate", { name, len: coerceLen(len) }); } /** @@ -30,5 +29,5 @@ export function truncateSync(name: string, len?: number): void { * await Deno.truncate("hello.txt", 10); */ export async function truncate(name: string, len?: number): Promise { - await sendAsync(dispatch.OP_TRUNCATE, { name, len: coerceLen(len) }); + await sendAsync("op_truncate", { name, len: coerceLen(len) }); } diff --git a/cli/js/url_test.ts b/cli/js/url_test.ts index 64130b6b9c..003fcd3477 100644 --- a/cli/js/url_test.ts +++ b/cli/js/url_test.ts @@ -180,6 +180,7 @@ test(function sortingNonExistentParamRemovesQuestionMarkFromURL(): void { assertEquals(url.search, ""); }); +/* test(function customInspectFunction(): void { const url = new URL("http://example.com/?"); assertEquals( @@ -187,6 +188,7 @@ test(function customInspectFunction(): void { 'URL { href: "http://example.com/?", origin: "http://example.com", protocol: "http:", username: "", password: "", host: "example.com", hostname: "example.com", port: "", pathname: "/", hash: "", search: "?" }' ); }); +*/ test(function protocolNotHttpOrFile() { const url = new URL("about:blank"); @@ -200,3 +202,7 @@ test(function createBadUrl(): void { new URL("0.0.0.0:8080"); }); }); + +if (import.meta.main) { + Deno.runTests(); +} diff --git a/cli/js/utime.ts b/cli/js/utime.ts index c96461b2c3..d80b8b396d 100644 --- a/cli/js/utime.ts +++ b/cli/js/utime.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "./dispatch_json.ts"; -import { OP_UTIME } from "./dispatch.ts"; function toSecondsFromEpoch(v: number | Date): number { return v instanceof Date ? v.valueOf() / 1000 : v; @@ -17,7 +16,7 @@ export function utimeSync( atime: number | Date, mtime: number | Date ): void { - sendSync(OP_UTIME, { + sendSync("op_utime", { filename, // TODO(ry) split atime, mtime into [seconds, nanoseconds] tuple atime: toSecondsFromEpoch(atime), @@ -36,7 +35,7 @@ export async function utime( atime: number | Date, mtime: number | Date ): Promise { - await sendAsync(OP_UTIME, { + await sendAsync("op_utime", { filename, // TODO(ry) split atime, mtime into [seconds, nanoseconds] tuple atime: toSecondsFromEpoch(atime), diff --git a/cli/js/workers.ts b/cli/js/workers.ts index 7b0c503365..3258e4137f 100644 --- a/cli/js/workers.ts +++ b/cli/js/workers.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. /* eslint-disable @typescript-eslint/no-explicit-any */ -import * as dispatch from "./dispatch.ts"; import { sendAsync, sendSync } from "./dispatch_json.ts"; import { log } from "./util.ts"; import { TextDecoder, TextEncoder } from "./text_encoding.ts"; @@ -30,7 +29,7 @@ function createWorker( sourceCode: Uint8Array, name?: string ): { id: number } { - return sendSync(dispatch.OP_CREATE_WORKER, { + return sendSync("op_create_worker", { specifier, hasSourceCode, sourceCode: new TextDecoder().decode(sourceCode), @@ -39,12 +38,12 @@ function createWorker( } function hostTerminateWorker(id: number): void { - sendSync(dispatch.OP_HOST_TERMINATE_WORKER, { id }); + sendSync("op_host_terminate_worker", { id }); } function hostPostMessage(id: number, data: any): void { const dataIntArray = encodeMessage(data); - sendSync(dispatch.OP_HOST_POST_MESSAGE, { id }, dataIntArray); + sendSync("op_host_post_message", { id }, dataIntArray); } interface WorkerEvent { @@ -54,7 +53,7 @@ interface WorkerEvent { } async function hostGetMessage(id: number): Promise { - return await sendAsync(dispatch.OP_HOST_GET_MESSAGE, { id }); + return await sendAsync("op_host_get_message", { id }); } export interface Worker { diff --git a/cli/ops/compiler.rs b/cli/ops/compiler.rs index a559bb539d..015c77c4ef 100644 --- a/cli/ops/compiler.rs +++ b/cli/ops/compiler.rs @@ -5,25 +5,22 @@ use super::dispatch_json::Value; use crate::futures::future::try_join_all; use crate::msg; use crate::op_error::OpError; -use crate::ops::json_op; use crate::state::State; use deno_core::Loader; use deno_core::*; use futures::future::FutureExt; pub fn init(i: &mut Isolate, s: &State) { - i.register_op("cache", s.core_op(json_op(s.stateful_op(op_cache)))); + i.register_op("op_cache", s.stateful_json_op(op_cache)); + i.register_op("op_resolve_modules", s.stateful_json_op(op_resolve_modules)); i.register_op( - "resolve_modules", - s.core_op(json_op(s.stateful_op(op_resolve_modules))), + "op_fetch_source_files", + s.stateful_json_op(op_fetch_source_files), ); + let custom_assets = std::collections::HashMap::new(); // TODO(ry) use None. i.register_op( - "fetch_source_files", - s.core_op(json_op(s.stateful_op(op_fetch_source_files))), - ); - i.register_op( - "fetch_asset", - s.core_op(json_op(s.stateful_op(op_fetch_asset))), + "op_fetch_asset", + deno_typescript::op_fetch_asset(custom_assets), ); } @@ -169,26 +166,3 @@ fn op_fetch_source_files( Ok(JsonOp::Async(future)) } - -#[derive(Deserialize, Debug)] -struct FetchRemoteAssetArgs { - name: String, -} - -fn op_fetch_asset( - _state: &State, - args: Value, - _data: Option, -) -> Result { - let args: FetchRemoteAssetArgs = serde_json::from_value(args)?; - debug!("args.name: {}", args.name); - - let source_code = - if let Some(source_code) = deno_typescript::get_asset(&args.name) { - source_code.to_string() - } else { - panic!("Asset not found: \"{}\"", args.name) - }; - - Ok(JsonOp::Sync(json!({ "sourceCode": source_code }))) -} diff --git a/cli/ops/errors.rs b/cli/ops/errors.rs index b5cc75f7ad..c588759cf3 100644 --- a/cli/ops/errors.rs +++ b/cli/ops/errors.rs @@ -3,7 +3,6 @@ use super::dispatch_json::{Deserialize, JsonOp, Value}; use crate::diagnostics::Diagnostic; use crate::fmt_errors::JSError; use crate::op_error::OpError; -use crate::ops::json_op; use crate::source_maps::get_orig_position; use crate::source_maps::CachedMaps; use crate::state::State; @@ -12,16 +11,13 @@ use std::collections::HashMap; pub fn init(i: &mut Isolate, s: &State) { i.register_op( - "apply_source_map", - s.core_op(json_op(s.stateful_op(op_apply_source_map))), + "op_apply_source_map", + s.stateful_json_op(op_apply_source_map), ); + i.register_op("op_format_error", s.stateful_json_op(op_format_error)); i.register_op( - "format_error", - s.core_op(json_op(s.stateful_op(op_format_error))), - ); - i.register_op( - "format_diagnostic", - s.core_op(json_op(s.stateful_op(op_format_diagnostic))), + "op_format_diagnostic", + s.stateful_json_op(op_format_diagnostic), ); } diff --git a/cli/ops/fetch.rs b/cli/ops/fetch.rs index efcadc6a07..9f36ad5fd1 100644 --- a/cli/ops/fetch.rs +++ b/cli/ops/fetch.rs @@ -3,7 +3,6 @@ use super::dispatch_json::{Deserialize, JsonOp, Value}; use super::io::StreamResource; use crate::http_util::{create_http_client, HttpBody}; use crate::op_error::OpError; -use crate::ops::json_op; use crate::state::State; use deno_core::*; use futures::future::FutureExt; @@ -14,7 +13,7 @@ use std; use std::convert::From; pub fn init(i: &mut Isolate, s: &State) { - i.register_op("fetch", s.core_op(json_op(s.stateful_op(op_fetch)))); + i.register_op("op_fetch", s.stateful_json_op(op_fetch)); } #[derive(Deserialize)] diff --git a/cli/ops/files.rs b/cli/ops/files.rs index 2fc41bc342..4bf8b16887 100644 --- a/cli/ops/files.rs +++ b/cli/ops/files.rs @@ -3,7 +3,6 @@ use super::dispatch_json::{Deserialize, JsonOp, Value}; use super::io::StreamResource; use crate::fs as deno_fs; use crate::op_error::OpError; -use crate::ops::json_op; use crate::state::State; use deno_core::*; use futures::future::FutureExt; @@ -14,9 +13,9 @@ use std::path::Path; use tokio; pub fn init(i: &mut Isolate, s: &State) { - i.register_op("open", s.core_op(json_op(s.stateful_op(op_open)))); - i.register_op("close", s.core_op(json_op(s.stateful_op(op_close)))); - i.register_op("seek", s.core_op(json_op(s.stateful_op(op_seek)))); + i.register_op("op_open", s.stateful_json_op(op_open)); + i.register_op("op_close", s.stateful_json_op(op_close)); + i.register_op("op_seek", s.stateful_json_op(op_seek)); } #[derive(Deserialize)] diff --git a/cli/ops/fs.rs b/cli/ops/fs.rs index 014ba04a36..13c2418cb4 100644 --- a/cli/ops/fs.rs +++ b/cli/ops/fs.rs @@ -4,7 +4,6 @@ use super::dispatch_json::{blocking_json, Deserialize, JsonOp, Value}; use crate::fs as deno_fs; use crate::op_error::OpError; use crate::ops::dispatch_json::JsonResult; -use crate::ops::json_op; use crate::state::State; use deno_core::*; use remove_dir_all::remove_dir_all; @@ -19,30 +18,24 @@ use std::os::unix::fs::MetadataExt; use std::os::unix::fs::PermissionsExt; pub fn init(i: &mut Isolate, s: &State) { - i.register_op("chdir", s.core_op(json_op(s.stateful_op(op_chdir)))); - i.register_op("mkdir", s.core_op(json_op(s.stateful_op(op_mkdir)))); - i.register_op("chmod", s.core_op(json_op(s.stateful_op(op_chmod)))); - i.register_op("chown", s.core_op(json_op(s.stateful_op(op_chown)))); - i.register_op("remove", s.core_op(json_op(s.stateful_op(op_remove)))); - i.register_op("copy_file", s.core_op(json_op(s.stateful_op(op_copy_file)))); - i.register_op("stat", s.core_op(json_op(s.stateful_op(op_stat)))); - i.register_op("realpath", s.core_op(json_op(s.stateful_op(op_realpath)))); - i.register_op("read_dir", s.core_op(json_op(s.stateful_op(op_read_dir)))); - i.register_op("rename", s.core_op(json_op(s.stateful_op(op_rename)))); - i.register_op("link", s.core_op(json_op(s.stateful_op(op_link)))); - i.register_op("symlink", s.core_op(json_op(s.stateful_op(op_symlink)))); - i.register_op("read_link", s.core_op(json_op(s.stateful_op(op_read_link)))); - i.register_op("truncate", s.core_op(json_op(s.stateful_op(op_truncate)))); - i.register_op( - "make_temp_dir", - s.core_op(json_op(s.stateful_op(op_make_temp_dir))), - ); - i.register_op( - "make_temp_file", - s.core_op(json_op(s.stateful_op(op_make_temp_file))), - ); - i.register_op("cwd", s.core_op(json_op(s.stateful_op(op_cwd)))); - i.register_op("utime", s.core_op(json_op(s.stateful_op(op_utime)))); + i.register_op("op_chdir", s.stateful_json_op(op_chdir)); + i.register_op("op_mkdir", s.stateful_json_op(op_mkdir)); + i.register_op("op_chmod", s.stateful_json_op(op_chmod)); + i.register_op("op_chown", s.stateful_json_op(op_chown)); + i.register_op("op_remove", s.stateful_json_op(op_remove)); + i.register_op("op_copy_file", s.stateful_json_op(op_copy_file)); + i.register_op("op_stat", s.stateful_json_op(op_stat)); + i.register_op("op_realpath", s.stateful_json_op(op_realpath)); + i.register_op("op_read_dir", s.stateful_json_op(op_read_dir)); + i.register_op("op_rename", s.stateful_json_op(op_rename)); + i.register_op("op_link", s.stateful_json_op(op_link)); + i.register_op("op_symlink", s.stateful_json_op(op_symlink)); + i.register_op("op_read_link", s.stateful_json_op(op_read_link)); + i.register_op("op_truncate", s.stateful_json_op(op_truncate)); + i.register_op("op_make_temp_dir", s.stateful_json_op(op_make_temp_dir)); + i.register_op("op_make_temp_file", s.stateful_json_op(op_make_temp_file)); + i.register_op("op_cwd", s.stateful_json_op(op_cwd)); + i.register_op("op_utime", s.stateful_json_op(op_utime)); } #[derive(Deserialize)] diff --git a/cli/ops/fs_events.rs b/cli/ops/fs_events.rs index 3b4c9b9e51..21e402344a 100644 --- a/cli/ops/fs_events.rs +++ b/cli/ops/fs_events.rs @@ -1,7 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. use super::dispatch_json::{Deserialize, JsonOp, Value}; use crate::op_error::OpError; -use crate::ops::json_op; use crate::state::State; use deno_core::*; use futures::future::poll_fn; @@ -18,14 +17,8 @@ use std::path::PathBuf; use tokio::sync::mpsc; pub fn init(i: &mut Isolate, s: &State) { - i.register_op( - "fs_events_open", - s.core_op(json_op(s.stateful_op(op_fs_events_open))), - ); - i.register_op( - "fs_events_poll", - s.core_op(json_op(s.stateful_op(op_fs_events_poll))), - ); + i.register_op("op_fs_events_open", s.stateful_json_op(op_fs_events_open)); + i.register_op("op_fs_events_poll", s.stateful_json_op(op_fs_events_poll)); } struct FsEventsResource { diff --git a/cli/ops/io.rs b/cli/ops/io.rs index b150fa978d..8edb1f748e 100644 --- a/cli/ops/io.rs +++ b/cli/ops/io.rs @@ -47,11 +47,11 @@ lazy_static! { pub fn init(i: &mut Isolate, s: &State) { i.register_op( - "read", + "op_read", s.core_op(minimal_op(s.stateful_minimal_op(op_read))), ); i.register_op( - "write", + "op_write", s.core_op(minimal_op(s.stateful_minimal_op(op_write))), ); } @@ -124,23 +124,6 @@ enum IoState { Done, } -/// Tries to read some bytes directly into the given `buf` in asynchronous -/// manner, returning a future type. -/// -/// The returned future will resolve to both the I/O stream and the buffer -/// as well as the number of bytes read once the read operation is completed. -pub fn read(state: &State, rid: ResourceId, buf: T) -> Read -where - T: AsMut<[u8]>, -{ - Read { - rid, - buf, - io_state: IoState::Pending, - state: state.clone(), - } -} - /// A future which can be used to easily read available number of bytes to fill /// a buffer. /// @@ -185,13 +168,17 @@ pub fn op_read( zero_copy: Option, ) -> Pin> { debug!("read rid={}", rid); - let zero_copy = match zero_copy { - None => return futures::future::err(no_buffer_specified()).boxed_local(), - Some(buf) => buf, - }; - - let fut = read(state, rid as u32, zero_copy); - fut.boxed_local() + if zero_copy.is_none() { + return futures::future::err(no_buffer_specified()).boxed_local(); + } + // TODO(ry) Probably poll_fn can be used here and the Read struct eliminated. + Read { + rid: rid as u32, + buf: zero_copy.unwrap(), + io_state: IoState::Pending, + state: state.clone(), + } + .boxed_local() } /// `DenoAsyncWrite` is the same as the `tokio_io::AsyncWrite` trait @@ -261,24 +248,6 @@ pub struct Write { nwritten: i32, } -/// Creates a future that will write some of the buffer `buf` to -/// the stream resource with `rid`. -/// -/// Any error which happens during writing will cause both the stream and the -/// buffer to get destroyed. -pub fn write(state: &State, rid: ResourceId, buf: T) -> Write -where - T: AsRef<[u8]>, -{ - Write { - rid, - buf, - io_state: IoState::Pending, - state: state.clone(), - nwritten: 0, - } -} - /// This is almost the same implementation as in tokio, difference is /// that error type is `OpError` instead of `std::io::Error`. impl Future for Write @@ -329,12 +298,16 @@ pub fn op_write( zero_copy: Option, ) -> Pin> { debug!("write rid={}", rid); - let zero_copy = match zero_copy { - None => return futures::future::err(no_buffer_specified()).boxed_local(), - Some(buf) => buf, - }; - - let fut = write(state, rid as u32, zero_copy); - - fut.boxed_local() + if zero_copy.is_none() { + return futures::future::err(no_buffer_specified()).boxed_local(); + } + // TODO(ry) Probably poll_fn can be used here and the Write struct eliminated. + Write { + rid: rid as u32, + buf: zero_copy.unwrap(), + io_state: IoState::Pending, + state: state.clone(), + nwritten: 0, + } + .boxed_local() } diff --git a/cli/ops/net.rs b/cli/ops/net.rs index cdc5d9f1f3..2b3638fdb1 100644 --- a/cli/ops/net.rs +++ b/cli/ops/net.rs @@ -2,7 +2,6 @@ use super::dispatch_json::{Deserialize, JsonOp, Value}; use super::io::StreamResource; use crate::op_error::OpError; -use crate::ops::json_op; use crate::resolve_addr::resolve_addr; use crate::state::State; use deno_core::*; @@ -21,12 +20,12 @@ use tokio::net::TcpStream; use tokio::net::UdpSocket; pub fn init(i: &mut Isolate, s: &State) { - i.register_op("accept", s.core_op(json_op(s.stateful_op(op_accept)))); - i.register_op("connect", s.core_op(json_op(s.stateful_op(op_connect)))); - i.register_op("shutdown", s.core_op(json_op(s.stateful_op(op_shutdown)))); - i.register_op("listen", s.core_op(json_op(s.stateful_op(op_listen)))); - i.register_op("receive", s.core_op(json_op(s.stateful_op(op_receive)))); - i.register_op("send", s.core_op(json_op(s.stateful_op(op_send)))); + i.register_op("op_accept", s.stateful_json_op(op_accept)); + i.register_op("op_connect", s.stateful_json_op(op_connect)); + i.register_op("op_shutdown", s.stateful_json_op(op_shutdown)); + i.register_op("op_listen", s.stateful_json_op(op_listen)); + i.register_op("op_receive", s.stateful_json_op(op_receive)); + i.register_op("op_send", s.stateful_json_op(op_send)); } #[derive(Debug, PartialEq)] @@ -35,15 +34,6 @@ enum AcceptState { Done, } -/// Simply accepts a connection. -pub fn accept(state: &State, rid: ResourceId) -> Accept { - Accept { - accept_state: AcceptState::Pending, - rid, - state, - } -} - /// A future representing state of accepting a TCP connection. pub struct Accept<'a> { accept_state: AcceptState, @@ -109,7 +99,12 @@ fn op_accept( } let op = async move { - let (tcp_stream, _socket_addr) = accept(&state_, rid).await?; + let accept_fut = Accept { + accept_state: AcceptState::Pending, + rid, + state: &state_, + }; + let (tcp_stream, _socket_addr) = accept_fut.await?; let local_addr = tcp_stream.local_addr()?; let remote_addr = tcp_stream.peer_addr()?; let mut state = state_.borrow_mut(); @@ -164,10 +159,6 @@ struct ReceiveArgs { rid: i32, } -fn receive(state: &State, rid: ResourceId, buf: ZeroCopyBuf) -> Receive { - Receive { state, rid, buf } -} - fn op_receive( state: &State, args: Value, @@ -182,8 +173,12 @@ fn op_receive( let state_ = state.clone(); let op = async move { - let (size, remote_addr) = receive(&state_, rid, buf).await?; - + let receive_fut = Receive { + state: &state_, + rid, + buf, + }; + let (size, remote_addr) = receive_fut.await?; Ok(json!({ "size": size, "remoteAddr": { diff --git a/cli/ops/os.rs b/cli/ops/os.rs index 8e4f1e95db..c0479c656c 100644 --- a/cli/ops/os.rs +++ b/cli/ops/os.rs @@ -1,7 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. use super::dispatch_json::{Deserialize, JsonOp, Value}; use crate::op_error::OpError; -use crate::ops::json_op; use crate::state::State; use atty; use deno_core::*; @@ -12,19 +11,16 @@ use sys_info; use url::Url; pub fn init(i: &mut Isolate, s: &State) { - i.register_op("exit", s.core_op(json_op(s.stateful_op(op_exit)))); - i.register_op("is_tty", s.core_op(json_op(s.stateful_op(op_is_tty)))); - i.register_op("env", s.core_op(json_op(s.stateful_op(op_env)))); - i.register_op("exec_path", s.core_op(json_op(s.stateful_op(op_exec_path)))); - i.register_op("set_env", s.core_op(json_op(s.stateful_op(op_set_env)))); - i.register_op("get_env", s.core_op(json_op(s.stateful_op(op_get_env)))); - i.register_op("get_dir", s.core_op(json_op(s.stateful_op(op_get_dir)))); - i.register_op("hostname", s.core_op(json_op(s.stateful_op(op_hostname)))); - i.register_op("loadavg", s.core_op(json_op(s.stateful_op(op_loadavg)))); - i.register_op( - "os_release", - s.core_op(json_op(s.stateful_op(op_os_release))), - ); + i.register_op("op_exit", s.stateful_json_op(op_exit)); + i.register_op("op_is_tty", s.stateful_json_op(op_is_tty)); + i.register_op("op_env", s.stateful_json_op(op_env)); + i.register_op("op_exec_path", s.stateful_json_op(op_exec_path)); + i.register_op("op_set_env", s.stateful_json_op(op_set_env)); + i.register_op("op_get_env", s.stateful_json_op(op_get_env)); + i.register_op("op_get_dir", s.stateful_json_op(op_get_dir)); + i.register_op("op_hostname", s.stateful_json_op(op_hostname)); + i.register_op("op_loadavg", s.stateful_json_op(op_loadavg)); + i.register_op("op_os_release", s.stateful_json_op(op_os_release)); } #[derive(Deserialize)] diff --git a/cli/ops/permissions.rs b/cli/ops/permissions.rs index 7737174a27..6d109e0a81 100644 --- a/cli/ops/permissions.rs +++ b/cli/ops/permissions.rs @@ -2,23 +2,22 @@ use super::dispatch_json::{Deserialize, JsonOp, Value}; use crate::fs as deno_fs; use crate::op_error::OpError; -use crate::ops::json_op; use crate::state::State; use deno_core::*; use std::path::Path; pub fn init(i: &mut Isolate, s: &State) { i.register_op( - "query_permission", - s.core_op(json_op(s.stateful_op(op_query_permission))), + "op_query_permission", + s.stateful_json_op(op_query_permission), ); i.register_op( - "revoke_permission", - s.core_op(json_op(s.stateful_op(op_revoke_permission))), + "op_revoke_permission", + s.stateful_json_op(op_revoke_permission), ); i.register_op( - "request_permission", - s.core_op(json_op(s.stateful_op(op_request_permission))), + "op_request_permission", + s.stateful_json_op(op_request_permission), ); } diff --git a/cli/ops/plugins.rs b/cli/ops/plugins.rs index 67ad5a13ad..816c7ebb49 100644 --- a/cli/ops/plugins.rs +++ b/cli/ops/plugins.rs @@ -13,7 +13,7 @@ use std::rc::Rc; pub fn init(i: &mut Isolate, s: &State, r: Rc) { let r_ = r; i.register_op( - "open_plugin", + "op_open_plugin", s.core_op(json_op(s.stateful_op(move |state, args, zero_copy| { op_open_plugin(&r_, state, args, zero_copy) }))), diff --git a/cli/ops/process.rs b/cli/ops/process.rs index fe461bd28c..9da87bd396 100644 --- a/cli/ops/process.rs +++ b/cli/ops/process.rs @@ -2,7 +2,6 @@ use super::dispatch_json::{Deserialize, JsonOp, Value}; use super::io::StreamResource; use crate::op_error::OpError; -use crate::ops::json_op; use crate::signal::kill; use crate::state::State; use deno_core::*; @@ -22,12 +21,9 @@ use tokio::process::Command; use std::os::unix::process::ExitStatusExt; pub fn init(i: &mut Isolate, s: &State) { - i.register_op("run", s.core_op(json_op(s.stateful_op(op_run)))); - i.register_op( - "run_status", - s.core_op(json_op(s.stateful_op(op_run_status))), - ); - i.register_op("kill", s.core_op(json_op(s.stateful_op(op_kill)))); + i.register_op("op_run", s.stateful_json_op(op_run)); + i.register_op("op_run_status", s.stateful_json_op(op_run_status)); + i.register_op("op_kill", s.stateful_json_op(op_kill)); } fn clone_file(rid: u32, state: &State) -> Result { diff --git a/cli/ops/random.rs b/cli/ops/random.rs index 436b4d4fa9..4430aa9c5d 100644 --- a/cli/ops/random.rs +++ b/cli/ops/random.rs @@ -1,7 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. use super::dispatch_json::{JsonOp, Value}; use crate::op_error::OpError; -use crate::ops::json_op; use crate::state::State; use deno_core::*; use rand::thread_rng; @@ -9,8 +8,8 @@ use rand::Rng; pub fn init(i: &mut Isolate, s: &State) { i.register_op( - "get_random_values", - s.core_op(json_op(s.stateful_op(op_get_random_values))), + "op_get_random_values", + s.stateful_json_op(op_get_random_values), ); } diff --git a/cli/ops/repl.rs b/cli/ops/repl.rs index abd88b973e..3645cb9021 100644 --- a/cli/ops/repl.rs +++ b/cli/ops/repl.rs @@ -1,7 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. use super::dispatch_json::{blocking_json, Deserialize, JsonOp, Value}; use crate::op_error::OpError; -use crate::ops::json_op; use crate::repl; use crate::repl::Repl; use crate::state::State; @@ -10,14 +9,8 @@ use std::sync::Arc; use std::sync::Mutex; pub fn init(i: &mut Isolate, s: &State) { - i.register_op( - "repl_start", - s.core_op(json_op(s.stateful_op(op_repl_start))), - ); - i.register_op( - "repl_readline", - s.core_op(json_op(s.stateful_op(op_repl_readline))), - ); + i.register_op("op_repl_start", s.stateful_json_op(op_repl_start)); + i.register_op("op_repl_readline", s.stateful_json_op(op_repl_readline)); } struct ReplResource(Arc>); diff --git a/cli/ops/resources.rs b/cli/ops/resources.rs index 787894c2cc..3031725e2a 100644 --- a/cli/ops/resources.rs +++ b/cli/ops/resources.rs @@ -1,12 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. use super::dispatch_json::{JsonOp, Value}; use crate::op_error::OpError; -use crate::ops::json_op; use crate::state::State; use deno_core::*; pub fn init(i: &mut Isolate, s: &State) { - i.register_op("resources", s.core_op(json_op(s.stateful_op(op_resources)))); + i.register_op("op_resources", s.stateful_json_op(op_resources)); } fn op_resources( diff --git a/cli/ops/runtime.rs b/cli/ops/runtime.rs index fda05f4344..a888ce9a8c 100644 --- a/cli/ops/runtime.rs +++ b/cli/ops/runtime.rs @@ -3,7 +3,6 @@ use super::dispatch_json::{JsonOp, Value}; use crate::colors; use crate::fs as deno_fs; use crate::op_error::OpError; -use crate::ops::json_op; use crate::state::State; use crate::version; use crate::DenoSubcommand; @@ -21,8 +20,8 @@ static BUILD_OS: &str = "win"; static BUILD_ARCH: &str = "x64"; pub fn init(i: &mut Isolate, s: &State) { - i.register_op("start", s.core_op(json_op(s.stateful_op(op_start)))); - i.register_op("metrics", s.core_op(json_op(s.stateful_op(op_metrics)))); + i.register_op("op_start", s.stateful_json_op(op_start)); + i.register_op("op_metrics", s.stateful_json_op(op_metrics)); } fn op_start( diff --git a/cli/ops/runtime_compiler.rs b/cli/ops/runtime_compiler.rs index a9b907e287..0560567466 100644 --- a/cli/ops/runtime_compiler.rs +++ b/cli/ops/runtime_compiler.rs @@ -3,14 +3,13 @@ use super::dispatch_json::{Deserialize, JsonOp, Value}; use crate::compilers::runtime_compile_async; use crate::compilers::runtime_transpile_async; use crate::op_error::OpError; -use crate::ops::json_op; use crate::state::State; use deno_core::*; use std::collections::HashMap; pub fn init(i: &mut Isolate, s: &State) { - i.register_op("compile", s.core_op(json_op(s.stateful_op(op_compile)))); - i.register_op("transpile", s.core_op(json_op(s.stateful_op(op_transpile)))); + i.register_op("op_compile", s.stateful_json_op(op_compile)); + i.register_op("op_transpile", s.stateful_json_op(op_transpile)); } #[derive(Deserialize, Debug)] diff --git a/cli/ops/signal.rs b/cli/ops/signal.rs index 07a9cd5278..035c5ff454 100644 --- a/cli/ops/signal.rs +++ b/cli/ops/signal.rs @@ -1,7 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. use super::dispatch_json::{JsonOp, Value}; use crate::op_error::OpError; -use crate::ops::json_op; use crate::state::State; use deno_core::*; @@ -17,18 +16,9 @@ use std::task::Waker; use tokio::signal::unix::{signal, Signal, SignalKind}; pub fn init(i: &mut Isolate, s: &State) { - i.register_op( - "signal_bind", - s.core_op(json_op(s.stateful_op(op_signal_bind))), - ); - i.register_op( - "signal_unbind", - s.core_op(json_op(s.stateful_op(op_signal_unbind))), - ); - i.register_op( - "signal_poll", - s.core_op(json_op(s.stateful_op(op_signal_poll))), - ); + i.register_op("op_signal_bind", s.stateful_json_op(op_signal_bind)); + i.register_op("op_signal_unbind", s.stateful_json_op(op_signal_unbind)); + i.register_op("op_signal_poll", s.stateful_json_op(op_signal_poll)); } #[cfg(unix)] diff --git a/cli/ops/timers.rs b/cli/ops/timers.rs index b9a7dbdf7a..33aa7f8285 100644 --- a/cli/ops/timers.rs +++ b/cli/ops/timers.rs @@ -1,7 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. use super::dispatch_json::{Deserialize, JsonOp, Value}; use crate::op_error::OpError; -use crate::ops::json_op; use crate::state::State; use deno_core::*; use futures::future::FutureExt; @@ -11,14 +10,11 @@ use std::time::Instant; pub fn init(i: &mut Isolate, s: &State) { i.register_op( - "global_timer_stop", - s.core_op(json_op(s.stateful_op(op_global_timer_stop))), + "op_global_timer_stop", + s.stateful_json_op(op_global_timer_stop), ); - i.register_op( - "global_timer", - s.core_op(json_op(s.stateful_op(op_global_timer))), - ); - i.register_op("now", s.core_op(json_op(s.stateful_op(op_now)))); + i.register_op("op_global_timer", s.stateful_json_op(op_global_timer)); + i.register_op("op_now", s.stateful_json_op(op_now)); } fn op_global_timer_stop( diff --git a/cli/ops/tls.rs b/cli/ops/tls.rs index 8c648faafd..af507ce6a1 100644 --- a/cli/ops/tls.rs +++ b/cli/ops/tls.rs @@ -2,7 +2,6 @@ use super::dispatch_json::{Deserialize, JsonOp, Value}; use super::io::StreamResource; use crate::op_error::OpError; -use crate::ops::json_op; use crate::resolve_addr::resolve_addr; use crate::state::State; use deno_core::*; @@ -34,18 +33,9 @@ use webpki::DNSNameRef; use webpki_roots; pub fn init(i: &mut Isolate, s: &State) { - i.register_op( - "connect_tls", - s.core_op(json_op(s.stateful_op(op_connect_tls))), - ); - i.register_op( - "listen_tls", - s.core_op(json_op(s.stateful_op(op_listen_tls))), - ); - i.register_op( - "accept_tls", - s.core_op(json_op(s.stateful_op(op_accept_tls))), - ); + i.register_op("op_connect_tls", s.stateful_json_op(op_connect_tls)); + i.register_op("op_listen_tls", s.stateful_json_op(op_listen_tls)); + i.register_op("op_accept_tls", s.stateful_json_op(op_accept_tls)); } #[derive(Deserialize)] @@ -281,15 +271,6 @@ enum AcceptTlsState { Done, } -/// Simply accepts a TLS connection. -pub fn accept_tls(state: &State, rid: ResourceId) -> AcceptTls { - AcceptTls { - accept_state: AcceptTlsState::Pending, - rid, - state: state.clone(), - } -} - /// A future representing state of accepting a TLS connection. pub struct AcceptTls { accept_state: AcceptTlsState, @@ -347,7 +328,12 @@ fn op_accept_tls( let rid = args.rid as u32; let state = state.clone(); let op = async move { - let (tcp_stream, _socket_addr) = accept_tls(&state.clone(), rid).await?; + let accept_fut = AcceptTls { + accept_state: AcceptTlsState::Pending, + rid, + state: state.clone(), + }; + let (tcp_stream, _socket_addr) = accept_fut.await?; let local_addr = tcp_stream.local_addr()?; let remote_addr = tcp_stream.peer_addr()?; let tls_acceptor = { diff --git a/cli/ops/web_worker.rs b/cli/ops/web_worker.rs index db3ecd6ce4..f293fcf7e6 100644 --- a/cli/ops/web_worker.rs +++ b/cli/ops/web_worker.rs @@ -29,14 +29,14 @@ where pub fn init(i: &mut Isolate, s: &State, sender: &mpsc::Sender) { i.register_op( - "worker_post_message", + "op_worker_post_message", s.core_op(json_op(web_worker_op( sender.clone(), op_worker_post_message, ))), ); i.register_op( - "worker_close", + "op_worker_close", s.core_op(json_op(web_worker_op(sender.clone(), op_worker_close))), ); } diff --git a/cli/ops/worker_host.rs b/cli/ops/worker_host.rs index 910f444596..55afd6bf96 100644 --- a/cli/ops/worker_host.rs +++ b/cli/ops/worker_host.rs @@ -4,7 +4,6 @@ use crate::fmt_errors::JSError; use crate::futures::SinkExt; use crate::global_state::GlobalState; use crate::op_error::OpError; -use crate::ops::json_op; use crate::permissions::DenoPermissions; use crate::startup_data; use crate::state::State; @@ -21,21 +20,18 @@ use std::convert::From; use std::thread::JoinHandle; pub fn init(i: &mut Isolate, s: &State) { + i.register_op("op_create_worker", s.stateful_json_op(op_create_worker)); i.register_op( - "create_worker", - s.core_op(json_op(s.stateful_op(op_create_worker))), + "op_host_terminate_worker", + s.stateful_json_op(op_host_terminate_worker), ); i.register_op( - "host_terminate_worker", - s.core_op(json_op(s.stateful_op(op_host_terminate_worker))), + "op_host_post_message", + s.stateful_json_op(op_host_post_message), ); i.register_op( - "host_post_message", - s.core_op(json_op(s.stateful_op(op_host_post_message))), - ); - i.register_op( - "host_get_message", - s.core_op(json_op(s.stateful_op(op_host_get_message))), + "op_host_get_message", + s.stateful_json_op(op_host_get_message), ); } diff --git a/cli/state.rs b/cli/state.rs index 4e822f6a9f..5b8416093f 100644 --- a/cli/state.rs +++ b/cli/state.rs @@ -62,6 +62,17 @@ pub struct StateInner { } impl State { + pub fn stateful_json_op( + &self, + dispatcher: D, + ) -> impl Fn(&[u8], Option) -> CoreOp + where + D: Fn(&State, Value, Option) -> Result, + { + use crate::ops::json_op; + self.core_op(json_op(self.stateful_op(dispatcher))) + } + /// Wrap core `OpDispatcher` to collect metrics. pub fn core_op( &self, diff --git a/core/bindings.rs b/core/bindings.rs index 1741ad3b50..6ea0b9b917 100644 --- a/core/bindings.rs +++ b/core/bindings.rs @@ -387,9 +387,16 @@ fn send( unsafe { &mut *(scope.isolate().get_data(0) as *mut Isolate) }; assert!(!deno_isolate.global_context.is_empty()); - let op_id = v8::Local::::try_from(args.get(0)) - .unwrap() - .value() as u32; + let r = v8::Local::::try_from(args.get(0)); + + if let Err(err) = r { + let s = format!("bad op id {}", err); + let msg = v8::String::new(scope, &s).unwrap(); + scope.isolate().throw_exception(msg.into()); + return; + } + + let op_id = r.unwrap().value() as u32; let control = match v8::Local::::try_from(args.get(1)) { Ok(view) => { diff --git a/core/ops.rs b/core/ops.rs index 98407f1570..6b1aec6abc 100644 --- a/core/ops.rs +++ b/core/ops.rs @@ -62,7 +62,6 @@ impl OpRegistry { existing.is_none(), format!("Op already registered: {}", name) ); - lock.push(Rc::new(op)); drop(name_lock); drop(lock); diff --git a/deno_typescript/compiler_main.js b/deno_typescript/compiler_main.js index 013d6e157d..0f8c5cc145 100644 --- a/deno_typescript/compiler_main.js +++ b/deno_typescript/compiler_main.js @@ -46,7 +46,7 @@ function main(configText, rootNames) { handleDiagnostics(host, emitResult.diagnostics); dispatch( - "setEmitResult", + "op_set_emit_result", Object.assign(emitResult, { tsVersion: ts.version }) ); } @@ -98,7 +98,6 @@ function encode(str) { return ui8; } -// /** **Warning!** Op ids must be acquired from Rust using `Deno.core.ops()` * before dispatching any action. * @type {Record} @@ -184,7 +183,7 @@ class Host { fileName = moduleMap.get(fileName); } - const { sourceCode, moduleName } = dispatch("loadModule", { + const { sourceCode, moduleName } = dispatch("op_load_module", { moduleUrl: fileName, languageVersion, shouldCreateNewSourceFile @@ -228,7 +227,7 @@ class Host { return; } const moduleName = sourceFiles[sourceFiles.length - 1].moduleName; - return dispatch("writeFile", { fileName, moduleName, data }); + return dispatch("op_write_file", { fileName, moduleName, data }); } /** @@ -272,7 +271,7 @@ class Host { ? moduleMap.get(containingFile) : containingFile; /** @type {string[]} */ - const resolvedNames = dispatch("resolveModuleNames", { + const resolvedNames = dispatch("op_resolve_module_names", { moduleNames, containingFile }); @@ -332,7 +331,7 @@ function dispatch(opName, obj) { * @param {number} code */ function exit(code) { - dispatch("exit", { code }); + dispatch("op_exit2", { code }); return unreachable(); } diff --git a/deno_typescript/lib.rs b/deno_typescript/lib.rs index c825277e37..b2e2166be1 100644 --- a/deno_typescript/lib.rs +++ b/deno_typescript/lib.rs @@ -85,22 +85,24 @@ impl TSIsolate { })); isolate.register_op( - "loadModule", - compiler_op(state.clone(), ops::json_op(ops::load_module)), - ); - isolate - .register_op("exit", compiler_op(state.clone(), ops::json_op(ops::exit))); - isolate.register_op( - "writeFile", - compiler_op(state.clone(), ops::json_op(ops::write_file)), + "op_load_module", + compiler_op(state.clone(), ops::json_op(ops::op_load_module)), ); isolate.register_op( - "resolveModuleNames", - compiler_op(state.clone(), ops::json_op(ops::resolve_module_names)), + "op_exit2", + compiler_op(state.clone(), ops::json_op(ops::op_exit2)), ); isolate.register_op( - "setEmitResult", - compiler_op(state.clone(), ops::json_op(ops::set_emit_result)), + "op_write_file", + compiler_op(state.clone(), ops::json_op(ops::op_write_file)), + ); + isolate.register_op( + "op_resolve_module_names", + compiler_op(state.clone(), ops::json_op(ops::op_resolve_module_names)), + ); + isolate.register_op( + "op_set_emit_result", + compiler_op(state.clone(), ops::json_op(ops::op_set_emit_result)), ); TSIsolate { isolate, state } @@ -317,3 +319,28 @@ pub fn trace_serializer() { ]); assert_eq!(r, vec![dummy]); } + +/// Warning: Returns a non-JSON op dispatcher. Must be manually attached to +/// Isolate. +pub fn op_fetch_asset( + custom_assets: HashMap, +) -> impl Fn(&[u8], Option) -> CoreOp { + move |control: &[u8], zero_copy_buf: Option| -> CoreOp { + assert!(zero_copy_buf.is_none()); // zero_copy_buf unused in this op. + let name = std::str::from_utf8(control).unwrap(); + + let asset_code = if let Some(source_code) = get_asset(name) { + source_code.to_string() + } else if let Some(asset_path) = custom_assets.get(name) { + let source_code_vec = + std::fs::read(&asset_path).expect("Asset not found"); + let source_code = std::str::from_utf8(&source_code_vec).unwrap(); + source_code.to_string() + } else { + panic!("fetch_asset bad asset {}", name) + }; + + let vec = asset_code.into_bytes(); + deno_core::Op::Sync(vec.into_boxed_slice()) + } +} diff --git a/deno_typescript/ops.rs b/deno_typescript/ops.rs index f9b244397e..022eee00e3 100644 --- a/deno_typescript/ops.rs +++ b/deno_typescript/ops.rs @@ -41,7 +41,7 @@ struct LoadModule { should_create_new_source_file: bool, } -pub fn load_module(s: &mut TSState, v: Value) -> Result { +pub fn op_load_module(s: &mut TSState, v: Value) -> Result { let v: LoadModule = serde_json::from_value(v)?; let (module_name, source_code) = if v.module_url.starts_with("$asset$/") { let asset = v.module_url.replace("$asset$/", ""); @@ -98,7 +98,7 @@ struct WriteFile { module_name: String, } -pub fn write_file(s: &mut TSState, v: Value) -> Result { +pub fn op_write_file(s: &mut TSState, v: Value) -> Result { let v: WriteFile = serde_json::from_value(v)?; let module_specifier = ModuleSpecifier::resolve_url_or_path(&v.file_name)?; if s.bundle { @@ -119,7 +119,7 @@ struct ResolveModuleNames { containing_file: String, } -pub fn resolve_module_names( +pub fn op_resolve_module_names( _s: &mut TSState, v: Value, ) -> Result { @@ -143,7 +143,7 @@ struct Exit { code: i32, } -pub fn exit(s: &mut TSState, v: Value) -> Result { +pub fn op_exit2(s: &mut TSState, v: Value) -> Result { let v: Exit = serde_json::from_value(v)?; s.exit_code = v.code; std::process::exit(v.code) @@ -157,7 +157,7 @@ pub struct EmitResult { pub emitted_files: Vec, } -pub fn set_emit_result(s: &mut TSState, v: Value) -> Result { +pub fn op_set_emit_result(s: &mut TSState, v: Value) -> Result { let v: EmitResult = serde_json::from_value(v)?; s.emit_result = Some(v); Ok(json!(true))