Skip to content

Commit

Permalink
WIP op_id
Browse files Browse the repository at this point in the history
  • Loading branch information
ry committed Aug 6, 2019
1 parent 046cccf commit 6c5d684
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 43 deletions.
12 changes: 7 additions & 5 deletions core/isolate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,11 @@ impl Isolate {

extern "C" fn pre_dispatch(
user_data: *mut c_void,
op_id: i32,
control_argv0: deno_buf,
zero_copy_buf: deno_pinned_buf,
) {
assert_eq!(op_id, 42); // TODO(ry) actually use op_id.
let isolate = unsafe { Isolate::from_raw_ptr(user_data) };

let op = if let Some(ref f) = isolate.dispatch {
Expand Down Expand Up @@ -749,9 +751,9 @@ pub mod tests {
"filename.js",
r#"
let control = new Uint8Array([42]);
Deno.core.send(control);
Deno.core.send(42, control);
async function main() {
Deno.core.send(control);
Deno.core.send(42, control);
}
main();
"#,
Expand All @@ -770,7 +772,7 @@ pub mod tests {
import { b } from 'b.js'
if (b() != 'b') throw Error();
let control = new Uint8Array([42]);
Deno.core.send(control);
Deno.core.send(42, control);
"#,
)
.unwrap();
Expand Down Expand Up @@ -827,7 +829,7 @@ pub mod tests {
r#"
assert(nrecv == 0);
let control = new Uint8Array([42]);
Deno.core.send(control);
Deno.core.send(42, control);
assert(nrecv == 0);
"#,
));
Expand All @@ -838,7 +840,7 @@ pub mod tests {
"check2.js",
r#"
assert(nrecv == 1);
Deno.core.send(control);
Deno.core.send(42, control);
assert(nrecv == 1);
"#,
));
Expand Down
3 changes: 2 additions & 1 deletion core/libdeno.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ impl Snapshot2<'_> {
#[allow(non_camel_case_types)]
type deno_recv_cb = unsafe extern "C" fn(
user_data: *mut c_void,
control_buf: deno_buf, // deprecated
op_id: i32,
control_buf: deno_buf,
zero_copy_buf: deno_pinned_buf,
);

Expand Down
17 changes: 12 additions & 5 deletions core/libdeno/binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -223,22 +223,29 @@ void Send(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope handle_scope(isolate);

deno_buf control = {nullptr, 0};
if (args[0]->IsArrayBufferView()) {
auto view = v8::Local<v8::ArrayBufferView>::Cast(args[0]);

int32_t op_id = 0;
if (args[0]->IsInt32()) {
auto context = d->context_.Get(isolate);
op_id = args[0]->Int32Value(context).FromJust();
}

if (args[1]->IsArrayBufferView()) {
auto view = v8::Local<v8::ArrayBufferView>::Cast(args[1]);
auto data =
reinterpret_cast<uint8_t*>(view->Buffer()->GetContents().Data());
control = {data + view->ByteOffset(), view->ByteLength()};
}

PinnedBuf zero_copy =
args[1]->IsArrayBufferView()
? PinnedBuf(v8::Local<v8::ArrayBufferView>::Cast(args[1]))
args[2]->IsArrayBufferView()
? PinnedBuf(v8::Local<v8::ArrayBufferView>::Cast(args[2]))
: PinnedBuf();

DCHECK_NULL(d->current_args_);
d->current_args_ = &args;

d->recv_cb_(d->user_data_, control, zero_copy.IntoRaw());
d->recv_cb_(d->user_data_, op_id, control, zero_copy.IntoRaw());

if (d->current_args_ == nullptr) {
// This indicates that deno_repond() was called already.
Expand Down
20 changes: 15 additions & 5 deletions core/libdeno/deno.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,20 @@ typedef struct {

typedef struct deno_s Deno;

// A callback to receive a message from a libdeno.send() javascript call.
// A callback to receive a message from a Deno.core.send() javascript call.
// control_buf is valid for only for the lifetime of this callback.
// data_buf is valid until deno_respond() is called.
typedef void (*deno_recv_cb)(void* user_data, deno_buf control_buf,
//
// op_id corresponds to the first argument of Deno.core.send().
// op_id is an extra user-defined integer valued which is not interpreted by
// libdeno.
//
// control_buf corresponds to the second argument of Deno.core.send().
//
// zero_copy_buf corresponds to the third argument of Deno.core.send().
// The user must call deno_pinned_buf_delete on each zero_copy_buf received.
typedef void (*deno_recv_cb)(void* user_data, int32_t op_id,
deno_buf control_buf,
deno_pinned_buf zero_copy_buf);

typedef int deno_dyn_import_id;
Expand All @@ -49,7 +59,7 @@ typedef struct {
int will_snapshot; // Default 0. If calling deno_snapshot_new 1.
deno_snapshot load_snapshot; // A startup snapshot to use.
deno_buf shared; // Shared buffer to be mapped to libdeno.shared
deno_recv_cb recv_cb; // Maps to libdeno.send() calls.
deno_recv_cb recv_cb; // Maps to Deno.core.send() calls.
deno_dyn_import_cb dyn_import_cb;
} deno_config;

Expand Down Expand Up @@ -80,12 +90,12 @@ void deno_execute(Deno* d, void* user_data, const char* js_filename,

// deno_respond sends up to one message back for every deno_recv_cb made.
//
// If this is called during deno_recv_cb, the issuing libdeno.send() in
// If this is called during deno_recv_cb, the issuing Deno.core.send() in
// javascript will synchronously return the specified buf as an ArrayBuffer (or
// null if buf is empty).
//
// If this is called after deno_recv_cb has returned, the deno_respond
// will call into the JS callback specified by libdeno.recv().
// will call into the JS callback specified by Deno.core.recv().
//
// (Ideally, but not currently: After calling deno_respond(), the caller no
// longer owns `buf` and must not use it; deno_respond() is responsible for
Expand Down
17 changes: 12 additions & 5 deletions core/libdeno/libdeno_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ void assert_null(deno_pinned_buf b) {

TEST(LibDenoTest, RecvReturnEmpty) {
static int count = 0;
auto recv_cb = [](auto _, auto buf, auto zero_copy_buf) {
auto recv_cb = [](auto _, int32_t op_id, auto buf, auto zero_copy_buf) {
EXPECT_EQ(op_id, 42);
assert_null(zero_copy_buf);
count++;
EXPECT_EQ(static_cast<size_t>(3), buf.data_len);
Expand All @@ -66,7 +67,9 @@ TEST(LibDenoTest, RecvReturnEmpty) {

TEST(LibDenoTest, RecvReturnBar) {
static int count = 0;
auto recv_cb = [](auto user_data, auto buf, auto zero_copy_buf) {
auto recv_cb = [](auto user_data, int32_t op_id, auto buf,
auto zero_copy_buf) {
EXPECT_EQ(op_id, 42);
auto d = reinterpret_cast<Deno*>(user_data);
assert_null(zero_copy_buf);
count++;
Expand Down Expand Up @@ -126,8 +129,9 @@ TEST(LibDenoTest, GlobalErrorHandling) {
TEST(LibDenoTest, ZeroCopyBuf) {
static int count = 0;
static deno_pinned_buf zero_copy_buf2;
auto recv_cb = [](auto user_data, deno_buf buf,
auto recv_cb = [](auto user_data, int32_t op_id, deno_buf buf,
deno_pinned_buf zero_copy_buf) {
EXPECT_EQ(op_id, 42);
count++;
EXPECT_NE(zero_copy_buf.pin, nullptr);
zero_copy_buf.data_ptr[0] = 4;
Expand Down Expand Up @@ -155,7 +159,9 @@ TEST(LibDenoTest, ZeroCopyBuf) {

TEST(LibDenoTest, CheckPromiseErrors) {
static int count = 0;
auto recv_cb = [](auto _, auto buf, auto zero_copy_buf) { count++; };
auto recv_cb = [](auto _, int32_t op_id, auto buf, auto zero_copy_buf) {
count++;
};
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, nullptr});
EXPECT_EQ(deno_last_exception(d), nullptr);
deno_execute(d, nullptr, "a.js", "CheckPromiseErrors()");
Expand Down Expand Up @@ -264,7 +270,8 @@ TEST(LibDenoTest, SharedAtomics) {

TEST(LibDenoTest, WasmInstantiate) {
static int count = 0;
auto recv_cb = [](auto _, auto buf, auto zero_copy_buf) {
auto recv_cb = [](auto _, int32_t op_id, auto buf, auto zero_copy_buf) {
EXPECT_EQ(op_id, 42);
EXPECT_EQ(buf.data_len, 1u);
EXPECT_EQ(buf.data_ptr[0], 42);
count++;
Expand Down
24 changes: 12 additions & 12 deletions core/libdeno/libdeno_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ global.TypedArraySnapshots = () => {
global.RecvReturnEmpty = () => {
const m1 = new Uint8Array("abc".split("").map(c => c.charCodeAt(0)));
const m2 = m1.slice();
const r1 = Deno.core.send(m1);
const r1 = Deno.core.send(42, m1);
assert(r1 == null);
const r2 = Deno.core.send(m2);
const r2 = Deno.core.send(42, m2);
assert(r2 == null);
};

global.RecvReturnBar = () => {
const m = new Uint8Array("abc".split("").map(c => c.charCodeAt(0)));
const r = Deno.core.send(m);
const r = Deno.core.send(42, m);
assert(r instanceof Uint8Array);
assert(r.byteLength === 3);
const rstr = String.fromCharCode(...r);
Expand All @@ -58,7 +58,7 @@ global.SendRecvSlice = () => {
buf[0] = 100 + i;
buf[buf.length - 1] = 100 - i;
// On the native side, the slice is shortened by 19 bytes.
buf = Deno.core.send(buf);
buf = Deno.core.send(42, buf);
assert(buf.byteOffset === i * 11);
assert(buf.byteLength === abLen - i * 30 - 19);
assert(buf.buffer.byteLength == abLen);
Expand All @@ -78,17 +78,17 @@ global.JSSendArrayBufferViewTypes = () => {
const ab1 = new ArrayBuffer(4321);
const u8 = new Uint8Array(ab1, 2468, 1000);
u8[0] = 1;
Deno.core.send(u8);
Deno.core.send(42, u8);
// Send Uint32Array.
const ab2 = new ArrayBuffer(4321);
const u32 = new Uint32Array(ab2, 2468, 1000 / Uint32Array.BYTES_PER_ELEMENT);
u32[0] = 0x02020202;
Deno.core.send(u32);
Deno.core.send(42, u32);
// Send DataView.
const ab3 = new ArrayBuffer(4321);
const dv = new DataView(ab3, 2468, 1000);
dv.setUint8(0, 3);
Deno.core.send(dv);
Deno.core.send(42, dv);
};

// The following join has caused SnapshotBug to segfault when using kKeep.
Expand All @@ -110,7 +110,7 @@ global.ZeroCopyBuf = () => {
const b = zeroCopyBuf;
// The second parameter of send should modified by the
// privileged side.
const r = Deno.core.send(a, b);
const r = Deno.core.send(42, a, b);
assert(r == null);
// b is different.
assert(b[0] === 4);
Expand All @@ -129,7 +129,7 @@ global.CheckPromiseErrors = () => {
try {
await fn();
} catch (e) {
Deno.core.send(new Uint8Array([42]));
Deno.core.send(42, new Uint8Array([42]));
}
})();
};
Expand Down Expand Up @@ -239,17 +239,17 @@ global.WasmInstantiate = () => {
]);

(async () => {
Deno.core.send(new Uint8Array([42]));
Deno.core.send(42, new Uint8Array([42]));

const wasm = await WebAssembly.instantiate(bytes);

Deno.core.send(new Uint8Array([42]));
Deno.core.send(42, new Uint8Array([42]));

const result = wasm.instance.exports.add(1, 3);
if (result != 4) {
throw Error("bad");
}
// To signal success, we send back a fixed buffer.
Deno.core.send(new Uint8Array([42]));
Deno.core.send(42, new Uint8Array([42]));
})();
};
20 changes: 11 additions & 9 deletions core/libdeno/modules_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
#include "test.h"

static int exec_count = 0;
void recv_cb(void* user_data, deno_buf buf, deno_pinned_buf zero_copy_buf) {
void recv_cb(void* user_data, int32_t op_id, deno_buf buf,
deno_pinned_buf zero_copy_buf) {
// We use this to check that scripts have executed.
EXPECT_EQ(1u, buf.data_len);
EXPECT_EQ(42, op_id);
EXPECT_EQ(buf.data_ptr[0], 4);
EXPECT_EQ(zero_copy_buf.data_ptr, nullptr);
EXPECT_EQ(zero_copy_buf.data_len, 0u);
Expand All @@ -20,7 +22,7 @@ TEST(ModulesTest, Resolution) {
static deno_mod a = deno_mod_new(d, true, "a.js",
"import { b } from 'b.js'\n"
"if (b() != 'b') throw Error();\n"
"Deno.core.send(new Uint8Array([4]));");
"Deno.core.send(42, new Uint8Array([4]));");
EXPECT_NE(a, 0);
EXPECT_EQ(nullptr, deno_last_exception(d));

Expand Down Expand Up @@ -72,7 +74,7 @@ TEST(ModulesTest, ResolutionError) {

static deno_mod a = deno_mod_new(d, true, "a.js",
"import 'bad'\n"
"Deno.core.send(new Uint8Array([4]));");
"Deno.core.send(42, new Uint8Array([4]));");
EXPECT_NE(a, 0);
EXPECT_EQ(nullptr, deno_last_exception(d));

Expand Down Expand Up @@ -106,7 +108,7 @@ TEST(ModulesTest, ImportMetaUrl) {
static deno_mod a =
deno_mod_new(d, true, "a.js",
"if ('a.js' != import.meta.url) throw 'hmm'\n"
"Deno.core.send(new Uint8Array([4]));");
"Deno.core.send(42, new Uint8Array([4]));");
EXPECT_NE(a, 0);
EXPECT_EQ(nullptr, deno_last_exception(d));

Expand Down Expand Up @@ -165,7 +167,7 @@ TEST(ModulesTest, DynamicImportSuccess) {
" let mod = await import('foo'); \n"
" assert(mod.b() === 'b'); \n"
// Send a message to signify that we're done.
" Deno.core.send(new Uint8Array([4])); \n"
" Deno.core.send(42, new Uint8Array([4])); \n"
"})(); \n";
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, dyn_import_cb});
static deno_mod a = deno_mod_new(d, true, "a.js", src);
Expand Down Expand Up @@ -206,7 +208,7 @@ TEST(ModulesTest, DynamicImportError) {
"(async () => { \n"
" let mod = await import('foo'); \n"
// The following should be unreachable.
" Deno.core.send(new Uint8Array([4])); \n"
" Deno.core.send(42, new Uint8Array([4])); \n"
"})(); \n";
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, dyn_import_cb});
static deno_mod a = deno_mod_new(d, true, "a.js", src);
Expand Down Expand Up @@ -249,7 +251,7 @@ TEST(ModulesTest, DynamicImportAsync) {
" mod = await import('foo'); \n"
" assert(mod.b() === 'b'); \n"
// Send a message to signify that we're done.
" Deno.core.send(new Uint8Array([4])); \n"
" Deno.core.send(42, new Uint8Array([4])); \n"
"})(); \n";
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, dyn_import_cb});
static deno_mod a = deno_mod_new(d, true, "a.js", src);
Expand Down Expand Up @@ -327,7 +329,7 @@ TEST(ModulesTest, DynamicImportThrows) {
"(async () => { \n"
" let mod = await import('b.js'); \n"
// unreachable
" Deno.core.send(new Uint8Array([4])); \n"
" Deno.core.send(42, new Uint8Array([4])); \n"
"})(); \n";
static deno_mod a = deno_mod_new(d, true, "a.js", a_src);
EXPECT_NE(a, 0);
Expand Down Expand Up @@ -401,7 +403,7 @@ TEST(ModulesTest, DynamicImportSyntaxError) {
"(async () => { \n"
" let mod = await import('b.js'); \n"
// unreachable
" Deno.core.send(new Uint8Array([4])); \n"
" Deno.core.send(42, new Uint8Array([4])); \n"
"})(); \n";
static deno_mod a = deno_mod_new(d, true, "a.js", src);
EXPECT_NE(a, 0);
Expand Down
3 changes: 2 additions & 1 deletion core/shared_queue.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ SharedQueue Binary Layout

function dispatch(control, zeroCopy = null) {
maybeInit();
return Deno.core.send(control, zeroCopy);
// TODO(ry) Replace 42 with actual op id.
return Deno.core.send(42, control, zeroCopy);
}

const denoCore = {
Expand Down

0 comments on commit 6c5d684

Please sign in to comment.