diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2019-08-24 13:20:48 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-24 13:20:48 -0700 |
commit | 2235dd795d3cc6c24ff1bdd1bbdcd110b4b0bdfc (patch) | |
tree | a5811adc062cbb1c66f05c863c9be245cf4fd2d2 /js | |
parent | bdc0a13261deaa3748f51d9948b4e7b92864c324 (diff) |
Revert json ops (#2814)
* Revert "port more ops to JSON (#2809)"
This reverts commit 137f33733d365026903d40e7cde6e34ac6c36dcf.
* Revert "port ops to JSON: compiler, errors, fetch, files (#2804)"
This reverts commit 79f82cf10ed1dbf91346994250d7311a4d74377a.
* Revert "Port rest of os ops to JSON (#2802)"
This reverts commit 5b2baa5c990fbeae747e952c5dcd7a5369e950b1.
Diffstat (limited to 'js')
-rw-r--r-- | js/compiler.ts | 56 | ||||
-rw-r--r-- | js/dispatch.ts | 52 | ||||
-rw-r--r-- | js/error_stack.ts | 51 | ||||
-rw-r--r-- | js/fetch.ts | 96 | ||||
-rw-r--r-- | js/files.ts | 52 | ||||
-rw-r--r-- | js/format_error.ts | 18 | ||||
-rw-r--r-- | js/get_random_values.ts | 18 | ||||
-rw-r--r-- | js/main.ts | 24 | ||||
-rw-r--r-- | js/metrics.ts | 27 | ||||
-rw-r--r-- | js/net.ts | 46 | ||||
-rw-r--r-- | js/os.ts | 63 | ||||
-rw-r--r-- | js/performance.ts | 18 | ||||
-rw-r--r-- | js/permissions.ts | 42 | ||||
-rw-r--r-- | js/process.ts | 132 | ||||
-rw-r--r-- | js/repl.ts | 30 | ||||
-rw-r--r-- | js/resources.ts | 20 | ||||
-rw-r--r-- | js/timers.ts | 14 | ||||
-rw-r--r-- | js/workers.ts | 89 |
18 files changed, 559 insertions, 289 deletions
diff --git a/js/compiler.ts b/js/compiler.ts index 5399d59ad..7519c5115 100644 --- a/js/compiler.ts +++ b/js/compiler.ts @@ -7,11 +7,9 @@ import { Console } from "./console"; import { core } from "./core"; import { Diagnostic, fromTypeScriptDiagnostic } from "./diagnostics"; import { cwd } from "./dir"; -import * as dispatch from "./dispatch"; -import { sendSync } from "./dispatch_json"; -import { msg } from "./dispatch_flatbuffers"; +import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; import * as os from "./os"; -import { TextEncoder } from "./text_encoding"; +import { TextDecoder, TextEncoder } from "./text_encoding"; import { getMappedModuleName, parseTypeDirectives } from "./type_directives"; import { assert, notImplemented } from "./util"; import * as util from "./util"; @@ -123,15 +121,35 @@ interface EmitResult { /** Ops to Rust to resolve and fetch a modules meta data. */ function fetchSourceFile(specifier: string, referrer: string): SourceFile { - util.log("compiler.fetchSourceFile", { specifier, referrer }); - const res = sendSync(dispatch.OP_FETCH_SOURCE_FILE, { - specifier, - referrer - }); - + util.log("fetchSourceFile", { specifier, referrer }); + // Send FetchSourceFile message + const builder = flatbuffers.createBuilder(); + const specifier_ = builder.createString(specifier); + const referrer_ = builder.createString(referrer); + const inner = msg.FetchSourceFile.createFetchSourceFile( + builder, + specifier_, + referrer_ + ); + const baseRes = sendSync(builder, msg.Any.FetchSourceFile, inner); + assert(baseRes != null); + assert( + msg.Any.FetchSourceFileRes === baseRes!.innerType(), + `base.innerType() unexpectedly is ${baseRes!.innerType()}` + ); + const fetchSourceFileRes = new msg.FetchSourceFileRes(); + assert(baseRes!.inner(fetchSourceFileRes) != null); + const dataArray = fetchSourceFileRes.dataArray(); + const decoder = new TextDecoder(); + const sourceCode = dataArray ? decoder.decode(dataArray) : undefined; + // flatbuffers returns `null` for an empty value, this does not fit well with + // idiomatic TypeScript under strict null checks, so converting to `undefined` return { - ...res, - typeDirectives: parseTypeDirectives(res.sourceCode) + moduleName: fetchSourceFileRes.moduleName() || undefined, + filename: fetchSourceFileRes.filename() || undefined, + mediaType: fetchSourceFileRes.mediaType(), + sourceCode, + typeDirectives: parseTypeDirectives(sourceCode) }; } @@ -153,7 +171,19 @@ function humanFileSize(bytes: number): string { /** Ops to rest for caching source map and compiled js */ function cache(extension: string, moduleId: string, contents: string): void { - sendSync(dispatch.OP_CACHE, { extension, moduleId, contents }); + util.log("cache", extension, moduleId); + const builder = flatbuffers.createBuilder(); + const extension_ = builder.createString(extension); + const moduleId_ = builder.createString(moduleId); + const contents_ = builder.createString(contents); + const inner = msg.Cache.createCache( + builder, + extension_, + moduleId_, + contents_ + ); + const baseRes = sendSync(builder, msg.Any.Cache, inner); + assert(baseRes == null); } const encoder = new TextEncoder(); diff --git a/js/dispatch.ts b/js/dispatch.ts index 6c7551441..0c5c59553 100644 --- a/js/dispatch.ts +++ b/js/dispatch.ts @@ -12,40 +12,6 @@ export const OP_IS_TTY = 4; export const OP_ENV = 5; export const OP_EXEC_PATH = 6; export const OP_UTIME = 7; -export const OP_SET_ENV = 8; -export const OP_HOME_DIR = 9; -export const OP_START = 10; -export const OP_APPLY_SOURCE_MAP = 11; -export const OP_FORMAT_ERROR = 12; -export const OP_CACHE = 13; -export const OP_FETCH_SOURCE_FILE = 14; -export const OP_OPEN = 15; -export const OP_CLOSE = 16; -export const OP_SEEK = 17; -export const OP_FETCH = 18; -export const OP_METRICS = 19; -export const OP_REPL_START = 20; -export const OP_REPL_READLINE = 21; -export const OP_ACCEPT = 22; -export const OP_DIAL = 23; -export const OP_SHUTDOWN = 24; -export const OP_LISTEN = 25; -export const OP_RESOURCES = 26; -export const OP_GET_RANDOM_VALUES = 27; -export const OP_GLOBAL_TIMER_STOP = 28; -export const OP_GLOBAL_TIMER = 29; -export const OP_NOW = 30; -export const OP_PERMISSIONS = 31; -export const OP_REVOKE_PERMISSION = 32; -export const OP_CREATE_WORKER = 33; -export const OP_HOST_GET_WORKER_CLOSED = 34; -export const OP_HOST_POST_MESSAGE = 35; -export const OP_HOST_GET_MESSAGE = 36; -export const OP_WORKER_POST_MESSAGE = 37; -export const OP_WORKER_GET_MESSAGE = 38; -export const OP_RUN = 39; -export const OP_RUN_STATUS = 40; -export const OP_KILL = 41; export function asyncMsgFromRust(opId: number, ui8: Uint8Array): void { switch (opId) { @@ -56,26 +22,10 @@ export function asyncMsgFromRust(opId: number, ui8: Uint8Array): void { case OP_READ: minimal.asyncMsgFromRust(opId, ui8); break; - case OP_EXIT: - case OP_IS_TTY: - case OP_ENV: - case OP_EXEC_PATH: case OP_UTIME: - case OP_OPEN: - case OP_SEEK: - case OP_FETCH: - case OP_REPL_START: - case OP_REPL_READLINE: - case OP_ACCEPT: - case OP_DIAL: - case OP_GLOBAL_TIMER: - case OP_HOST_GET_WORKER_CLOSED: - case OP_HOST_GET_MESSAGE: - case OP_WORKER_GET_MESSAGE: - case OP_RUN_STATUS: json.asyncMsgFromRust(opId, ui8); break; default: - throw Error("bad async opId"); + throw Error("bad opId"); } } diff --git a/js/error_stack.ts b/js/error_stack.ts index 7d41b9cf4..003717a72 100644 --- a/js/error_stack.ts +++ b/js/error_stack.ts @@ -1,8 +1,8 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. // Some of the code here is adapted directly from V8 and licensed under a BSD // style license available here: https://github.com/v8/v8/blob/24886f2d1c565287d33d71e4109a53bf0b54b75c/LICENSE.v8 -import * as dispatch from "./dispatch"; -import { sendSync } from "./dispatch_json"; + +import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { assert } from "./util"; export interface Location { @@ -17,6 +17,40 @@ export interface Location { column: number; } +function req( + filename: string, + line: number, + column: number +): [flatbuffers.Builder, msg.Any.ApplySourceMap, flatbuffers.Offset] { + const builder = flatbuffers.createBuilder(); + const filename_ = builder.createString(filename); + const inner = msg.ApplySourceMap.createApplySourceMap( + builder, + filename_, + // On this side, line/column are 1 based, but in the source maps, they are + // 0 based, so we have to convert back and forth + line - 1, + column - 1 + ); + return [builder, msg.Any.ApplySourceMap, inner]; +} + +function res(baseRes: msg.Base | null): Location { + assert(baseRes != null); + assert(baseRes!.innerType() === msg.Any.ApplySourceMap); + const res = new msg.ApplySourceMap(); + assert(baseRes!.inner(res) != null); + const filename = res.filename()!; + assert(filename != null); + return { + filename, + // On this side, line/column are 1 based, but in the source maps, they are + // 0 based, so we have to convert back and forth + line: res.line() + 1, + column: res.column() + 1 + }; +} + /** Given a current location in a module, lookup the source location and * return it. * @@ -41,18 +75,7 @@ export interface Location { */ export function applySourceMap(location: Location): Location { const { filename, line, column } = location; - // On this side, line/column are 1 based, but in the source maps, they are - // 0 based, so we have to convert back and forth - const res = sendSync(dispatch.OP_APPLY_SOURCE_MAP, { - filename, - line: line - 1, - column: column - 1 - }); - return { - filename: res.filename, - line: res.line + 1, - column: res.column + 1 - }; + return res(sendSync(...req(filename, line, column))); } /** Mutate the call site so that it returns the location, instead of its diff --git a/js/fetch.ts b/js/fetch.ts index 317239630..505da218c 100644 --- a/js/fetch.ts +++ b/js/fetch.ts @@ -1,5 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. import { assert, createResolvable, notImplemented, isTypedArray } from "./util"; +import { sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; import * as domTypes from "./dom_types"; import { TextDecoder, TextEncoder } from "./text_encoding"; import { DenoBlob, bytesSymbol as blobBytesSymbol } from "./blob"; @@ -9,8 +10,6 @@ import { read, close } from "./files"; import { Buffer } from "./buffer"; import { FormData } from "./form_data"; import { URLSearchParams } from "./url_search_params"; -import * as dispatch from "./dispatch"; -import { sendAsync } from "./dispatch_json"; function getHeaderValueParams(value: string): Map<string, string> { const params = new Map(); @@ -321,35 +320,67 @@ export class Response implements domTypes.Response { } } -interface FetchResponse { - bodyRid: number; - status: number; - headers: Array<[string, string]>; -} - -async function sendFetchReq( +function msgHttpRequest( + builder: flatbuffers.Builder, url: string, - method: string | null, - headers: domTypes.Headers | null, - body: ArrayBufferView | undefined -): Promise<FetchResponse> { - let headerArray: Array<[string, string]> = []; + method: null | string, + headers: null | domTypes.Headers +): flatbuffers.Offset { + const methodOffset = !method ? 0 : builder.createString(method); + let fieldsOffset: flatbuffers.Offset = 0; + const urlOffset = builder.createString(url); if (headers) { - headerArray = Array.from(headers.entries()); + const kvOffsets: flatbuffers.Offset[] = []; + for (const [key, val] of headers.entries()) { + const keyOffset = builder.createString(key); + const valOffset = builder.createString(val); + kvOffsets.push( + msg.KeyValue.createKeyValue(builder, keyOffset, valOffset) + ); + } + fieldsOffset = msg.HttpHeader.createFieldsVector(builder, kvOffsets); + } else { } + return msg.HttpHeader.createHttpHeader( + builder, + true, + methodOffset, + urlOffset, + 0, + fieldsOffset + ); +} - let zeroCopy = undefined; - if (body) { - zeroCopy = new Uint8Array(body.buffer, body.byteOffset, body.byteLength); +function deserializeHeaderFields(m: msg.HttpHeader): Array<[string, string]> { + const out: Array<[string, string]> = []; + for (let i = 0; i < m.fieldsLength(); i++) { + const item = m.fields(i)!; + out.push([item.key()!, item.value()!]); } + return out; +} - const args = { - method, - url, - headers: headerArray - }; - - return (await sendAsync(dispatch.OP_FETCH, args, zeroCopy)) as FetchResponse; +async function getFetchRes( + url: string, + method: string | null, + headers: domTypes.Headers | null, + body: ArrayBufferView | undefined +): Promise<msg.FetchRes> { + // Send Fetch message + const builder = flatbuffers.createBuilder(); + const headerOff = msgHttpRequest(builder, url, method, headers); + const resBase = await sendAsync( + builder, + msg.Any.Fetch, + msg.Fetch.createFetch(builder, headerOff), + body + ); + + // Decode FetchRes + assert(msg.Any.FetchRes === resBase.innerType()); + const inner = new msg.FetchRes(); + assert(resBase.inner(inner) != null); + return inner; } /** Fetch a resource from the network. */ @@ -417,13 +448,20 @@ export async function fetch( } while (remRedirectCount) { - const fetchResponse = await sendFetchReq(url, method, headers, body); + const inner = await getFetchRes(url, method, headers, body); + + const header = inner.header()!; + const bodyRid = inner.bodyRid(); + assert(!header.isRequest()); + const status = header.status(); + + const headersList = deserializeHeaderFields(header); const response = new Response( url, - fetchResponse.status, - fetchResponse.headers, - fetchResponse.bodyRid, + status, + headersList, + bodyRid, redirected ); if ([301, 302, 303, 307, 308].includes(response.status)) { diff --git a/js/files.ts b/js/files.ts index 4eff17aac..6f0e523c9 100644 --- a/js/files.ts +++ b/js/files.ts @@ -12,22 +12,37 @@ import { } from "./io"; import { sendAsyncMinimal } from "./dispatch_minimal"; import { assert } from "./util"; -import * as dispatch from "./dispatch"; -import { - sendSync as sendSyncJson, - sendAsync as sendAsyncJson -} from "./dispatch_json"; -import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; +import { sendAsync, sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { OP_READ, OP_WRITE } from "./dispatch"; +function reqOpen( + filename: string, + mode: OpenMode +): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { + const builder = flatbuffers.createBuilder(); + const filename_ = builder.createString(filename); + const mode_ = builder.createString(mode); + const inner = msg.Open.createOpen(builder, filename_, 0, mode_); + return [builder, msg.Any.Open, inner]; +} + +function resOpen(baseRes: null | msg.Base): File { + assert(baseRes != null); + assert(msg.Any.OpenRes === baseRes!.innerType()); + const res = new msg.OpenRes(); + assert(baseRes!.inner(res) != null); + const rid = res.rid(); + // eslint-disable-next-line @typescript-eslint/no-use-before-define + return new File(rid); +} + /** Open a file and return an instance of the `File` object * synchronously. * * const file = Deno.openSync("/foo/bar.txt"); */ export function openSync(filename: string, mode: OpenMode = "r"): File { - const rid = sendSyncJson(dispatch.OP_OPEN, { filename, mode }); - return new File(rid); + return resOpen(sendSync(...reqOpen(filename, mode))); } /** Open a file and return an instance of the `File` object. @@ -40,8 +55,7 @@ export async function open( filename: string, mode: OpenMode = "r" ): Promise<File> { - const rid = await sendAsyncJson(dispatch.OP_OPEN, { filename, mode }); - return new File(rid); + return resOpen(await sendAsync(...reqOpen(filename, mode))); } function reqRead( @@ -151,13 +165,23 @@ export async function write(rid: number, p: Uint8Array): Promise<number> { } } +function reqSeek( + rid: number, + offset: number, + whence: SeekMode +): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { + const builder = flatbuffers.createBuilder(); + const inner = msg.Seek.createSeek(builder, rid, offset, whence); + return [builder, msg.Any.Seek, inner]; +} + /** Seek a file ID synchronously to the given offset under mode given by `whence`. * * const file = Deno.openSync("/foo/bar.txt"); * Deno.seekSync(file.rid, 0, 0); */ export function seekSync(rid: number, offset: number, whence: SeekMode): void { - sendSyncJson(dispatch.OP_SEEK, { rid, offset, whence }); + sendSync(...reqSeek(rid, offset, whence)); } /** Seek a file ID to the given offset under mode given by `whence`. @@ -172,12 +196,14 @@ export async function seek( offset: number, whence: SeekMode ): Promise<void> { - await sendAsyncJson(dispatch.OP_SEEK, { rid, offset, whence }); + await sendAsync(...reqSeek(rid, offset, whence)); } /** Close the file ID. */ export function close(rid: number): void { - sendSyncJson(dispatch.OP_CLOSE, { rid }); + const builder = flatbuffers.createBuilder(); + const inner = msg.Close.createClose(builder, rid); + sendSync(builder, msg.Any.Close, inner); } /** The Deno abstraction for reading and writing files. */ diff --git a/js/format_error.ts b/js/format_error.ts index dde0f6a58..6670b05e2 100644 --- a/js/format_error.ts +++ b/js/format_error.ts @@ -1,9 +1,17 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as dispatch from "./dispatch"; -import { sendSync } from "./dispatch_json"; +import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; +import { assert } from "./util"; -// TODO(bartlomieju): move to `repl.ts`? export function formatError(errString: string): string { - const res = sendSync(dispatch.OP_FORMAT_ERROR, { error: errString }); - return res.error; + const builder = flatbuffers.createBuilder(); + const errString_ = builder.createString(errString); + const offset = msg.FormatError.createFormatError(builder, errString_); + const baseRes = sendSync(builder, msg.Any.FormatError, offset); + assert(baseRes != null); + assert(msg.Any.FormatErrorRes === baseRes!.innerType()); + const formatErrorResMsg = new msg.FormatErrorRes(); + assert(baseRes!.inner(formatErrorResMsg) != null); + const formattedError = formatErrorResMsg.error(); + assert(formatError != null); + return formattedError!; } diff --git a/js/get_random_values.ts b/js/get_random_values.ts index 154e77f75..d5c0828c5 100644 --- a/js/get_random_values.ts +++ b/js/get_random_values.ts @@ -1,8 +1,15 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as dispatch from "./dispatch"; -import { sendSync } from "./dispatch_json"; +import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { assert } from "./util"; +function req( + typedArray: ArrayBufferView +): [flatbuffers.Builder, msg.Any, flatbuffers.Offset, ArrayBufferView] { + const builder = flatbuffers.createBuilder(); + const inner = msg.GetRandomValues.createGetRandomValues(builder); + return [builder, msg.Any.GetRandomValues, inner, typedArray]; +} + /** Synchronously collects cryptographically secure random values. The * underlying CSPRNG in use is Rust's `rand::rngs::ThreadRng`. * @@ -21,11 +28,6 @@ export function getRandomValues< >(typedArray: T): T { assert(typedArray !== null, "Input must not be null"); assert(typedArray.length <= 65536, "Input must not be longer than 65536"); - const ui8 = new Uint8Array( - typedArray.buffer, - typedArray.byteOffset, - typedArray.byteLength - ); - sendSync(dispatch.OP_GET_RANDOM_VALUES, {}, ui8); + sendSync(...req(typedArray as ArrayBufferView)); return typedArray; } diff --git a/js/main.ts b/js/main.ts index 25e27b69f..769f522a6 100644 --- a/js/main.ts +++ b/js/main.ts @@ -22,12 +22,12 @@ export default function denoMain( preserveDenoNamespace: boolean = true, name?: string ): void { - const s = os.start(preserveDenoNamespace, name); + const startResMsg = os.start(preserveDenoNamespace, name); - setVersions(s.denoVersion, s.v8Version); + setVersions(startResMsg.denoVersion()!, startResMsg.v8Version()!); // handle `--version` - if (s.versionFlag) { + if (startResMsg.versionFlag()) { console.log("deno:", deno.version.deno); console.log("v8:", deno.version.v8); console.log("typescript:", deno.version.typescript); @@ -36,22 +36,24 @@ export default function denoMain( setPrepareStackTrace(Error); - if (s.mainModule) { - assert(s.mainModule.length > 0); - setLocation(s.mainModule); + const mainModule = startResMsg.mainModule(); + if (mainModule) { + assert(mainModule.length > 0); + setLocation(mainModule); } - log("cwd", s.cwd); + const cwd = startResMsg.cwd(); + log("cwd", cwd); - for (let i = 1; i < s.argv.length; i++) { - args.push(s.argv[i]); + for (let i = 1; i < startResMsg.argvLength(); i++) { + args.push(startResMsg.argv(i)); } log("args", args); Object.freeze(args); if (window["_xevalWrapper"] !== undefined) { - xevalMain(window["_xevalWrapper"] as XevalFunc, s.xevalDelim); - } else if (!s.mainModule) { + xevalMain(window["_xevalWrapper"] as XevalFunc, startResMsg.xevalDelim()); + } else if (!mainModule) { replLoop(); } } diff --git a/js/metrics.ts b/js/metrics.ts index 48e3102e5..e93e9528c 100644 --- a/js/metrics.ts +++ b/js/metrics.ts @@ -1,6 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as dispatch from "./dispatch"; -import { sendSync } from "./dispatch_json"; +import { assert } from "./util"; +import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; export interface Metrics { opsDispatched: number; @@ -10,6 +10,27 @@ export interface Metrics { bytesReceived: number; } +function req(): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { + const builder = flatbuffers.createBuilder(); + const inner = msg.Metrics.createMetrics(builder); + return [builder, msg.Any.Metrics, inner]; +} + +function res(baseRes: null | msg.Base): Metrics { + assert(baseRes !== null); + assert(msg.Any.MetricsRes === baseRes!.innerType()); + const res = new msg.MetricsRes(); + assert(baseRes!.inner(res) !== null); + + return { + opsDispatched: res.opsDispatched().toFloat64(), + opsCompleted: res.opsCompleted().toFloat64(), + bytesSentControl: res.bytesSentControl().toFloat64(), + bytesSentData: res.bytesSentData().toFloat64(), + bytesReceived: res.bytesReceived().toFloat64() + }; +} + /** Receive metrics from the privileged side of Deno. * * > console.table(Deno.metrics()) @@ -24,5 +45,5 @@ export interface Metrics { * └──────────────────┴────────┘ */ export function metrics(): Metrics { - return sendSync(dispatch.OP_METRICS); + return res(sendSync(...req())); } @@ -1,9 +1,8 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. import { EOF, Reader, Writer, Closer } from "./io"; -import { notImplemented } from "./util"; +import { assert, notImplemented } from "./util"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { read, write, close } from "./files"; -import * as dispatch from "./dispatch"; -import { sendSync, sendAsync } from "./dispatch_json"; export type Network = "tcp"; // TODO support other types: @@ -37,7 +36,10 @@ enum ShutdownMode { } function shutdown(rid: number, how: ShutdownMode): void { - sendSync(dispatch.OP_SHUTDOWN, { rid, how }); + const builder = flatbuffers.createBuilder(); + const inner = msg.Shutdown.createShutdown(builder, rid, how); + const baseRes = sendSync(builder, msg.Any.Shutdown, inner); + assert(baseRes == null); } class ConnImpl implements Conn { @@ -78,9 +80,14 @@ class ListenerImpl implements Listener { constructor(readonly rid: number) {} async accept(): Promise<Conn> { - const res = await sendAsync(dispatch.OP_ACCEPT, { rid: this.rid }); - // TODO(bartlomieju): add remoteAddr and localAddr on Rust side - return new ConnImpl(res.rid, res.remoteAddr!, res.localAddr!); + const builder = flatbuffers.createBuilder(); + const inner = msg.Accept.createAccept(builder, this.rid); + const baseRes = await sendAsync(builder, msg.Any.Accept, inner); + assert(baseRes != null); + assert(msg.Any.NewConn === baseRes!.innerType()); + const res = new msg.NewConn(); + assert(baseRes!.inner(res) != null); + return new ConnImpl(res.rid(), res.remoteAddr()!, res.localAddr()!); } close(): void { @@ -136,8 +143,16 @@ export interface Conn extends Reader, Writer, Closer { * See `dial()` for a description of the network and address parameters. */ export function listen(network: Network, address: string): Listener { - const rid = sendSync(dispatch.OP_LISTEN, { network, address }); - return new ListenerImpl(rid); + const builder = flatbuffers.createBuilder(); + const network_ = builder.createString(network); + const address_ = builder.createString(address); + const inner = msg.Listen.createListen(builder, network_, address_); + const baseRes = sendSync(builder, msg.Any.Listen, inner); + assert(baseRes != null); + assert(msg.Any.ListenRes === baseRes!.innerType()); + const res = new msg.ListenRes(); + assert(baseRes!.inner(res) != null); + return new ListenerImpl(res.rid()); } /** Dial connects to the address on the named network. @@ -168,9 +183,16 @@ export function listen(network: Network, address: string): Listener { * dial("tcp", ":80") */ export async function dial(network: Network, address: string): Promise<Conn> { - const res = await sendAsync(dispatch.OP_DIAL, { network, address }); - // TODO(bartlomieju): add remoteAddr and localAddr on Rust side - return new ConnImpl(res.rid, res.remoteAddr!, res.localAddr!); + const builder = flatbuffers.createBuilder(); + const network_ = builder.createString(network); + const address_ = builder.createString(address); + const inner = msg.Dial.createDial(builder, network_, address_); + const baseRes = await sendAsync(builder, msg.Any.Dial, inner); + assert(baseRes != null); + assert(msg.Any.NewConn === baseRes!.innerType()); + const res = new msg.NewConn(); + assert(baseRes!.inner(res) != null); + return new ConnImpl(res.rid(), res.remoteAddr()!, res.localAddr()!); } /** **RESERVED** */ @@ -1,7 +1,8 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. import { core } from "./core"; import * as dispatch from "./dispatch"; -import { sendSync } from "./dispatch_json"; +import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; +import * as dispatchJson from "./dispatch_json"; import { assert } from "./util"; import * as util from "./util"; import { window } from "./window"; @@ -23,17 +24,21 @@ function setGlobals(pid_: number, noColor_: boolean): void { * console.log(Deno.isTTY().stdout); */ export function isTTY(): { stdin: boolean; stdout: boolean; stderr: boolean } { - return sendSync(dispatch.OP_IS_TTY); + return dispatchJson.sendSync(dispatch.OP_IS_TTY); } /** Exit the Deno process with optional exit code. */ export function exit(code = 0): never { - sendSync(dispatch.OP_EXIT, { code }); + dispatchJson.sendSync(dispatch.OP_EXIT, { code }); return util.unreachable(); } function setEnv(key: string, value: string): void { - sendSync(dispatch.OP_SET_ENV, { key, value }); + const builder = flatbuffers.createBuilder(); + const key_ = builder.createString(key); + const value_ = builder.createString(value); + const inner = msg.SetEnv.createSetEnv(builder, key_, value_); + sendSync(builder, msg.Any.SetEnv, inner); } /** Returns a snapshot of the environment variables at invocation. Mutating a @@ -48,7 +53,7 @@ function setEnv(key: string, value: string): void { * console.log(myEnv.TEST_VAR == newEnv.TEST_VAR); */ export function env(): { [index: string]: string } { - const env = sendSync(dispatch.OP_ENV); + const env = dispatchJson.sendSync(dispatch.OP_ENV); return new Proxy(env, { set(obj, prop: string, value: string): boolean { setEnv(prop, value); @@ -57,35 +62,35 @@ export function env(): { [index: string]: string } { }); } -interface Start { - cwd: string; - pid: number; - argv: string[]; - mainModule: string; // Absolute URL. - debugFlag: boolean; - depsFlag: boolean; - typesFlag: boolean; - versionFlag: boolean; - denoVersion: string; - v8Version: string; - noColor: boolean; - xevalDelim: string; +/** Send to the privileged side that we have setup and are ready. */ +function sendStart(): msg.StartRes { + const builder = flatbuffers.createBuilder(); + const startOffset = msg.Start.createStart(builder, 0 /* unused */); + const baseRes = sendSync(builder, msg.Any.Start, startOffset); + assert(baseRes != null); + assert(msg.Any.StartRes === baseRes!.innerType()); + const startResMsg = new msg.StartRes(); + assert(baseRes!.inner(startResMsg) != null); + return startResMsg; } // This function bootstraps an environment within Deno, it is shared both by // the runtime and the compiler environments. // @internal -export function start(preserveDenoNamespace = true, source?: string): Start { +export function start( + preserveDenoNamespace = true, + source?: string +): msg.StartRes { core.setAsyncHandler(dispatch.asyncMsgFromRust); // First we send an empty `Start` message to let the privileged side know we // are ready. The response should be a `StartRes` message containing the CLI // args and other info. - const s = sendSync(dispatch.OP_START); + const startResMsg = sendStart(); - util.setLogDebug(s.debugFlag, source); + util.setLogDebug(startResMsg.debugFlag(), source); - setGlobals(s.pid, s.noColor); + setGlobals(startResMsg.pid(), startResMsg.noColor()); if (preserveDenoNamespace) { util.immutableDefine(window, "Deno", window.Deno); @@ -100,7 +105,7 @@ export function start(preserveDenoNamespace = true, source?: string): Start { assert(window.Deno === undefined); } - return s; + return startResMsg; } /** @@ -108,10 +113,18 @@ export function start(preserveDenoNamespace = true, source?: string): Start { * Requires the `--allow-env` flag. */ export function homeDir(): string { - const path = sendSync(dispatch.OP_HOME_DIR); + const builder = flatbuffers.createBuilder(); + const inner = msg.HomeDir.createHomeDir(builder); + const baseRes = sendSync(builder, msg.Any.HomeDir, inner)!; + assert(msg.Any.HomeDirRes === baseRes.innerType()); + const res = new msg.HomeDirRes(); + assert(baseRes.inner(res) != null); + const path = res.path(); + if (!path) { throw new Error("Could not get home directory."); } + return path; } @@ -120,5 +133,5 @@ export function homeDir(): string { * Requires the `--allow-env` flag. */ export function execPath(): string { - return sendSync(dispatch.OP_EXEC_PATH); + return dispatchJson.sendSync(dispatch.OP_EXEC_PATH); } diff --git a/js/performance.ts b/js/performance.ts index d2f339c46..7aaa7ae45 100644 --- a/js/performance.ts +++ b/js/performance.ts @@ -1,11 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as dispatch from "./dispatch"; -import { sendSync } from "./dispatch_json"; - -interface NowResponse { - seconds: number; - subsecNanos: number; -} +import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; +import { assert } from "./util"; export class Performance { /** Returns a current time from Deno's start in milliseconds. @@ -16,7 +11,12 @@ export class Performance { * console.log(`${t} ms since start!`); */ now(): number { - const res = sendSync(dispatch.OP_NOW) as NowResponse; - return res.seconds * 1e3 + res.subsecNanos / 1e6; + const builder = flatbuffers.createBuilder(); + const inner = msg.Now.createNow(builder); + const baseRes = sendSync(builder, msg.Any.Now, inner)!; + assert(msg.Any.NowRes === baseRes.innerType()); + const res = new msg.NowRes(); + assert(baseRes.inner(res) != null); + return res.seconds().toFloat64() * 1e3 + res.subsecNanos() / 1e6; } } diff --git a/js/permissions.ts b/js/permissions.ts index bc969f3a8..822ae8cbd 100644 --- a/js/permissions.ts +++ b/js/permissions.ts @@ -1,6 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as dispatch from "./dispatch"; -import { sendSync } from "./dispatch_json"; +import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; +import { assert } from "./util"; /** Permissions as granted by the caller */ export interface Permissions { @@ -15,6 +15,23 @@ export interface Permissions { export type Permission = keyof Permissions; +function getReq(): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { + const builder = flatbuffers.createBuilder(); + const inner = msg.Permissions.createPermissions(builder); + return [builder, msg.Any.Permissions, inner]; +} + +function createPermissions(inner: msg.PermissionsRes): Permissions { + return { + read: inner.read(), + write: inner.write(), + net: inner.net(), + env: inner.env(), + run: inner.run(), + hrtime: inner.hrtime() + }; +} + /** Inspect granted permissions for the current program. * * if (Deno.permissions().read) { @@ -23,7 +40,24 @@ export type Permission = keyof Permissions; * } */ export function permissions(): Permissions { - return sendSync(dispatch.OP_PERMISSIONS) as Permissions; + const baseRes = sendSync(...getReq())!; + assert(msg.Any.PermissionsRes === baseRes.innerType()); + const res = new msg.PermissionsRes(); + assert(baseRes.inner(res) != null); + // TypeScript cannot track assertion above, therefore not null assertion + return createPermissions(res); +} + +function revokeReq( + permission: string +): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { + const builder = flatbuffers.createBuilder(); + const permission_ = builder.createString(permission); + const inner = msg.PermissionRevoke.createPermissionRevoke( + builder, + permission_ + ); + return [builder, msg.Any.PermissionRevoke, inner]; } /** Revoke a permission. When the permission was already revoked nothing changes @@ -35,5 +69,5 @@ export function permissions(): Permissions { * Deno.readFile("example.test"); // -> error or permission prompt */ export function revokePermission(permission: Permission): void { - sendSync(dispatch.OP_REVOKE_PERMISSION, { permission }); + sendSync(...revokeReq(permission)); } diff --git a/js/process.ts b/js/process.ts index dd4f70103..b2b6d4734 100644 --- a/js/process.ts +++ b/js/process.ts @@ -1,6 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync } from "./dispatch_json"; -import * as dispatch from "./dispatch"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; + import { File, close } from "./files"; import { ReadCloser, WriteCloser } from "./io"; import { readAll } from "./buffer"; @@ -31,22 +31,21 @@ export interface RunOptions { stdin?: ProcessStdio | number; } -interface RunStatusResponse { - gotSignal: boolean; - exitCode: number; - exitSignal: number; -} - async function runStatus(rid: number): Promise<ProcessStatus> { - const res = (await sendAsync(dispatch.OP_RUN_STATUS, { - rid - })) as RunStatusResponse; + const builder = flatbuffers.createBuilder(); + const inner = msg.RunStatus.createRunStatus(builder, rid); - if (res.gotSignal) { - const signal = res.exitSignal; + const baseRes = await sendAsync(builder, msg.Any.RunStatus, inner); + assert(baseRes != null); + assert(msg.Any.RunStatusRes === baseRes!.innerType()); + const res = new msg.RunStatusRes(); + assert(baseRes!.inner(res) != null); + + if (res.gotSignal()) { + const signal = res.exitSignal(); return { signal, success: false }; } else { - const code = res.exitCode; + const code = res.exitCode(); return { code, success: code === 0 }; } } @@ -57,7 +56,9 @@ async function runStatus(rid: number): Promise<ProcessStatus> { * Requires the `--allow-run` flag. */ export function kill(pid: number, signo: number): void { - sendSync(dispatch.OP_KILL, { pid, signo }); + const builder = flatbuffers.createBuilder(); + const inner = msg.Kill.createKill(builder, pid, signo); + sendSync(builder, msg.Any.Kill, inner); } export class Process { @@ -68,20 +69,20 @@ export class Process { readonly stderr?: ReadCloser; // @internal - constructor(res: RunResponse) { - this.rid = res.rid; - this.pid = res.pid; + constructor(res: msg.RunRes) { + this.rid = res.rid(); + this.pid = res.pid(); - if (res.stdinRid && res.stdinRid > 0) { - this.stdin = new File(res.stdinRid); + if (res.stdinRid() > 0) { + this.stdin = new File(res.stdinRid()); } - if (res.stdoutRid && res.stdoutRid > 0) { - this.stdout = new File(res.stdoutRid); + if (res.stdoutRid() > 0) { + this.stdout = new File(res.stdoutRid()); } - if (res.stderrRid && res.stderrRid > 0) { - this.stderr = new File(res.stderrRid); + if (res.stderrRid() > 0) { + this.stderr = new File(res.stderrRid()); } } @@ -134,13 +135,14 @@ export interface ProcessStatus { signal?: number; // TODO: Make this a string, e.g. 'SIGTERM'. } -// TODO: this method is only used to validate proper option, probably can be renamed -function stdioMap(s: string): string { +function stdioMap(s: ProcessStdio): msg.ProcessStdio { switch (s) { case "inherit": + return msg.ProcessStdio.Inherit; case "piped": + return msg.ProcessStdio.Piped; case "null": - return s; + return msg.ProcessStdio.Null; default: return unreachable(); } @@ -150,13 +152,6 @@ function isRid(arg: unknown): arg is number { return !isNaN(arg as number); } -interface RunResponse { - rid: number; - pid: number; - stdinRid: number | null; - stdoutRid: number | null; - stderrRid: number | null; -} /** * Spawns new subprocess. * @@ -171,56 +166,71 @@ interface RunResponse { * they can be set to either `ProcessStdio` or `rid` of open file. */ export function run(opt: RunOptions): Process { - assert(opt.args.length > 0); - let env: Array<[string, string]> = []; + const builder = flatbuffers.createBuilder(); + const argsOffset = msg.Run.createArgsVector( + builder, + opt.args.map((a): number => builder.createString(a)) + ); + const cwdOffset = opt.cwd == null ? 0 : builder.createString(opt.cwd); + const kvOffset: flatbuffers.Offset[] = []; if (opt.env) { - env = Array.from(Object.entries(opt.env)); + for (const [key, val] of Object.entries(opt.env)) { + const keyOffset = builder.createString(key); + const valOffset = builder.createString(String(val)); + kvOffset.push(msg.KeyValue.createKeyValue(builder, keyOffset, valOffset)); + } } + const envOffset = msg.Run.createEnvVector(builder, kvOffset); - let stdin = stdioMap("inherit"); - let stdout = stdioMap("inherit"); - let stderr = stdioMap("inherit"); - let stdinRid = 0; - let stdoutRid = 0; - let stderrRid = 0; + let stdInOffset = stdioMap("inherit"); + let stdOutOffset = stdioMap("inherit"); + let stdErrOffset = stdioMap("inherit"); + let stdinRidOffset = 0; + let stdoutRidOffset = 0; + let stderrRidOffset = 0; if (opt.stdin) { if (isRid(opt.stdin)) { - stdinRid = opt.stdin; + stdinRidOffset = opt.stdin; } else { - stdin = stdioMap(opt.stdin); + stdInOffset = stdioMap(opt.stdin); } } if (opt.stdout) { if (isRid(opt.stdout)) { - stdoutRid = opt.stdout; + stdoutRidOffset = opt.stdout; } else { - stdout = stdioMap(opt.stdout); + stdOutOffset = stdioMap(opt.stdout); } } if (opt.stderr) { if (isRid(opt.stderr)) { - stderrRid = opt.stderr; + stderrRidOffset = opt.stderr; } else { - stderr = stdioMap(opt.stderr); + stdErrOffset = stdioMap(opt.stderr); } } - const req = { - args: opt.args.map(String), - cwd: opt.cwd, - env, - stdin, - stdout, - stderr, - stdinRid, - stdoutRid, - stderrRid - }; + const inner = msg.Run.createRun( + builder, + argsOffset, + cwdOffset, + envOffset, + stdInOffset, + stdOutOffset, + stdErrOffset, + stdinRidOffset, + stdoutRidOffset, + stderrRidOffset + ); + const baseRes = sendSync(builder, msg.Any.Run, inner); + assert(baseRes != null); + assert(msg.Any.RunRes === baseRes!.innerType()); + const res = new msg.RunRes(); + assert(baseRes!.inner(res) != null); - const res = sendSync(dispatch.OP_RUN, req) as RunResponse; return new Process(res); } diff --git a/js/repl.ts b/js/repl.ts index ac6700657..c971e4420 100644 --- a/js/repl.ts +++ b/js/repl.ts @@ -1,12 +1,12 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +import { assert } from "./util"; import { close } from "./files"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { exit } from "./os"; import { window } from "./window"; import { core } from "./core"; import { formatError } from "./format_error"; import { stringifyArgs } from "./console"; -import * as dispatch from "./dispatch"; -import { sendSync, sendAsync } from "./dispatch_json"; /** * REPL logging. @@ -43,12 +43,34 @@ const replCommands = { }; function startRepl(historyFile: string): number { - return sendSync(dispatch.OP_REPL_START, { historyFile }); + const builder = flatbuffers.createBuilder(); + const historyFile_ = builder.createString(historyFile); + const inner = msg.ReplStart.createReplStart(builder, historyFile_); + + const baseRes = sendSync(builder, msg.Any.ReplStart, inner); + assert(baseRes != null); + assert(msg.Any.ReplStartRes === baseRes!.innerType()); + const innerRes = new msg.ReplStartRes(); + assert(baseRes!.inner(innerRes) != null); + const rid = innerRes.rid(); + return rid; } // @internal export async function readline(rid: number, prompt: string): Promise<string> { - return sendAsync(dispatch.OP_REPL_READLINE, { rid, prompt }); + const builder = flatbuffers.createBuilder(); + const prompt_ = builder.createString(prompt); + const inner = msg.ReplReadline.createReplReadline(builder, rid, prompt_); + + const baseRes = await sendAsync(builder, msg.Any.ReplReadline, inner); + + assert(baseRes != null); + assert(msg.Any.ReplReadlineRes === baseRes!.innerType()); + const innerRes = new msg.ReplReadlineRes(); + assert(baseRes!.inner(innerRes) != null); + const line = innerRes.line(); + assert(line !== null); + return line || ""; } // Error messages that allow users to continue input diff --git a/js/resources.ts b/js/resources.ts index 6e2ec202b..49093fab1 100644 --- a/js/resources.ts +++ b/js/resources.ts @@ -1,6 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as dispatch from "./dispatch"; -import { sendSync } from "./dispatch_json"; +import { assert } from "./util"; +import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; export interface ResourceMap { [rid: number]: string; @@ -10,10 +10,20 @@ export interface ResourceMap { * representation. */ export function resources(): ResourceMap { - const res = sendSync(dispatch.OP_RESOURCES) as Array<[number, string]>; + const builder = flatbuffers.createBuilder(); + const inner = msg.Resource.createResource(builder, 0, 0); + const baseRes = sendSync(builder, msg.Any.Resources, inner); + assert(baseRes !== null); + assert(msg.Any.ResourcesRes === baseRes!.innerType()); + const res = new msg.ResourcesRes(); + assert(baseRes!.inner(res) !== null); + const resources: ResourceMap = {}; - for (const resourceTuple of res) { - resources[resourceTuple[0]] = resourceTuple[1]; + + for (let i = 0; i < res.resourcesLength(); i++) { + const item = res.resources(i)!; + resources[item.rid()!] = item.repr()!; } + return resources; } diff --git a/js/timers.ts b/js/timers.ts index 079e779c4..cb0fd531c 100644 --- a/js/timers.ts +++ b/js/timers.ts @@ -1,8 +1,7 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. import { assert } from "./util"; +import { sendAsync, sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { window } from "./window"; -import * as dispatch from "./dispatch"; -import { sendSync, sendAsync } from "./dispatch_json"; interface Timer { id: number; @@ -38,8 +37,11 @@ function getTime(): number { } function clearGlobalTimeout(): void { + const builder = flatbuffers.createBuilder(); + const inner = msg.GlobalTimerStop.createGlobalTimerStop(builder); globalTimeoutDue = null; - sendSync(dispatch.OP_GLOBAL_TIMER_STOP); + let res = sendSync(builder, msg.Any.GlobalTimerStop, inner); + assert(res == null); } async function setGlobalTimeout(due: number, now: number): Promise<void> { @@ -50,8 +52,12 @@ async function setGlobalTimeout(due: number, now: number): Promise<void> { assert(timeout >= 0); // Send message to the backend. + const builder = flatbuffers.createBuilder(); + msg.GlobalTimer.startGlobalTimer(builder); + msg.GlobalTimer.addTimeout(builder, timeout); + const inner = msg.GlobalTimer.endGlobalTimer(builder); globalTimeoutDue = due; - await sendAsync(dispatch.OP_GLOBAL_TIMER, { timeout }); + await sendAsync(builder, msg.Any.GlobalTimer, inner); // eslint-disable-next-line @typescript-eslint/no-use-before-define fireTimers(); } diff --git a/js/workers.ts b/js/workers.ts index 7bcbe6279..e59e853c5 100644 --- a/js/workers.ts +++ b/js/workers.ts @@ -1,8 +1,7 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. /* eslint-disable @typescript-eslint/no-explicit-any */ -import * as dispatch from "./dispatch"; -import { sendAsync, sendSync } from "./dispatch_json"; -import { log } from "./util"; +import { sendAsync, sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; +import { assert, log } from "./util"; import { TextDecoder, TextEncoder } from "./text_encoding"; import { window } from "./window"; import { blobURLMap } from "./url"; @@ -27,28 +26,61 @@ function createWorker( hasSourceCode: boolean, sourceCode: Uint8Array ): number { - return sendSync(dispatch.OP_CREATE_WORKER, { - specifier, + const builder = flatbuffers.createBuilder(); + const specifier_ = builder.createString(specifier); + const sourceCode_ = builder.createString(sourceCode); + const inner = msg.CreateWorker.createCreateWorker( + builder, + specifier_, includeDenoNamespace, hasSourceCode, - sourceCode: new TextDecoder().decode(sourceCode) - }); + sourceCode_ + ); + const baseRes = sendSync(builder, msg.Any.CreateWorker, inner); + assert(baseRes != null); + assert( + msg.Any.CreateWorkerRes === baseRes!.innerType(), + `base.innerType() unexpectedly is ${baseRes!.innerType()}` + ); + const res = new msg.CreateWorkerRes(); + assert(baseRes!.inner(res) != null); + return res.rid(); } async function hostGetWorkerClosed(rid: number): Promise<void> { - await sendAsync(dispatch.OP_HOST_GET_WORKER_CLOSED, { rid }); + const builder = flatbuffers.createBuilder(); + const inner = msg.HostGetWorkerClosed.createHostGetWorkerClosed(builder, rid); + await sendAsync(builder, msg.Any.HostGetWorkerClosed, inner); } function hostPostMessage(rid: number, data: any): void { const dataIntArray = encodeMessage(data); - sendSync(dispatch.OP_HOST_POST_MESSAGE, { rid }, dataIntArray); + const builder = flatbuffers.createBuilder(); + const inner = msg.HostPostMessage.createHostPostMessage(builder, rid); + const baseRes = sendSync( + builder, + msg.Any.HostPostMessage, + inner, + dataIntArray + ); + assert(baseRes != null); } async function hostGetMessage(rid: number): Promise<any> { - const res = await sendAsync(dispatch.OP_HOST_GET_MESSAGE, { rid }); - - if (res.data != null) { - return decodeMessage(new Uint8Array(res.data)); + const builder = flatbuffers.createBuilder(); + const inner = msg.HostGetMessage.createHostGetMessage(builder, rid); + const baseRes = await sendAsync(builder, msg.Any.HostGetMessage, inner); + assert(baseRes != null); + assert( + msg.Any.HostGetMessageRes === baseRes!.innerType(), + `base.innerType() unexpectedly is ${baseRes!.innerType()}` + ); + const res = new msg.HostGetMessageRes(); + assert(baseRes!.inner(res) != null); + + const dataArray = res.dataArray(); + if (dataArray != null) { + return decodeMessage(dataArray); } else { return null; } @@ -59,15 +91,36 @@ export let onmessage: (e: { data: any }) => void = (): void => {}; export function postMessage(data: any): void { const dataIntArray = encodeMessage(data); - sendSync(dispatch.OP_WORKER_POST_MESSAGE, {}, dataIntArray); + const builder = flatbuffers.createBuilder(); + const inner = msg.WorkerPostMessage.createWorkerPostMessage(builder); + const baseRes = sendSync( + builder, + msg.Any.WorkerPostMessage, + inner, + dataIntArray + ); + assert(baseRes != null); } export async function getMessage(): Promise<any> { log("getMessage"); - const res = await sendAsync(dispatch.OP_WORKER_GET_MESSAGE); - - if (res.data != null) { - return decodeMessage(new Uint8Array(res.data)); + const builder = flatbuffers.createBuilder(); + const inner = msg.WorkerGetMessage.createWorkerGetMessage( + builder, + 0 /* unused */ + ); + const baseRes = await sendAsync(builder, msg.Any.WorkerGetMessage, inner); + assert(baseRes != null); + assert( + msg.Any.WorkerGetMessageRes === baseRes!.innerType(), + `base.innerType() unexpectedly is ${baseRes!.innerType()}` + ); + const res = new msg.WorkerGetMessageRes(); + assert(baseRes!.inner(res) != null); + + const dataArray = res.dataArray(); + if (dataArray != null) { + return decodeMessage(dataArray); } else { return null; } |