Skip to content

Commit

Permalink
minimal dispatch wip
Browse files Browse the repository at this point in the history
ry committed Mar 19, 2019
1 parent b61aa39 commit a2f67e6
Showing 3 changed files with 262 additions and 107 deletions.
113 changes: 99 additions & 14 deletions js/dispatch.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,86 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { window } from "./window";

import * as flatbuffers from "./flatbuffers";
import * as msg from "gen/msg_generated";
import * as errors from "./errors";
import * as util from "./util";
import { window } from "./window";

let nextCmdId = 0;
const DISPATCH_MINIMAL = 0xcafe;

let nextPromiseId = 0;
const promiseTable = new Map<number, util.Resolvable<msg.Base>>();
const promiseTable2 = new Map<number, util.Resolvable<number>>();

interface Record {
promiseId: number;
opId: number;
arg: number;
result: number;
base?: msg.Base;
}

function recordFromBuf(buf: Uint8Array): Record {
// assert(buf.byteLength % 4 == 0);
const buf32 = new Int32Array(buf.buffer, buf.byteOffset, buf.byteLength / 4);
if (buf32[0] == DISPATCH_MINIMAL) {
return {
promiseId: buf32[1],
opId: buf32[2],
arg: buf32[3],
result: buf32[4]
};
} else {
const bb = new flatbuffers.ByteBuffer(buf);
const base = msg.Base.getRootAsBase(bb);
const cmdId = base.cmdId();
return {
promiseId: cmdId,
arg: -1,
result: 0,
opId: -1,
base
};
}
}

export function handleAsyncMsgFromRust(ui8: Uint8Array): void {
const bb = new flatbuffers.ByteBuffer(ui8);
const base = msg.Base.getRootAsBase(bb);
const cmdId = base.cmdId();
const promise = promiseTable.get(cmdId);
util.assert(promise != null, `Expecting promise in table. ${cmdId}`);
promiseTable.delete(cmdId);
const err = errors.maybeError(base);
if (err != null) {
promise!.reject(err);
const record = recordFromBuf(ui8);

if (record.base) {
// Legacy
const { promiseId, base } = record;
const promise = promiseTable.get(promiseId);
util.assert(promise != null, `Expecting promise in table. ${promiseId}`);
promiseTable.delete(record.promiseId);
const err = errors.maybeError(base);
if (err != null) {
promise!.reject(err);
} else {
promise!.resolve(base);
}
} else {
promise!.resolve(base);
// Fast and new
util.log("minimal handleAsyncMsgFromRust ", ui8.length);
const { promiseId, result } = record;
const promise = promiseTable2.get(promiseId);
promiseTable2.delete(promiseId);
promise!.resolve(result);
}
}

function ui8FromArrayBufferView(abv: ArrayBufferView): Uint8Array {
return new Uint8Array(abv.buffer, abv.byteOffset, abv.byteLength);
}

function sendInternal(
builder: flatbuffers.Builder,
innerType: msg.Any,
inner: flatbuffers.Offset,
zeroCopy: undefined | ArrayBufferView,
sync = true
): [number, null | Uint8Array] {
const cmdId = nextCmdId++;
const cmdId = nextPromiseId++;
msg.Base.startBase(builder);
msg.Base.addInner(builder, inner);
msg.Base.addInnerType(builder, innerType);
@@ -39,7 +89,12 @@ function sendInternal(
builder.finish(msg.Base.endBase(builder));

const control = builder.asUint8Array();
const response = window.DenoCore.dispatch(control, zeroCopy);

//const response = DenoCore.dispatch(
const response = window.DenoCore.dispatch(
control,
zeroCopy ? ui8FromArrayBufferView(zeroCopy!) : undefined
);

builder.inUse = false;
return [cmdId, response];
@@ -65,6 +120,36 @@ export function sendAsync(
return promise;
}

const scratch32 = new Int32Array(5);
const scratchBytes = new Uint8Array(
scratch32.buffer,
scratch32.byteOffset,
scratch32.byteLength
);
util.assert(scratchBytes.byteLength === scratch32.length * 4);

export function sendAsync2(
opId: number,
arg: number,
zeroCopy: Uint8Array
): Promise<number> {
const promiseId = nextPromiseId++; // AKA cmdId

scratch32[0] = DISPATCH_MINIMAL;
scratch32[1] = promiseId;
scratch32[2] = opId;
scratch32[3] = arg;
// scratch32[4] = -1;

const promise = util.createResolvable<number>();
promiseTable2.set(promiseId, promise);

window.DenoCore.dispatch(scratchBytes, zeroCopy);

//DenoCore.dispatch(scratchBytes, zeroCopy);
return promise;
}

// @internal
export function sendSync(
builder: flatbuffers.Builder,
41 changes: 19 additions & 22 deletions js/files.ts
Original file line number Diff line number Diff line change
@@ -5,6 +5,9 @@ import * as msg from "gen/msg_generated";
import { assert } from "./util";
import * as flatbuffers from "./flatbuffers";

const OP_READ = 1;
const OP_WRITE = 2;

/** Open a file and return an instance of the `File` object.
*
* (async () => {
@@ -36,34 +39,28 @@ export async function open(
*
* Resolves with the `ReadResult` for the operation.
*/
export async function read(rid: number, p: Uint8Array): Promise<ReadResult> {
const builder = flatbuffers.createBuilder();
msg.Read.startRead(builder);
msg.Read.addRid(builder, rid);
const inner = msg.Read.endRead(builder);
const baseRes = await dispatch.sendAsync(builder, msg.Any.Read, inner, p);
assert(baseRes != null);
assert(msg.Any.ReadRes === baseRes!.innerType());
const res = new msg.ReadRes();
assert(baseRes!.inner(res) != null);
return { nread: res.nread(), eof: res.eof() };
export async function read(rid: number, ui8: Uint8Array): Promise<ReadResult> {
let result = await dispatch.sendAsync2(OP_READ, rid, ui8);
if (result < 0) {
throw new Error("read error");
} else if (result == 0) {
return { nread: 0, eof: true };
} else {
return { nread: result, eof: false };
}
}

/** Write to the file ID the contents of the array buffer.
*
* Resolves with the number of bytes written.
*/
export async function write(rid: number, p: Uint8Array): Promise<number> {
const builder = flatbuffers.createBuilder();
msg.Write.startWrite(builder);
msg.Write.addRid(builder, rid);
const inner = msg.Write.endWrite(builder);
const baseRes = await dispatch.sendAsync(builder, msg.Any.Write, inner, p);
assert(baseRes != null);
assert(msg.Any.WriteRes === baseRes!.innerType());
const res = new msg.WriteRes();
assert(baseRes!.inner(res) != null);
return res.nbyte();
export async function write(rid: number, ui8: Uint8Array): Promise<number> {
let result = await dispatch.sendAsync2(OP_WRITE, rid, ui8);
if (result < 0) {
throw new Error("write error");
} else {
return result;
}
}

/** Seek a file ID to the given offset under mode given by `whence`.
Loading

0 comments on commit a2f67e6

Please sign in to comment.