mirror of
https://github.com/denoland/deno.git
synced 2025-01-21 21:50:00 -05:00
Switch back to recv/send instead of pub/sub for low-level API.
This commit is contained in:
parent
7fcaf7d35d
commit
a33f575cda
9 changed files with 79 additions and 78 deletions
4
js/deno.d.ts
vendored
4
js/deno.d.ts
vendored
|
@ -3,8 +3,8 @@
|
|||
type MessageCallback = (msg: ArrayBuffer) => void;
|
||||
|
||||
interface Deno {
|
||||
sub(channel: string, cb: MessageCallback): void;
|
||||
pub(channel: string, msg: ArrayBuffer): null | ArrayBuffer;
|
||||
recv(channel: string, cb: MessageCallback): void;
|
||||
send(channel: string, msg: ArrayBuffer): null | ArrayBuffer;
|
||||
print(x: string): void;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ const window = globalEval("this");
|
|||
|
||||
window["denoMain"] = () => {
|
||||
deno.print(`ts.version: ${ts.version}`);
|
||||
const res = deno.pub("startDeno2", emptyArrayBuffer());
|
||||
const res = deno.send("startDeno2", emptyArrayBuffer());
|
||||
// deno.print(`after`);
|
||||
const resUi8 = new Uint8Array(res);
|
||||
deno.print(`before`);
|
||||
|
|
|
@ -27,34 +27,34 @@ global.TypedArraySnapshots = () => {
|
|||
assert(snapshotted[3] === 7);
|
||||
};
|
||||
|
||||
global.PubSuccess = () => {
|
||||
deno.sub((channel, msg) => {
|
||||
assert(channel === "PubSuccess");
|
||||
deno.print("PubSuccess: ok");
|
||||
global.SendSuccess = () => {
|
||||
deno.recv((channel, msg) => {
|
||||
assert(channel === "SendSuccess");
|
||||
deno.print("SendSuccess: ok");
|
||||
});
|
||||
};
|
||||
|
||||
global.PubByteLength = () => {
|
||||
deno.sub((channel, msg) => {
|
||||
assert(channel === "PubByteLength");
|
||||
global.SendByteLength = () => {
|
||||
deno.recv((channel, msg) => {
|
||||
assert(channel === "SendByteLength");
|
||||
assert(msg instanceof ArrayBuffer);
|
||||
assert(msg.byteLength === 3);
|
||||
});
|
||||
};
|
||||
|
||||
global.SubReturnEmpty = () => {
|
||||
global.RecvReturnEmpty = () => {
|
||||
const ui8 = new Uint8Array("abc".split("").map(c => c.charCodeAt(0)));
|
||||
const ab = typedArrayToArrayBuffer(ui8);
|
||||
let r = deno.pub("SubReturnEmpty", ab);
|
||||
let r = deno.send("RecvReturnEmpty", ab);
|
||||
assert(r == null);
|
||||
r = deno.pub("SubReturnEmpty", ab);
|
||||
r = deno.send("RecvReturnEmpty", ab);
|
||||
assert(r == null);
|
||||
};
|
||||
|
||||
global.SubReturnBar = () => {
|
||||
global.RecvReturnBar = () => {
|
||||
const ui8 = new Uint8Array("abc".split("").map(c => c.charCodeAt(0)));
|
||||
const ab = typedArrayToArrayBuffer(ui8);
|
||||
const r = deno.pub("SubReturnBar", ab);
|
||||
const r = deno.send("RecvReturnBar", ab);
|
||||
assert(r instanceof ArrayBuffer);
|
||||
assert(r.byteLength === 3);
|
||||
const rui8 = new Uint8Array(r);
|
||||
|
@ -62,11 +62,11 @@ global.SubReturnBar = () => {
|
|||
assert(rstr === "bar");
|
||||
};
|
||||
|
||||
global.DoubleSubFails = () => {
|
||||
// deno.sub is an internal function and should only be called once from the
|
||||
global.DoubleRecvFails = () => {
|
||||
// deno.recv is an internal function and should only be called once from the
|
||||
// runtime.
|
||||
deno.sub((channel, msg) => assert(false));
|
||||
deno.sub((channel, msg) => assert(false));
|
||||
deno.recv((channel, msg) => assert(false));
|
||||
deno.recv((channel, msg) => assert(false));
|
||||
};
|
||||
|
||||
// The following join has caused SnapshotBug to segfault when using kKeep.
|
||||
|
@ -84,7 +84,7 @@ global.ErrorHandling = () => {
|
|||
assert(line === 3);
|
||||
assert(col === 1);
|
||||
assert(error instanceof Error);
|
||||
deno.pub("ErrorHandling", typedArrayToArrayBuffer(new Uint8Array([42])));
|
||||
deno.send("ErrorHandling", typedArrayToArrayBuffer(new Uint8Array([42])));
|
||||
};
|
||||
eval("\n\n notdefined()\n//# sourceURL=helloworld.js");
|
||||
};
|
||||
|
|
34
src/deno.cc
34
src/deno.cc
|
@ -110,16 +110,16 @@ void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|||
fflush(stdout);
|
||||
}
|
||||
|
||||
// Sets the sub callback.
|
||||
void Sub(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
// Sets the recv callback.
|
||||
void Recv(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
v8::Isolate* isolate = args.GetIsolate();
|
||||
Deno* d = reinterpret_cast<Deno*>(isolate->GetData(0));
|
||||
DCHECK_EQ(d->isolate, isolate);
|
||||
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
if (!d->sub.IsEmpty()) {
|
||||
isolate->ThrowException(v8_str("denoSub already called."));
|
||||
if (!d->recv.IsEmpty()) {
|
||||
isolate->ThrowException(v8_str("deno.recv already called."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -127,10 +127,10 @@ void Sub(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|||
CHECK(v->IsFunction());
|
||||
v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(v);
|
||||
|
||||
d->sub.Reset(isolate, func);
|
||||
d->recv.Reset(isolate, func);
|
||||
}
|
||||
|
||||
void Pub(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
void Send(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
v8::Isolate* isolate = args.GetIsolate();
|
||||
Deno* d = static_cast<Deno*>(isolate->GetData(0));
|
||||
DCHECK_EQ(d->isolate, isolate);
|
||||
|
@ -211,13 +211,13 @@ void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context,
|
|||
auto print_val = print_tmpl->GetFunction(context).ToLocalChecked();
|
||||
CHECK(deno_val->Set(context, deno::v8_str("print"), print_val).FromJust());
|
||||
|
||||
auto sub_tmpl = v8::FunctionTemplate::New(isolate, Sub);
|
||||
auto sub_val = sub_tmpl->GetFunction(context).ToLocalChecked();
|
||||
CHECK(deno_val->Set(context, deno::v8_str("sub"), sub_val).FromJust());
|
||||
auto recv_tmpl = v8::FunctionTemplate::New(isolate, Recv);
|
||||
auto recv_val = recv_tmpl->GetFunction(context).ToLocalChecked();
|
||||
CHECK(deno_val->Set(context, deno::v8_str("recv"), recv_val).FromJust());
|
||||
|
||||
auto pub_tmpl = v8::FunctionTemplate::New(isolate, Pub);
|
||||
auto pub_val = pub_tmpl->GetFunction(context).ToLocalChecked();
|
||||
CHECK(deno_val->Set(context, deno::v8_str("pub"), pub_val).FromJust());
|
||||
auto send_tmpl = v8::FunctionTemplate::New(isolate, Send);
|
||||
auto send_val = send_tmpl->GetFunction(context).ToLocalChecked();
|
||||
CHECK(deno_val->Set(context, deno::v8_str("send"), send_val).FromJust());
|
||||
|
||||
bool r = Execute(context, js_filename, js_source);
|
||||
CHECK(r);
|
||||
|
@ -264,7 +264,7 @@ int deno_execute(Deno* d, const char* js_filename, const char* js_source) {
|
|||
return deno::Execute(context, js_filename, js_source) ? 1 : 0;
|
||||
}
|
||||
|
||||
int deno_pub(Deno* d, const char* channel, deno_buf buf) {
|
||||
int deno_send(Deno* d, const char* channel, deno_buf buf) {
|
||||
v8::Locker locker(d->isolate);
|
||||
v8::Isolate::Scope isolate_scope(d->isolate);
|
||||
v8::HandleScope handle_scope(d->isolate);
|
||||
|
@ -274,9 +274,9 @@ int deno_pub(Deno* d, const char* channel, deno_buf buf) {
|
|||
|
||||
v8::TryCatch try_catch(d->isolate);
|
||||
|
||||
auto sub = d->sub.Get(d->isolate);
|
||||
if (sub.IsEmpty()) {
|
||||
d->last_exception = "deno_sub has not been called.";
|
||||
auto recv = d->recv.Get(d->isolate);
|
||||
if (recv.IsEmpty()) {
|
||||
d->last_exception = "deno.recv has not been called.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -288,7 +288,7 @@ int deno_pub(Deno* d, const char* channel, deno_buf buf) {
|
|||
args[0] = deno::v8_str(channel);
|
||||
args[1] = ab;
|
||||
|
||||
sub->Call(context->Global(), 1, args);
|
||||
recv->Call(context->Global(), 1, args);
|
||||
|
||||
if (try_catch.HasCaught()) {
|
||||
deno::HandleException(context, try_catch.Exception());
|
||||
|
|
|
@ -13,9 +13,9 @@ struct deno_s {
|
|||
v8::Isolate* isolate;
|
||||
const v8::FunctionCallbackInfo<v8::Value>* currentArgs;
|
||||
std::string last_exception;
|
||||
v8::Persistent<v8::Function> sub;
|
||||
v8::Persistent<v8::Function> recv;
|
||||
v8::Persistent<v8::Context> context;
|
||||
deno_sub_cb cb;
|
||||
deno_recv_cb cb;
|
||||
void* data;
|
||||
};
|
||||
}
|
||||
|
@ -27,13 +27,13 @@ struct InternalFieldData {
|
|||
};
|
||||
|
||||
void Print(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void Sub(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void Pub(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void Recv(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void Send(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static intptr_t external_references[] = {reinterpret_cast<intptr_t>(Print),
|
||||
reinterpret_cast<intptr_t>(Sub),
|
||||
reinterpret_cast<intptr_t>(Pub), 0};
|
||||
reinterpret_cast<intptr_t>(Recv),
|
||||
reinterpret_cast<intptr_t>(Send), 0};
|
||||
|
||||
Deno* NewFromSnapshot(void* data, deno_sub_cb cb);
|
||||
Deno* NewFromSnapshot(void* data, deno_recv_cb cb);
|
||||
|
||||
void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context,
|
||||
const char* js_filename, const char* js_source);
|
||||
|
|
|
@ -34,7 +34,7 @@ void DeserializeInternalFields(v8::Local<v8::Object> holder, int index,
|
|||
deserialized_data.push_back(embedder_field);
|
||||
}
|
||||
|
||||
Deno* NewFromSnapshot(void* data, deno_sub_cb cb) {
|
||||
Deno* NewFromSnapshot(void* data, deno_recv_cb cb) {
|
||||
Deno* d = new Deno;
|
||||
d->currentArgs = nullptr;
|
||||
d->cb = cb;
|
||||
|
@ -65,7 +65,7 @@ Deno* NewFromSnapshot(void* data, deno_sub_cb cb) {
|
|||
} // namespace deno
|
||||
|
||||
extern "C" {
|
||||
Deno* deno_new(void* data, deno_sub_cb cb) {
|
||||
Deno* deno_new(void* data, deno_recv_cb cb) {
|
||||
return deno::NewFromSnapshot(data, cb);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,15 +17,15 @@ typedef struct {
|
|||
struct deno_s;
|
||||
typedef struct deno_s Deno;
|
||||
|
||||
// A callback to receive a message from deno_pub javascript call.
|
||||
// A callback to receive a message from deno.send javascript call.
|
||||
// buf is valid only for the lifetime of the call.
|
||||
typedef void (*deno_sub_cb)(Deno* d, const char* channel, deno_buf buf);
|
||||
typedef void (*deno_recv_cb)(Deno* d, const char* channel, deno_buf buf);
|
||||
|
||||
void deno_init();
|
||||
const char* deno_v8_version();
|
||||
void deno_set_flags(int* argc, char** argv);
|
||||
|
||||
Deno* deno_new(void* data, deno_sub_cb cb);
|
||||
Deno* deno_new(void* data, deno_recv_cb cb);
|
||||
void deno_delete(Deno* d);
|
||||
|
||||
// Returns false on error.
|
||||
|
@ -33,14 +33,14 @@ void deno_delete(Deno* d);
|
|||
// 0 = fail, 1 = success
|
||||
int deno_execute(Deno* d, const char* js_filename, const char* js_source);
|
||||
|
||||
// Routes message to the javascript callback set with deno_sub(). A false return
|
||||
// value indicates error. Check deno_last_exception() for exception text.
|
||||
// Routes message to the javascript callback set with deno.recv(). A false
|
||||
// return value indicates error. Check deno_last_exception() for exception text.
|
||||
// 0 = fail, 1 = success
|
||||
int deno_pub(Deno* d, const char* channel, deno_buf buf);
|
||||
int deno_send(Deno* d, const char* channel, deno_buf buf);
|
||||
|
||||
// Call this inside a deno_sub_cb to respond synchronously to messages.
|
||||
// If this is not called during the life time of a deno_sub_cb callback
|
||||
// the denoPub() call in javascript will return null.
|
||||
// Call this inside a deno_recv_cb to respond synchronously to messages.
|
||||
// If this is not called during the life time of a deno_recv_cb callback
|
||||
// the deno.send() call in javascript will return null.
|
||||
void deno_set_response(Deno* d, deno_buf buf);
|
||||
|
||||
const char* deno_last_exception(Deno* d);
|
||||
|
|
13
src/main.rs
13
src/main.rs
|
@ -17,7 +17,7 @@ struct DenoC {
|
|||
_unused: [u8; 0],
|
||||
}
|
||||
|
||||
type DenoSubCb = extern "C" fn(d: *const DenoC, channel: *const c_char, buf: deno_buf);
|
||||
type DenoRecvCb = extern "C" fn(d: *const DenoC, channel: *const c_char, buf: deno_buf);
|
||||
|
||||
#[link(name = "deno", kind = "static")]
|
||||
extern "C" {
|
||||
|
@ -26,7 +26,7 @@ extern "C" {
|
|||
fn deno_v8_version() -> *const c_char;
|
||||
fn deno_set_flags(argc: *mut c_int, argv: *mut *mut c_char);
|
||||
|
||||
fn deno_new(data: *const c_void, cb: DenoSubCb) -> *const DenoC;
|
||||
fn deno_new(data: *const c_void, cb: DenoRecvCb) -> *const DenoC;
|
||||
fn deno_delete(d: *const DenoC);
|
||||
fn deno_last_exception(d: *const DenoC) -> *const c_char;
|
||||
#[allow(dead_code)]
|
||||
|
@ -123,8 +123,9 @@ fn main() {
|
|||
|
||||
let mut d = Deno::new();
|
||||
|
||||
d.execute("deno_main.js", "denoMain();").unwrap_or_else(|err| {
|
||||
println!("Error {}\n", err);
|
||||
std::process::exit(1);
|
||||
});
|
||||
d.execute("deno_main.js", "denoMain();")
|
||||
.unwrap_or_else(|err| {
|
||||
println!("Error {}\n", err);
|
||||
std::process::exit(1);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -25,62 +25,62 @@ TEST(MockRuntimeTest, ErrorsCorrectly) {
|
|||
|
||||
deno_buf strbuf(const char* str) { return deno_buf{str, strlen(str)}; }
|
||||
|
||||
TEST(MockRuntimeTest, PubSuccess) {
|
||||
TEST(MockRuntimeTest, SendSuccess) {
|
||||
Deno* d = deno_new(nullptr, nullptr);
|
||||
EXPECT_TRUE(deno_execute(d, "a.js", "PubSuccess()"));
|
||||
EXPECT_TRUE(deno_pub(d, "PubSuccess", strbuf("abc")));
|
||||
EXPECT_TRUE(deno_execute(d, "a.js", "SendSuccess()"));
|
||||
EXPECT_TRUE(deno_send(d, "SendSuccess", strbuf("abc")));
|
||||
deno_delete(d);
|
||||
}
|
||||
|
||||
TEST(MockRuntimeTest, PubByteLength) {
|
||||
TEST(MockRuntimeTest, SendByteLength) {
|
||||
Deno* d = deno_new(nullptr, nullptr);
|
||||
EXPECT_TRUE(deno_execute(d, "a.js", "PubByteLength()"));
|
||||
EXPECT_TRUE(deno_execute(d, "a.js", "SendByteLength()"));
|
||||
// We pub the wrong sized message, it should throw.
|
||||
EXPECT_FALSE(deno_pub(d, "PubByteLength", strbuf("abcd")));
|
||||
EXPECT_FALSE(deno_send(d, "SendByteLength", strbuf("abcd")));
|
||||
deno_delete(d);
|
||||
}
|
||||
|
||||
TEST(MockRuntimeTest, PubNoCallback) {
|
||||
TEST(MockRuntimeTest, SendNoCallback) {
|
||||
Deno* d = deno_new(nullptr, nullptr);
|
||||
// We didn't call deno_sub(), pubing should fail.
|
||||
EXPECT_FALSE(deno_pub(d, "PubNoCallback", strbuf("abc")));
|
||||
// We didn't call deno.recv() in JS, should fail.
|
||||
EXPECT_FALSE(deno_send(d, "SendNoCallback", strbuf("abc")));
|
||||
deno_delete(d);
|
||||
}
|
||||
|
||||
TEST(MockRuntimeTest, SubReturnEmpty) {
|
||||
TEST(MockRuntimeTest, RecvReturnEmpty) {
|
||||
static int count = 0;
|
||||
Deno* d = deno_new(nullptr, [](auto _, auto channel, auto buf) {
|
||||
count++;
|
||||
EXPECT_STREQ(channel, "SubReturnEmpty");
|
||||
EXPECT_STREQ(channel, "RecvReturnEmpty");
|
||||
EXPECT_EQ(static_cast<size_t>(3), buf.len);
|
||||
EXPECT_EQ(buf.data[0], 'a');
|
||||
EXPECT_EQ(buf.data[1], 'b');
|
||||
EXPECT_EQ(buf.data[2], 'c');
|
||||
});
|
||||
EXPECT_TRUE(deno_execute(d, "a.js", "SubReturnEmpty()"));
|
||||
EXPECT_TRUE(deno_execute(d, "a.js", "RecvReturnEmpty()"));
|
||||
EXPECT_EQ(count, 2);
|
||||
deno_delete(d);
|
||||
}
|
||||
|
||||
TEST(MockRuntimeTest, SubReturnBar) {
|
||||
TEST(MockRuntimeTest, RecvReturnBar) {
|
||||
static int count = 0;
|
||||
Deno* d = deno_new(nullptr, [](auto deno, auto channel, auto buf) {
|
||||
count++;
|
||||
EXPECT_STREQ(channel, "SubReturnBar");
|
||||
EXPECT_STREQ(channel, "RecvReturnBar");
|
||||
EXPECT_EQ(static_cast<size_t>(3), buf.len);
|
||||
EXPECT_EQ(buf.data[0], 'a');
|
||||
EXPECT_EQ(buf.data[1], 'b');
|
||||
EXPECT_EQ(buf.data[2], 'c');
|
||||
deno_set_response(deno, strbuf("bar"));
|
||||
});
|
||||
EXPECT_TRUE(deno_execute(d, "a.js", "SubReturnBar()"));
|
||||
EXPECT_TRUE(deno_execute(d, "a.js", "RecvReturnBar()"));
|
||||
EXPECT_EQ(count, 1);
|
||||
deno_delete(d);
|
||||
}
|
||||
|
||||
TEST(MockRuntimeTest, DoubleSubFails) {
|
||||
TEST(MockRuntimeTest, DoubleRecvFails) {
|
||||
Deno* d = deno_new(nullptr, nullptr);
|
||||
EXPECT_FALSE(deno_execute(d, "a.js", "DoubleSubFails()"));
|
||||
EXPECT_FALSE(deno_execute(d, "a.js", "DoubleRecvFails()"));
|
||||
deno_delete(d);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue