Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signals handling [WIP] #2621

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions core/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ main_extern_rlib = [
"libc",
"serde_json",
"log",
"tokio_signal"
]

rust_rlib("deno") {
Expand Down
1 change: 1 addition & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ lazy_static = "1.3.0"
libc = "0.2.55"
log = "0.4.6"
serde_json = "1.0.39"
tokio-signal = "0.2.7"

[[example]]
name = "deno_core_http_bench"
Expand Down
17 changes: 15 additions & 2 deletions core/isolate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use futures::task;
use futures::Async::*;
use futures::Future;
use futures::Poll;
use tokio_signal;
use libc::c_void;
use std::ffi::CStr;
use std::ffi::CString;
Expand All @@ -27,6 +28,8 @@ use std::sync::{Arc, Mutex, Once, ONCE_INIT};

pub type Buf = Box<[u8]>;

pub type Custom = futures::FlattenStream<std::boxed::Box<dyn futures::Future<Item=std::boxed::Box<dyn futures::Stream<Error=std::io::Error, Item=()> + std::marker::Send>, Error=std::io::Error> + std::marker::Send>>;

pub type OpAsyncFuture = Box<dyn Future<Item = Buf, Error = ()> + Send>;

pub enum Op {
Expand Down Expand Up @@ -86,6 +89,7 @@ pub struct Isolate {
shared: SharedQueue,
pending_ops: FuturesUnordered<OpAsyncFuture>,
have_unpolled_ops: bool,
ctrl_c: Custom,
}

unsafe impl Send for Isolate {}
Expand Down Expand Up @@ -138,6 +142,7 @@ impl Isolate {
};

let libdeno_isolate = unsafe { libdeno::deno_new(libdeno_config) };
let ctrl_c = tokio_signal::ctrl_c().flatten_stream();

let mut core_isolate = Self {
libdeno_isolate,
Expand All @@ -147,6 +152,7 @@ impl Isolate {
needs_init,
pending_ops: FuturesUnordered::new(),
have_unpolled_ops: false,
ctrl_c,
};

// If we want to use execute this has to happen here sadly.
Expand Down Expand Up @@ -274,7 +280,11 @@ impl Isolate {
libdeno::deno_check_promise_errors(self.libdeno_isolate);
}
}

fn throw_error(&self) {
unsafe {
libdeno::deno_print_stack_trace(self.libdeno_isolate);
}
}
fn respond(&mut self, maybe_buf: Option<&[u8]>) -> Result<(), JSError> {
let buf = match maybe_buf {
None => deno_buf::empty(),
Expand Down Expand Up @@ -464,7 +474,10 @@ impl Future for Isolate {
// The other side should have shifted off all the messages.
assert_eq!(self.shared.size(), 0);
}

match self.ctrl_c.poll() {
Ok(Ready(_)) => self.throw_error(),
_ => println!("..."),
}
if overflow_response.is_some() {
let buf = overflow_response.take().unwrap();
self.respond(Some(&buf))?;
Expand Down
2 changes: 2 additions & 0 deletions core/libdeno.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ extern "C" {
js_source: *const c_char,
);
pub fn deno_terminate_execution(i: *const isolate);
pub fn deno_print_stack_trace(i: *const isolate);

// Modules

Expand Down Expand Up @@ -296,4 +297,5 @@ extern "C" {

#[allow(dead_code)]
pub fn deno_snapshot_delete(s: &mut deno_snapshot);

}
7 changes: 7 additions & 0 deletions core/libdeno/api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -243,4 +243,11 @@ void deno_terminate_execution(Deno* d_) {
deno::DenoIsolate* d = reinterpret_cast<deno::DenoIsolate*>(d_);
d->isolate_->TerminateExecution();
}

void deno_print_stack_trace(Deno * d_){
deno::DenoIsolate* d = reinterpret_cast<deno::DenoIsolate*>(d_);
auto* isolate = d->isolate_;
CHECK_NOT_NULL(isolate);
deno::ThrowInvalidArgument(isolate);
}
}
14 changes: 10 additions & 4 deletions core/libdeno/binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,11 @@ void PromiseRejectCallback(v8::PromiseRejectMessage promise_reject_message) {
}

void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
CHECK_GE(args.Length(), 1);
CHECK_LE(args.Length(), 3);
auto* isolate = args.GetIsolate();
int argsLen = args.Length();
if (argsLen < 1 || argsLen > 2) {
ThrowInvalidArgument(isolate);
}
DenoIsolate* d = DenoIsolate::FromIsolate(isolate);
auto context = d->context_.Get(d->isolate_);
v8::HandleScope handle_scope(isolate);
Expand Down Expand Up @@ -220,7 +222,7 @@ void Send(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
DenoIsolate* d = DenoIsolate::FromIsolate(isolate);
DCHECK_EQ(d->isolate_, isolate);

v8::HandleScope handle_scope(isolate);

deno_buf control = {nullptr, 0};
Expand Down Expand Up @@ -375,7 +377,11 @@ void EvalContext(const v8::FunctionCallbackInfo<v8::Value>& args) {
auto context = d->context_.Get(isolate);
v8::Context::Scope context_scope(context);

CHECK(args[0]->IsString());
if (!(args[0]->IsString())) {
ThrowInvalidArgument(isolate);
return;
}

auto source = args[0].As<v8::String>();

auto output = v8::Array::New(isolate, 2);
Expand Down
5 changes: 5 additions & 0 deletions core/libdeno/exceptions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -214,4 +214,9 @@ void HandleExceptionMessage(v8::Local<v8::Context> context,
CHECK_NOT_NULL(d);
d->last_exception_ = json_str;
}

void ThrowInvalidArgument(v8::Isolate* isolate) {
isolate->ThrowException(v8::Exception::TypeError(v8_str("Invalid Argument")));
}

} // namespace deno
2 changes: 2 additions & 0 deletions core/libdeno/exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ void HandleException(v8::Local<v8::Context> context,

void HandleExceptionMessage(v8::Local<v8::Context> context,
v8::Local<v8::Message> message);

void ThrowInvalidArgument(v8::Isolate* isolate);
} // namespace deno

#endif // EXCEPTIONS_H_
14 changes: 14 additions & 0 deletions core/libdeno/libdeno_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,20 @@ TEST(LibDenoTest, LibDenoEvalContextError) {
deno_delete(d);
}

TEST(LibDenoTest, LibDenoEvalContextInvalidArgument) {
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
deno_execute(d, nullptr, "a.js", "LibDenoEvalContextInvalidArgument();");
EXPECT_EQ(nullptr, deno_last_exception(d));
deno_delete(d);
}

TEST(LibDenoTest, LibDenoPrintInvalidArgument) {
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
deno_execute(d, nullptr, "a.js", "LibDenoPrintInvalidArgument();");
EXPECT_EQ(nullptr, deno_last_exception(d));
deno_delete(d);
}

TEST(LibDenoTest, SharedAtomics) {
int32_t s[] = {0, 1, 2};
deno_buf shared = {reinterpret_cast<uint8_t*>(s), sizeof s};
Expand Down
24 changes: 24 additions & 0 deletions core/libdeno/libdeno_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,27 @@ global.LibDenoEvalContextError = () => {
assert(!errInfo5.isCompileError); // is NOT a compilation error! (just eval)
assert(errInfo5.thrown.message === "Unexpected end of input");
};

global.LibDenoEvalContextInvalidArgument = () => {
try {
Deno.core.evalContext();
} catch (e) {
assert(e instanceof TypeError);
assert(e.message === "Invalid Argument");
}
};

global.LibDenoPrintInvalidArgument = () => {
try {
Deno.core.print();
} catch (e) {
assert(e instanceof TypeError);
assert(e.message === "Invalid Argument");
}
try {
Deno.core.print(2, 3, 4);
} catch (e) {
assert(e instanceof TypeError);
assert(e.message === "Invalid Argument");
}
};