1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-22 06:09:25 -05:00

Switch back to recv/send instead of pub/sub for low-level API.

This commit is contained in:
Ryan Dahl 2018-07-01 18:07:12 +02:00
parent 7fcaf7d35d
commit a33f575cda
9 changed files with 79 additions and 78 deletions

4
js/deno.d.ts vendored
View file

@ -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;
}

View file

@ -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`);

View file

@ -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");
};

View file

@ -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());

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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);
});
}

View file

@ -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);
}