1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

perf: use fast ops for tty (#15976)

This commit is contained in:
Divy Srivastava 2022-09-23 09:35:45 +05:30 committed by GitHub
parent b5dfcbbcbe
commit 72af1496d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 72 additions and 62 deletions

21
cli/bench/tty.js Normal file
View file

@ -0,0 +1,21 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
const queueMicrotask = globalThis.queueMicrotask || process.nextTick;
let [total, count] = typeof Deno !== "undefined"
? Deno.args
: [process.argv[2], process.argv[3]];
total = total ? parseInt(total, 0) : 50;
count = count ? parseInt(count, 10) : 100000;
function bench(fun) {
const start = Date.now();
for (let i = 0; i < count; i++) fun();
const elapsed = Date.now() - start;
const rate = Math.floor(count / (elapsed / 1000));
console.log(`time ${elapsed} ms rate ${rate}`);
if (--total) queueMicrotask(() => bench(fun));
}
bench(() => {
Deno.consoleSize(0);
});

View file

@ -629,6 +629,10 @@ fn can_be_fast_api(core: &TokenStream2, f: &syn::ItemFn) -> Option<FastApiSyn> {
args.push(arg);
}
None => match is_ref_slice(&ty) {
Some(SliceType::U32Mut) => {
args.push(quote! { #core::v8::fast_api::Type::TypedArray(#core::v8::fast_api::CType::Uint32) });
slices.insert(pos, quote!(u32));
}
Some(_) => {
args.push(quote! { #core::v8::fast_api::Type::TypedArray(#core::v8::fast_api::CType::Uint8) });
slices.insert(pos, quote!(u8));

View file

@ -2,24 +2,28 @@
"use strict";
((window) => {
const {
Uint32Array,
Uint8Array,
} = window.__bootstrap.primordials;
const core = window.Deno.core;
const ops = core.ops;
const size = new Uint32Array(2);
function consoleSize(rid) {
return ops.op_console_size(rid);
ops.op_console_size(rid, size);
return { columns: size[0], rows: size[1] };
}
const isattyBuffer = new Uint8Array(1);
function isatty(rid) {
return ops.op_isatty(rid);
ops.op_isatty(rid, isattyBuffer);
return !!isattyBuffer[0];
}
const DEFAULT_SET_RAW_OPTIONS = {
cbreak: false,
};
const DEFAULT_CBREAK = false;
function setRaw(rid, mode, options = {}) {
const rOptions = { ...DEFAULT_SET_RAW_OPTIONS, ...options };
ops.op_set_raw({ rid, mode, options: rOptions });
ops.op_set_raw(rid, mode, options.cbreak || DEFAULT_CBREAK);
}
window.__bootstrap.tty = {

View file

@ -837,7 +837,6 @@ fn op_copy_file_sync(
#[cfg(target_os = "macos")]
{
use libc::chmod;
use libc::clonefile;
use libc::stat;
use libc::unlink;

View file

@ -5,9 +5,6 @@ use deno_core::error::AnyError;
use deno_core::op;
use deno_core::Extension;
use deno_core::OpState;
use deno_core::ResourceId;
use serde::Deserialize;
use serde::Serialize;
use std::io::Error;
#[cfg(unix)]
@ -50,27 +47,15 @@ pub fn init() -> Extension {
.build()
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SetRawOptions {
#[op(fast)]
fn op_set_raw(
state: &mut OpState,
rid: u32,
is_raw: bool,
cbreak: bool,
}
#[derive(Deserialize)]
pub struct SetRawArgs {
rid: ResourceId,
mode: bool,
options: SetRawOptions,
}
#[op]
fn op_set_raw(state: &mut OpState, args: SetRawArgs) -> Result<(), AnyError> {
) -> Result<(), AnyError> {
super::check_unstable(state, "Deno.setRaw");
let rid = args.rid;
let is_raw = args.mode;
let cbreak = args.options.cbreak;
// From https://github.com/kkawakam/rustyline/blob/master/src/tty/windows.rs
// and https://github.com/kkawakam/rustyline/blob/master/src/tty/unix.rs
// and https://github.com/crossterm-rs/crossterm/blob/e35d4d2c1cc4c919e36d242e014af75f6127ab50/src/terminal/sys/windows.rs
@ -168,9 +153,13 @@ fn op_set_raw(state: &mut OpState, args: SetRawArgs) -> Result<(), AnyError> {
}
}
#[op]
fn op_isatty(state: &mut OpState, rid: ResourceId) -> Result<bool, AnyError> {
let isatty: bool = StdFileResource::with_file(state, rid, move |std_file| {
#[op(fast)]
fn op_isatty(
state: &mut OpState,
rid: u32,
out: &mut [u8],
) -> Result<(), AnyError> {
StdFileResource::with_file(state, rid, move |std_file| {
#[cfg(windows)]
{
use winapi::shared::minwindef::FALSE;
@ -181,7 +170,11 @@ fn op_isatty(state: &mut OpState, rid: ResourceId) -> Result<bool, AnyError> {
// If I cannot get mode out of console, it is not a console.
// TODO(bartlomieju):
#[allow(clippy::undocumented_unsafe_blocks)]
Ok(unsafe { consoleapi::GetConsoleMode(handle, &mut test_mode) != FALSE })
{
out[0] = unsafe {
consoleapi::GetConsoleMode(handle, &mut test_mode) != FALSE
} as u8;
}
}
#[cfg(unix)]
{
@ -189,26 +182,22 @@ fn op_isatty(state: &mut OpState, rid: ResourceId) -> Result<bool, AnyError> {
let raw_fd = std_file.as_raw_fd();
// TODO(bartlomieju):
#[allow(clippy::undocumented_unsafe_blocks)]
Ok(unsafe { libc::isatty(raw_fd as libc::c_int) == 1 })
{
out[0] = unsafe { libc::isatty(raw_fd as libc::c_int) == 1 } as u8;
}
}
})?;
Ok(isatty)
Ok(())
})
}
#[derive(Serialize)]
struct ConsoleSize {
columns: u32,
rows: u32,
}
#[op]
#[op(fast)]
fn op_console_size(
state: &mut OpState,
rid: ResourceId,
) -> Result<ConsoleSize, AnyError> {
rid: u32,
result: &mut [u32],
) -> Result<(), AnyError> {
super::check_unstable(state, "Deno.consoleSize");
let size = StdFileResource::with_file(state, rid, move |std_file| {
StdFileResource::with_file(state, rid, move |std_file| {
#[cfg(windows)]
{
use std::os::windows::io::AsRawHandle;
@ -224,11 +213,9 @@ fn op_console_size(
{
return Err(Error::last_os_error().into());
}
Ok(ConsoleSize {
columns: bufinfo.dwSize.X as u32,
rows: bufinfo.dwSize.Y as u32,
})
result[0] = bufinfo.dwSize.X as u32;
result[1] = bufinfo.dwSize.Y as u32;
Ok(())
}
}
@ -244,15 +231,10 @@ fn op_console_size(
if libc::ioctl(fd, libc::TIOCGWINSZ, &mut size as *mut _) != 0 {
return Err(Error::last_os_error().into());
}
// TODO (caspervonb) return a tuple instead
Ok(ConsoleSize {
columns: size.ws_col as u32,
rows: size.ws_row as u32,
})
result[0] = size.ws_col as u32;
result[1] = size.ws_row as u32;
Ok(())
}
}
})?;
Ok(size)
})
}