1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-03 04:48:52 -05:00

Clean up return value of deno_execute

and deno_respond
This commit is contained in:
Ryan Dahl 2019-02-01 19:46:54 -05:00
parent 0b082c4361
commit 1770a77bca
6 changed files with 53 additions and 43 deletions

View file

@ -112,8 +112,8 @@ const char* deno_last_exception(Deno* d_) {
} }
} }
int deno_execute(Deno* d_, void* user_data, const char* js_filename, void deno_execute(Deno* d_, void* user_data, const char* js_filename,
const char* js_source) { const char* js_source) {
auto* d = unwrap(d_); auto* d = unwrap(d_);
deno::UserDataScope user_data_scope(d, user_data); deno::UserDataScope user_data_scope(d, user_data);
auto* isolate = d->isolate_; auto* isolate = d->isolate_;
@ -122,17 +122,17 @@ int deno_execute(Deno* d_, void* user_data, const char* js_filename,
v8::HandleScope handle_scope(isolate); v8::HandleScope handle_scope(isolate);
auto context = d->context_.Get(d->isolate_); auto context = d->context_.Get(d->isolate_);
CHECK(!context.IsEmpty()); CHECK(!context.IsEmpty());
return deno::Execute(context, js_filename, js_source) ? 1 : 0; deno::Execute(context, js_filename, js_source);
} }
int deno_respond(Deno* d_, void* user_data, int32_t req_id, deno_buf buf) { void deno_respond(Deno* d_, void* user_data, int32_t req_id, deno_buf buf) {
auto* d = unwrap(d_); auto* d = unwrap(d_);
if (d->current_args_ != nullptr) { if (d->current_args_ != nullptr) {
// Synchronous response. // Synchronous response.
auto ab = deno::ImportBuf(d, buf); auto ab = deno::ImportBuf(d, buf);
d->current_args_->GetReturnValue().Set(ab); d->current_args_->GetReturnValue().Set(ab);
d->current_args_ = nullptr; d->current_args_ = nullptr;
return 0; return;
} }
// Asynchronous response. // Asynchronous response.
@ -151,7 +151,7 @@ int deno_respond(Deno* d_, void* user_data, int32_t req_id, deno_buf buf) {
auto recv_ = d->recv_.Get(d->isolate_); auto recv_ = d->recv_.Get(d->isolate_);
if (recv_.IsEmpty()) { if (recv_.IsEmpty()) {
d->last_exception_ = "libdeno.recv_ has not been called."; d->last_exception_ = "libdeno.recv_ has not been called.";
return 1; return;
} }
v8::Local<v8::Value> args[1]; v8::Local<v8::Value> args[1];
@ -161,10 +161,7 @@ int deno_respond(Deno* d_, void* user_data, int32_t req_id, deno_buf buf) {
if (try_catch.HasCaught()) { if (try_catch.HasCaught()) {
CHECK(v.IsEmpty()); CHECK(v.IsEmpty());
deno::HandleException(context, try_catch.Exception()); deno::HandleException(context, try_catch.Exception());
return 1;
} }
return 0;
} }
void deno_check_promise_errors(Deno* d_) { void deno_check_promise_errors(Deno* d_) {

View file

@ -49,10 +49,9 @@ void deno_delete(Deno* d);
// Compile and execute a traditional JavaScript script that does not use // Compile and execute a traditional JavaScript script that does not use
// module import statements. // module import statements.
// Return value: 0 = fail, 1 = success // If it succeeded deno_last_exception() will return NULL.
// Get error text with deno_last_exception(). void deno_execute(Deno* d, void* user_data, const char* js_filename,
int deno_execute(Deno* d, void* user_data, const char* js_filename, const char* js_source);
const char* js_source);
// deno_respond sends up to one message back for every deno_recv_cb made. // deno_respond sends up to one message back for every deno_recv_cb made.
// //
@ -70,9 +69,8 @@ int deno_execute(Deno* d, void* user_data, const char* js_filename,
// Calling this function more than once with the same req_id will result in // Calling this function more than once with the same req_id will result in
// an error. // an error.
// //
// A non-zero return value, means a JS exception was encountered during the // If a JS exception was encountered, deno_last_exception() will be non-NULL.
// libdeno.recv() callback. Check deno_last_exception() for exception text. void deno_respond(Deno* d, void* user_data, int32_t req_id, deno_buf buf);
int deno_respond(Deno* d, void* user_data, int32_t req_id, deno_buf buf);
void deno_check_promise_errors(Deno* d); void deno_check_promise_errors(Deno* d);
@ -95,9 +93,11 @@ const char* deno_mod_imports_get(Deno* d, deno_mod id, size_t index);
typedef deno_mod (*deno_resolve_cb)(void* user_data, const char* specifier, typedef deno_mod (*deno_resolve_cb)(void* user_data, const char* specifier,
deno_mod referrer); deno_mod referrer);
// If it succeeded deno_last_exception() will return NULL.
void deno_mod_instantiate(Deno* d, void* user_data, deno_mod id, void deno_mod_instantiate(Deno* d, void* user_data, deno_mod id,
deno_resolve_cb cb); deno_resolve_cb cb);
// If it succeeded deno_last_exception() will return NULL.
void deno_mod_evaluate(Deno* d, void* user_data, deno_mod id); void deno_mod_evaluate(Deno* d, void* user_data, deno_mod id);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -4,19 +4,21 @@
TEST(LibDenoTest, InitializesCorrectly) { TEST(LibDenoTest, InitializesCorrectly) {
EXPECT_NE(snapshot.data_ptr, nullptr); EXPECT_NE(snapshot.data_ptr, nullptr);
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr}); Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "1 + 2")); deno_execute(d, nullptr, "a.js", "1 + 2");
EXPECT_EQ(nullptr, deno_last_exception(d));
deno_delete(d); deno_delete(d);
} }
TEST(LibDenoTest, Snapshotter) { TEST(LibDenoTest, Snapshotter) {
Deno* d1 = deno_new(deno_config{1, empty, empty, nullptr}); Deno* d1 = deno_new(deno_config{1, empty, empty, nullptr});
EXPECT_TRUE(deno_execute(d1, nullptr, "a.js", "a = 1 + 2")); deno_execute(d1, nullptr, "a.js", "a = 1 + 2");
EXPECT_EQ(nullptr, deno_last_exception(d1));
deno_buf test_snapshot = deno_get_snapshot(d1); deno_buf test_snapshot = deno_get_snapshot(d1);
deno_delete(d1); deno_delete(d1);
Deno* d2 = deno_new(deno_config{0, test_snapshot, empty, nullptr}); Deno* d2 = deno_new(deno_config{0, test_snapshot, empty, nullptr});
EXPECT_TRUE( deno_execute(d2, nullptr, "b.js", "if (a != 3) throw Error('x');");
deno_execute(d2, nullptr, "b.js", "if (a != 3) throw Error('x');")); EXPECT_EQ(nullptr, deno_last_exception(d2));
deno_delete(d2); deno_delete(d2);
delete[] test_snapshot.data_ptr; delete[] test_snapshot.data_ptr;
@ -24,14 +26,16 @@ TEST(LibDenoTest, Snapshotter) {
TEST(LibDenoTest, CanCallFunction) { TEST(LibDenoTest, CanCallFunction) {
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr}); Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", deno_execute(d, nullptr, "a.js",
"if (CanCallFunction() != 'foo') throw Error();")); "if (CanCallFunction() != 'foo') throw Error();");
EXPECT_EQ(nullptr, deno_last_exception(d));
deno_delete(d); deno_delete(d);
} }
TEST(LibDenoTest, ErrorsCorrectly) { TEST(LibDenoTest, ErrorsCorrectly) {
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr}); Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
EXPECT_FALSE(deno_execute(d, nullptr, "a.js", "throw Error()")); deno_execute(d, nullptr, "a.js", "throw Error()");
EXPECT_NE(nullptr, deno_last_exception(d));
deno_delete(d); deno_delete(d);
} }
@ -76,7 +80,8 @@ TEST(LibDenoTest, RecvReturnEmpty) {
EXPECT_EQ(buf.data_ptr[2], 'c'); EXPECT_EQ(buf.data_ptr[2], 'c');
}; };
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb}); Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb});
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "RecvReturnEmpty()")); deno_execute(d, nullptr, "a.js", "RecvReturnEmpty()");
EXPECT_EQ(nullptr, deno_last_exception(d));
EXPECT_EQ(count, 2); EXPECT_EQ(count, 2);
deno_delete(d); deno_delete(d);
} }
@ -94,14 +99,16 @@ TEST(LibDenoTest, RecvReturnBar) {
deno_respond(d, user_data, req_id, strbuf("bar")); deno_respond(d, user_data, req_id, strbuf("bar"));
}; };
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb}); Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb});
EXPECT_TRUE(deno_execute(d, d, "a.js", "RecvReturnBar()")); deno_execute(d, d, "a.js", "RecvReturnBar()");
EXPECT_EQ(nullptr, deno_last_exception(d));
EXPECT_EQ(count, 1); EXPECT_EQ(count, 1);
deno_delete(d); deno_delete(d);
} }
TEST(LibDenoTest, DoubleRecvFails) { TEST(LibDenoTest, DoubleRecvFails) {
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr}); Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
EXPECT_FALSE(deno_execute(d, nullptr, "a.js", "DoubleRecvFails()")); deno_execute(d, nullptr, "a.js", "DoubleRecvFails()");
EXPECT_NE(nullptr, deno_last_exception(d));
deno_delete(d); deno_delete(d);
} }
@ -135,7 +142,8 @@ TEST(LibDenoTest, SendRecvSlice) {
deno_respond(d, user_data, req_id, buf2); deno_respond(d, user_data, req_id, buf2);
}; };
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb}); Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb});
EXPECT_TRUE(deno_execute(d, d, "a.js", "SendRecvSlice()")); deno_execute(d, d, "a.js", "SendRecvSlice()");
EXPECT_EQ(nullptr, deno_last_exception(d));
EXPECT_EQ(count, 5); EXPECT_EQ(count, 5);
deno_delete(d); deno_delete(d);
} }
@ -152,26 +160,29 @@ TEST(LibDenoTest, JSSendArrayBufferViewTypes) {
EXPECT_EQ(buf.data_ptr[0], count); EXPECT_EQ(buf.data_ptr[0], count);
}; };
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb}); Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb});
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "JSSendArrayBufferViewTypes()")); deno_execute(d, nullptr, "a.js", "JSSendArrayBufferViewTypes()");
EXPECT_EQ(nullptr, deno_last_exception(d));
EXPECT_EQ(count, 3); EXPECT_EQ(count, 3);
deno_delete(d); deno_delete(d);
} }
TEST(LibDenoTest, TypedArraySnapshots) { TEST(LibDenoTest, TypedArraySnapshots) {
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr}); Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "TypedArraySnapshots()")); deno_execute(d, nullptr, "a.js", "TypedArraySnapshots()");
EXPECT_EQ(nullptr, deno_last_exception(d));
deno_delete(d); deno_delete(d);
} }
TEST(LibDenoTest, SnapshotBug) { TEST(LibDenoTest, SnapshotBug) {
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr}); Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "SnapshotBug()")); deno_execute(d, nullptr, "a.js", "SnapshotBug()");
EXPECT_EQ(nullptr, deno_last_exception(d));
deno_delete(d); deno_delete(d);
} }
TEST(LibDenoTest, GlobalErrorHandling) { TEST(LibDenoTest, GlobalErrorHandling) {
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr}); Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
EXPECT_FALSE(deno_execute(d, nullptr, "a.js", "GlobalErrorHandling()")); deno_execute(d, nullptr, "a.js", "GlobalErrorHandling()");
std::string expected = std::string expected =
"{\"message\":\"Uncaught ReferenceError: notdefined is not defined\"," "{\"message\":\"Uncaught ReferenceError: notdefined is not defined\","
"\"sourceLine\":\" " "\"sourceLine\":\" "
@ -200,7 +211,8 @@ TEST(LibDenoTest, DataBuf) {
EXPECT_EQ(buf.data_ptr[1], 2); EXPECT_EQ(buf.data_ptr[1], 2);
}; };
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb}); Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb});
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "DataBuf()")); deno_execute(d, nullptr, "a.js", "DataBuf()");
EXPECT_EQ(nullptr, deno_last_exception(d));
EXPECT_EQ(count, 1); EXPECT_EQ(count, 1);
// data_buf was subsequently changed in JS, let's check that our copy reflects // data_buf was subsequently changed in JS, let's check that our copy reflects
// that. // that.
@ -214,7 +226,8 @@ TEST(LibDenoTest, CheckPromiseErrors) {
auto recv_cb = [](auto _, int req_id, auto buf, auto data_buf) { count++; }; auto recv_cb = [](auto _, int req_id, auto buf, auto data_buf) { count++; };
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb}); Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb});
EXPECT_EQ(deno_last_exception(d), nullptr); EXPECT_EQ(deno_last_exception(d), nullptr);
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "CheckPromiseErrors()")); deno_execute(d, nullptr, "a.js", "CheckPromiseErrors()");
EXPECT_EQ(nullptr, deno_last_exception(d));
EXPECT_EQ(deno_last_exception(d), nullptr); EXPECT_EQ(deno_last_exception(d), nullptr);
EXPECT_EQ(count, 1); EXPECT_EQ(count, 1);
// We caught the exception. So still no errors after calling // We caught the exception. So still no errors after calling
@ -227,7 +240,7 @@ TEST(LibDenoTest, CheckPromiseErrors) {
TEST(LibDenoTest, LastException) { TEST(LibDenoTest, LastException) {
Deno* d = deno_new(deno_config{0, empty, empty, nullptr}); Deno* d = deno_new(deno_config{0, empty, empty, nullptr});
EXPECT_EQ(deno_last_exception(d), nullptr); EXPECT_EQ(deno_last_exception(d), nullptr);
EXPECT_FALSE(deno_execute(d, nullptr, "a.js", "\n\nthrow Error('boo');\n\n")); deno_execute(d, nullptr, "a.js", "\n\nthrow Error('boo');\n\n");
EXPECT_STREQ(deno_last_exception(d), EXPECT_STREQ(deno_last_exception(d),
"{\"message\":\"Uncaught Error: boo\",\"sourceLine\":\"throw " "{\"message\":\"Uncaught Error: boo\",\"sourceLine\":\"throw "
"Error('boo');\",\"scriptResourceName\":\"a.js\",\"lineNumber\":" "Error('boo');\",\"scriptResourceName\":\"a.js\",\"lineNumber\":"
@ -242,7 +255,7 @@ TEST(LibDenoTest, LastException) {
TEST(LibDenoTest, EncodeErrorBug) { TEST(LibDenoTest, EncodeErrorBug) {
Deno* d = deno_new(deno_config{0, empty, empty, nullptr}); Deno* d = deno_new(deno_config{0, empty, empty, nullptr});
EXPECT_EQ(deno_last_exception(d), nullptr); EXPECT_EQ(deno_last_exception(d), nullptr);
EXPECT_FALSE(deno_execute(d, nullptr, "a.js", "eval('a')")); deno_execute(d, nullptr, "a.js", "eval('a')");
EXPECT_STREQ( EXPECT_STREQ(
deno_last_exception(d), deno_last_exception(d),
"{\"message\":\"Uncaught ReferenceError: a is not " "{\"message\":\"Uncaught ReferenceError: a is not "
@ -260,7 +273,8 @@ TEST(LibDenoTest, Shared) {
uint8_t s[] = {0, 1, 2}; uint8_t s[] = {0, 1, 2};
deno_buf shared = {nullptr, 0, s, 3}; deno_buf shared = {nullptr, 0, s, 3};
Deno* d = deno_new(deno_config{0, snapshot, shared, nullptr}); Deno* d = deno_new(deno_config{0, snapshot, shared, nullptr});
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "Shared()")); deno_execute(d, nullptr, "a.js", "Shared()");
EXPECT_EQ(nullptr, deno_last_exception(d));
EXPECT_EQ(s[0], 42); EXPECT_EQ(s[0], 42);
EXPECT_EQ(s[1], 43); EXPECT_EQ(s[1], 43);
EXPECT_EQ(s[2], 44); EXPECT_EQ(s[2], 44);

View file

@ -26,8 +26,8 @@ int main(int argc, char** argv) {
deno_config config = {1, deno::empty_buf, deno::empty_buf, nullptr}; deno_config config = {1, deno::empty_buf, deno::empty_buf, nullptr};
Deno* d = deno_new(config); Deno* d = deno_new(config);
int r = deno_execute(d, nullptr, js_fn, js_source.c_str()); deno_execute(d, nullptr, js_fn, js_source.c_str());
if (!r) { if (deno_last_exception(d) != nullptr) {
std::cerr << "Snapshot Exception " << std::endl; std::cerr << "Snapshot Exception " << std::endl;
std::cerr << deno_last_exception(d) << std::endl; std::cerr << deno_last_exception(d) << std::endl;
deno_delete(d); deno_delete(d);

View file

@ -251,7 +251,7 @@ impl Isolate {
) -> Result<(), JSError> { ) -> Result<(), JSError> {
let filename = CString::new(js_filename).unwrap(); let filename = CString::new(js_filename).unwrap();
let source = CString::new(js_source).unwrap(); let source = CString::new(js_source).unwrap();
let r = unsafe { unsafe {
libdeno::deno_execute( libdeno::deno_execute(
self.libdeno_isolate, self.libdeno_isolate,
self.as_raw_ptr(), self.as_raw_ptr(),
@ -259,9 +259,8 @@ impl Isolate {
source.as_ptr(), source.as_ptr(),
) )
}; };
if r == 0 { if let Some(err) = self.last_exception() {
let js_error = self.last_exception().unwrap(); return Err(err);
return Err(js_error);
} }
Ok(()) Ok(())
} }

View file

@ -148,7 +148,7 @@ extern "C" {
user_data: *const c_void, user_data: *const c_void,
js_filename: *const c_char, js_filename: *const c_char,
js_source: *const c_char, js_source: *const c_char,
) -> c_int; );
// Modules // Modules