From c43cfedeba5d6ac96e1b1febed8549e750606e3f Mon Sep 17 00:00:00 2001 From: Kitson Kelly Date: Tue, 26 Mar 2019 23:22:07 +1100 Subject: [PATCH] namespace reorg: libdeno and DenoCore to Deno.core (#1998) --- BUILD.gn | 1 - cli/ops.rs | 6 +-- core/core.d.ts | 25 ++++++++++ core/http_bench.js | 12 ++--- core/isolate.rs | 68 +++++++++++++-------------- core/shared_queue.js | 35 +++++++++----- core/shared_queue_test.js | 4 +- js/compiler.ts | 4 +- js/console.ts | 4 +- js/core.ts | 11 +---- js/deno.ts | 6 ++- js/dispatch.ts | 4 +- js/event.ts | 4 +- js/flatbuffers.ts | 2 +- js/globals.ts | 5 +- js/os.ts | 11 ++--- js/repl.ts | 10 ++-- libdeno/api.cc | 2 +- libdeno/binding.cc | 19 ++++---- libdeno/deno.h | 12 ++--- libdeno/internal.h | 4 +- js/libdeno.ts => libdeno/libdeno.d.ts | 12 ++--- libdeno/libdeno_test.cc | 2 +- libdeno/libdeno_test.js | 47 +++++++++--------- libdeno/modules_test.cc | 6 +-- tsconfig.json | 8 +++- 26 files changed, 178 insertions(+), 146 deletions(-) create mode 100644 core/core.d.ts rename js/libdeno.ts => libdeno/libdeno.d.ts (82%) diff --git a/BUILD.gn b/BUILD.gn index 41a84613..bde36a7f 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -82,7 +82,6 @@ ts_sources = [ "js/globals.ts", "js/headers.ts", "js/io.ts", - "js/libdeno.ts", "js/lib.web_assembly.d.ts", "js/location.ts", "js/main.ts", diff --git a/cli/ops.rs b/cli/ops.rs index a0605f64..68e59393 100644 --- a/cli/ops.rs +++ b/cli/ops.rs @@ -69,9 +69,9 @@ fn empty_buf() -> Buf { } /// Processes raw messages from JavaScript. -/// This functions invoked every time libdeno.send() is called. -/// control corresponds to the first argument of libdeno.send(). -/// data corresponds to the second argument of libdeno.send(). +/// This functions invoked every time Deno.core.dispatch() is called. +/// control corresponds to the first argument of Deno.core.dispatch(). +/// data corresponds to the second argument of Deno.core.dispatch(). pub fn dispatch_all( sc: &IsolateStateContainer, control: &[u8], diff --git a/core/core.d.ts b/core/core.d.ts new file mode 100644 index 00000000..b1d1ac57 --- /dev/null +++ b/core/core.d.ts @@ -0,0 +1,25 @@ +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. + +// This file contains APIs that are introduced into the global namespace by +// Deno core. These are not intended to be used directly by runtime users of +// Deno and therefore do not flow through to the runtime type library. + +declare interface MessageCallback { + (msg: Uint8Array): void; +} + +declare interface DenoCore { + dispatch( + control: Uint8Array, + zeroCopy?: ArrayBufferView | null + ): Uint8Array | null; + setAsyncHandler(cb: MessageCallback): void; + sharedQueue: { + head(): number; + numRecords(): number; + size(): number; + push(buf: Uint8Array): boolean; + reset(): void; + shift(): Uint8Array | null; + }; +} diff --git a/core/http_bench.js b/core/http_bench.js index d7cffcb7..8eb764b5 100644 --- a/core/http_bench.js +++ b/core/http_bench.js @@ -42,7 +42,7 @@ function send(promiseId, opId, arg, zeroCopy = null) { scratch32[1] = opId; scratch32[2] = arg; scratch32[3] = -1; - return DenoCore.dispatch(scratchBytes, zeroCopy); + return Deno.core.dispatch(scratchBytes, zeroCopy); } /** Returns Promise */ @@ -123,17 +123,17 @@ async function serve(rid) { } async function main() { - DenoCore.setAsyncHandler(handleAsyncMsgFromRust); + Deno.core.setAsyncHandler(handleAsyncMsgFromRust); - libdeno.print("http_bench.js start\n"); + Deno.core.print("http_bench.js start\n"); const listenerRid = listen(); - libdeno.print(`listening http://127.0.0.1:4544/ rid = ${listenerRid}\n`); + Deno.core.print(`listening http://127.0.0.1:4544/ rid = ${listenerRid}\n`); while (true) { const rid = await accept(listenerRid); - // libdeno.print(`accepted ${rid}`); + // Deno.core.print(`accepted ${rid}`); if (rid < 0) { - libdeno.print(`accept error ${rid}`); + Deno.core.print(`accept error ${rid}`); return; } serve(rid); diff --git a/core/isolate.rs b/core/isolate.rs index 74b8a727..b28730ba 100644 --- a/core/isolate.rs +++ b/core/isolate.rs @@ -63,8 +63,8 @@ pub trait Behavior { /// Isolate is created. fn startup_data(&mut self) -> Option; - /// Called whenever libdeno.send() is called in JavaScript. zero_copy_buf - /// corresponds to the second argument of libdeno.send(). + /// Called whenever Deno.core.send() is called in JavaScript. zero_copy_buf + /// corresponds to the second argument of Deno.core.send(). fn dispatch( &mut self, control: &[u8], @@ -77,7 +77,7 @@ pub trait Behavior { /// Tokio. The Isolate future complete when there is an error or when all /// pending ops have completed. /// -/// Ops are created in JavaScript by calling libdeno.send(), and in Rust by +/// Ops are created in JavaScript by calling Deno.core.send(), and in Rust by /// implementing Behavior::dispatch. An Op corresponds exactly to a Promise in /// JavaScript. pub struct Isolate { @@ -125,7 +125,7 @@ impl Isolate { None => libdeno::deno_buf::empty(), }, shared: shared.as_deno_buf(), - recv_cb: Self::pre_dispatch, + recv_cb: Self::predispatch, }; let libdeno_isolate = unsafe { libdeno::deno_new(config) }; @@ -157,7 +157,7 @@ impl Isolate { } } - /// Executes a bit of built-in JavaScript to provide Deno._sharedQueue. + /// Executes a bit of built-in JavaScript to provide Deno.sharedQueue. pub fn shared_init(&mut self) { if self.needs_init { self.needs_init = false; @@ -167,7 +167,7 @@ impl Isolate { } } - extern "C" fn pre_dispatch( + extern "C" fn predispatch( user_data: *mut c_void, control_argv0: deno_buf, zero_copy_buf: deno_buf, @@ -178,12 +178,12 @@ impl Isolate { let control_shared = isolate.shared.shift(); let (is_sync, op) = if control_argv0.len() > 0 { - // The user called libdeno.send(control) + // The user called Deno.core.send(control) isolate .behavior .dispatch(control_argv0.as_ref(), zero_copy_buf) } else if let Some(c) = control_shared { - // The user called Deno._sharedQueue.push(control) + // The user called Deno.sharedQueue.push(control) isolate.behavior.dispatch(&c, zero_copy_buf) } else { // The sharedQueue is empty. The shouldn't happen usually, but it's also @@ -199,7 +199,7 @@ impl Isolate { if is_sync { let res_record = op.wait().unwrap(); - // For sync messages, we always return the response via libdeno.send's + // For sync messages, we always return the response via Deno.core.send's // return value. // TODO(ry) check that if JSError thrown during respond(), that it will be // picked up. @@ -614,15 +614,15 @@ mod tests { } #[test] - fn test_dispatch() { + fn testdispatch() { let mut isolate = TestBehavior::setup(TestBehaviorMode::AsyncImmediate); js_check(isolate.execute( "filename.js", r#" let control = new Uint8Array([42]); - libdeno.send(control); + Deno.core.send(control); async function main() { - libdeno.send(control); + Deno.core.send(control); } main(); "#, @@ -641,7 +641,7 @@ mod tests { import { b } from 'b.js' if (b() != 'b') throw Error(); let control = new Uint8Array([42]); - libdeno.send(control); + Deno.core.send(control); "#, ).unwrap(); assert_eq!(isolate.behavior.dispatch_count, 0); @@ -685,7 +685,7 @@ mod tests { "setup2.js", r#" let nrecv = 0; - DenoCore.setAsyncHandler((buf) => { + Deno.core.setAsyncHandler((buf) => { nrecv++; }); "#, @@ -696,7 +696,7 @@ mod tests { r#" assert(nrecv == 0); let control = new Uint8Array([42]); - libdeno.send(control); + Deno.core.send(control); assert(nrecv == 0); "#, )); @@ -707,7 +707,7 @@ mod tests { "check2.js", r#" assert(nrecv == 1); - libdeno.send(control); + Deno.core.send(control); assert(nrecv == 1); "#, )); @@ -727,7 +727,7 @@ mod tests { "setup2.js", r#" let nrecv = 0; - DenoCore.setAsyncHandler((buf) => { + Deno.core.setAsyncHandler((buf) => { assert(buf.byteLength === 1); assert(buf[0] === 43); nrecv++; @@ -740,12 +740,12 @@ mod tests { "send1.js", r#" let control = new Uint8Array([42]); - DenoCore.shared.push(control); - libdeno.send(); + Deno.core.sharedQueue.push(control); + Deno.core.send(); assert(nrecv === 0); - DenoCore.shared.push(control); - libdeno.send(); + Deno.core.sharedQueue.push(control); + Deno.core.send(); assert(nrecv === 0); "#, )); @@ -832,10 +832,10 @@ mod tests { "overflow_req_sync.js", r#" let asyncRecv = 0; - DenoCore.setAsyncHandler((buf) => { asyncRecv++ }); + Deno.core.setAsyncHandler((buf) => { asyncRecv++ }); // Large message that will overflow the shared space. let control = new Uint8Array(100 * 1024 * 1024); - let response = DenoCore.dispatch(control); + let response = Deno.core.dispatch(control); assert(response instanceof Uint8Array); assert(response.length == 1); assert(response[0] == 43); @@ -854,10 +854,10 @@ mod tests { "overflow_res_sync.js", r#" let asyncRecv = 0; - DenoCore.setAsyncHandler((buf) => { asyncRecv++ }); + Deno.core.setAsyncHandler((buf) => { asyncRecv++ }); // Large message that will overflow the shared space. let control = new Uint8Array([42]); - let response = DenoCore.dispatch(control); + let response = Deno.core.dispatch(control); assert(response instanceof Uint8Array); assert(response.length == 100 * 1024 * 1024); assert(response[0] == 99); @@ -874,14 +874,14 @@ mod tests { "overflow_req_async.js", r#" let asyncRecv = 0; - DenoCore.setAsyncHandler((buf) => { + Deno.core.setAsyncHandler((buf) => { assert(buf.byteLength === 1); assert(buf[0] === 43); asyncRecv++; }); // Large message that will overflow the shared space. let control = new Uint8Array(100 * 1024 * 1024); - let response = DenoCore.dispatch(control); + let response = Deno.core.dispatch(control); // Async messages always have null response. assert(response == null); assert(asyncRecv == 0); @@ -901,14 +901,14 @@ mod tests { "overflow_res_async.js", r#" let asyncRecv = 0; - DenoCore.setAsyncHandler((buf) => { + Deno.core.setAsyncHandler((buf) => { assert(buf.byteLength === 100 * 1024 * 1024); assert(buf[0] === 4); asyncRecv++; }); // Large message that will overflow the shared space. let control = new Uint8Array([42]); - let response = DenoCore.dispatch(control); + let response = Deno.core.dispatch(control); assert(response == null); assert(asyncRecv == 0); "#, @@ -919,27 +919,27 @@ mod tests { } #[test] - fn overflow_res_multiple_dispatch_async() { + fn overflow_res_multipledispatch_async() { // TODO(ry) This test is quite slow due to memcpy-ing 100MB into JS. We // should optimize this. let mut isolate = TestBehavior::setup(TestBehaviorMode::OverflowResAsync); js_check(isolate.execute( - "overflow_res_multiple_dispatch_async.js", + "overflow_res_multipledispatch_async.js", r#" let asyncRecv = 0; - DenoCore.setAsyncHandler((buf) => { + Deno.core.setAsyncHandler((buf) => { assert(buf.byteLength === 100 * 1024 * 1024); assert(buf[0] === 4); asyncRecv++; }); // Large message that will overflow the shared space. let control = new Uint8Array([42]); - let response = DenoCore.dispatch(control); + let response = Deno.core.dispatch(control); assert(response == null); assert(asyncRecv == 0); // Dispatch another message to verify that pending ops // are done even if shared space overflows - DenoCore.dispatch(control); + Deno.core.dispatch(control); "#, )); assert_eq!(isolate.behavior.dispatch_count, 2); diff --git a/core/shared_queue.js b/core/shared_queue.js index 6c9a0326..02aded74 100644 --- a/core/shared_queue.js +++ b/core/shared_queue.js @@ -1,5 +1,8 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. + (window => { + const GLOBAL_NAMESPACE = "Deno"; + const CORE_NAMESPACE = "core"; const MAX_RECORDS = 100; const INDEX_NUM_RECORDS = 0; const INDEX_NUM_SHIFTED_OFF = 1; @@ -8,8 +11,11 @@ const INDEX_RECORDS = 3 + MAX_RECORDS; const HEAD_INIT = 4 * INDEX_RECORDS; - let sharedBytes = null; - let shared32 = null; + const Deno = window[GLOBAL_NAMESPACE]; + const core = Deno[CORE_NAMESPACE]; + + let sharedBytes; + let shared32; function assert(cond) { if (!cond) { @@ -92,10 +98,12 @@ reset(); } + assert(off != null); + assert(end != null); return sharedBytes.subarray(off, end); } - let asyncHandler = null; + let asyncHandler; function setAsyncHandler(cb) { assert(asyncHandler == null); asyncHandler = cb; @@ -117,23 +125,22 @@ assert(shared32 == null); sharedBytes = new Uint8Array(shared); shared32 = new Int32Array(shared); - // Callers should not call libdeno.recv, use setAsyncHandler. - libdeno.recv(handleAsyncMsgFromRust); + // Callers should not call Deno.core.recv, use setAsyncHandler. + window.Deno.core.recv(handleAsyncMsgFromRust); } function dispatch(control, zeroCopy = null) { // First try to push control to shared. const success = push(control); - // If successful, don't use first argument of libdeno.send. + // If successful, don't use first argument of core.send. const arg0 = success ? null : control; - return libdeno.send(arg0, zeroCopy); + return window.Deno.core.send(arg0, zeroCopy); } - assert(!window["DenoCore"]); - window["DenoCore"] = { + const denoCore = { setAsyncHandler, dispatch, - shared: { + sharedQueue: { head, numRecords, size, @@ -143,5 +150,9 @@ } }; - init(libdeno.shared); -})(this); + assert(window[GLOBAL_NAMESPACE] != null); + assert(window[GLOBAL_NAMESPACE][CORE_NAMESPACE] != null); + Object.assign(core, denoCore); + + init(Deno.core.shared); +})(globalThis); diff --git a/core/shared_queue_test.js b/core/shared_queue_test.js index 817bb3bc..75a87793 100644 --- a/core/shared_queue_test.js +++ b/core/shared_queue_test.js @@ -7,7 +7,7 @@ function assert(cond) { } function main() { - const q = DenoCore.shared; + const q = Deno.core.sharedQueue; let h = q.head(); assert(h > 0); @@ -56,7 +56,7 @@ function main() { assert(q.numRecords() == 0); assert(q.size() == 0); - libdeno.print("shared_queue_test.js ok\n"); + Deno.core.print("shared_queue_test.js ok\n"); } main(); diff --git a/js/compiler.ts b/js/compiler.ts index aefdf989..8be78935 100644 --- a/js/compiler.ts +++ b/js/compiler.ts @@ -4,7 +4,7 @@ import * as msg from "gen/msg_generated"; import { window } from "./window"; import { assetSourceCode } from "./assets"; import { Console } from "./console"; -import { libdeno } from "./libdeno"; +import { core } from "./core"; import * as os from "./os"; import { TextDecoder, TextEncoder } from "./text_encoding"; import { clearTimer, setTimeout } from "./timers"; @@ -16,7 +16,7 @@ const ASSETS = "$asset$"; const LIB_RUNTIME = `${ASSETS}/lib.deno_runtime.d.ts`; // An instance of console -const console = new Console(libdeno.print); +const console = new Console(core.print); /** The location that a module is being loaded from. This could be a directory, * like `.`, or it could be a module specifier like diff --git a/js/console.ts b/js/console.ts index b68794d3..3669a1d3 100644 --- a/js/console.ts +++ b/js/console.ts @@ -5,7 +5,7 @@ import { TextEncoder } from "./text_encoding"; import { File, stdout } from "./files"; import { cliTable } from "./console_table"; import { formatError } from "./format_error"; -import { libdeno } from "./libdeno"; +import { core } from "./core"; type ConsoleContext = Set; type ConsoleOptions = Partial<{ @@ -323,7 +323,7 @@ function createObjectString( ...args: [ConsoleContext, number, number] ): string { if (value instanceof Error) { - const errorJSON = libdeno.errorToJSON(value); + const errorJSON = core.errorToJSON(value); return formatError(errorJSON); } else if (Array.isArray(value)) { return createArrayString(value, ...args); diff --git a/js/core.ts b/js/core.ts index 9e94ffdb..03473ff3 100644 --- a/js/core.ts +++ b/js/core.ts @@ -1,13 +1,4 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. import { window } from "./window"; -type MessageCallback = (msg: Uint8Array) => void; - -// Declared in core/shared_queue.js. -interface DenoCore { - setAsyncHandler(cb: MessageCallback): void; - dispatch(control: Uint8Array, zeroCopy?: Uint8Array): null | Uint8Array; -} - -// TODO(ry) Rename to Deno.core.shared and Deno.core.setAsyncHandler. -export const DenoCore = window.DenoCore as DenoCore; +export const core = window.Deno.core as DenoCore; diff --git a/js/deno.ts b/js/deno.ts index d663ca55..ed42dc89 100644 --- a/js/deno.ts +++ b/js/deno.ts @@ -49,7 +49,6 @@ export { statSync, lstatSync, stat, lstat } from "./stat"; export { symlinkSync, symlink } from "./symlink"; export { writeFileSync, writeFile, WriteFileOptions } from "./write_file"; export { ErrorKind, DenoError } from "./errors"; -export { libdeno } from "./libdeno"; export { permissions, revokePermission, @@ -67,6 +66,11 @@ export { build, platform, OperatingSystem, Arch } from "./build"; export { version } from "./version"; export const args: string[] = []; +// These are internal Deno APIs. We are marking them as internal so they do not +// appear in the runtime type library. +/** @internal */ +export { core } from "./core"; + // TODO Don't expose Console nor stringifyArgs. /** @internal */ export { Console, stringifyArgs } from "./console"; diff --git a/js/dispatch.ts b/js/dispatch.ts index 2e6cbf10..3ca0cd79 100644 --- a/js/dispatch.ts +++ b/js/dispatch.ts @@ -1,5 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { window } from "./window"; +import { core } from "./core"; import * as flatbuffers from "./flatbuffers"; import * as msg from "gen/msg_generated"; import * as errors from "./errors"; @@ -39,7 +39,7 @@ function sendInternal( builder.finish(msg.Base.endBase(builder)); const control = builder.asUint8Array(); - const response = window.DenoCore.dispatch(control, zeroCopy); + const response = core.dispatch(control, zeroCopy); builder.inUse = false; return [cmdId, response]; diff --git a/js/event.ts b/js/event.ts index 61f21f2e..8cd4d22d 100644 --- a/js/event.ts +++ b/js/event.ts @@ -21,7 +21,7 @@ export class EventInit implements domTypes.EventInit { export class Event implements domTypes.Event { // Each event has the following associated flags private _canceledFlag = false; - private _dispatchedFlag = false; + private dispatchedFlag = false; private _initializedFlag = false; private _inPassiveListenerFlag = false; private _stopImmediatePropagationFlag = false; @@ -76,7 +76,7 @@ export class Event implements domTypes.Event { } get dispatched(): boolean { - return this._dispatchedFlag; + return this.dispatchedFlag; } get eventPhase(): number { diff --git a/js/flatbuffers.ts b/js/flatbuffers.ts index 73f3ceb8..f05bd1c5 100644 --- a/js/flatbuffers.ts +++ b/js/flatbuffers.ts @@ -17,7 +17,7 @@ globalBuilder.inUse = false; // This is a wrapper around the real Builder . // The purpose is to reuse a single ArrayBuffer for every message. // We can do this because the "control" messages sent to the privileged -// side are guaranteed to be used during the call to libdeno.send(). +// side are guaranteed to be used during the call to Deno.core.send(). export function createBuilder(): Builder { // eslint-disable-next-line @typescript-eslint/no-explicit-any const gb = globalBuilder as any; diff --git a/js/globals.ts b/js/globals.ts index af99ae7e..5a0fb18c 100644 --- a/js/globals.ts +++ b/js/globals.ts @@ -27,7 +27,7 @@ import * as performanceUtil from "./performance"; // These imports are not exposed and therefore are fine to just import the // symbols required. -import { libdeno } from "./libdeno"; +import { core } from "./core"; // During the build process, augmentations to the variable `window` in this // file are tracked and created as part of default library that is built into @@ -43,7 +43,6 @@ window.window = window; // This is the Deno namespace, it is handled differently from other window // properties when building the runtime type library, as the whole module // is flattened into a single namespace. - window.Deno = deno; Object.freeze(window.Deno); @@ -53,7 +52,7 @@ window.btoa = textEncoding.btoa; window.fetch = fetchTypes.fetch; window.clearTimeout = timers.clearTimer; window.clearInterval = timers.clearTimer; -window.console = new consoleTypes.Console(libdeno.print); +window.console = new consoleTypes.Console(core.print); window.setTimeout = timers.setTimeout; window.setInterval = timers.setInterval; window.location = (undefined as unknown) as domTypes.Location; diff --git a/js/os.ts b/js/os.ts index c9641693..0ad107bf 100644 --- a/js/os.ts +++ b/js/os.ts @@ -1,6 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. import * as msg from "gen/msg_generated"; -import { window } from "./window"; +import { core } from "./core"; import { handleAsyncMsgFromRust, sendSync } from "./dispatch"; import * as flatbuffers from "./flatbuffers"; import { TextDecoder } from "./text_encoding"; @@ -16,12 +16,7 @@ export let noColor: boolean; /** Path to the current deno process's executable file. */ export let execPath: string; -/** @internal */ -export function setGlobals( - pid_: number, - noColor_: boolean, - execPath_: string -): void { +function setGlobals(pid_: number, noColor_: boolean, execPath_: string): void { assert(!pid); pid = pid_; noColor = noColor_; @@ -169,7 +164,7 @@ function sendStart(): msg.StartRes { // the runtime and the compiler environments. // @internal export function start(source?: string): msg.StartRes { - window.DenoCore.setAsyncHandler(handleAsyncMsgFromRust); + core.setAsyncHandler(handleAsyncMsgFromRust); // 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 diff --git a/js/repl.ts b/js/repl.ts index c39a79a7..06850187 100644 --- a/js/repl.ts +++ b/js/repl.ts @@ -6,7 +6,7 @@ import { close } from "./files"; import * as dispatch from "./dispatch"; import { exit } from "./os"; import { window } from "./window"; -import { libdeno } from "./libdeno"; +import { core } from "./core"; import { formatError } from "./format_error"; const helpMsg = [ @@ -90,7 +90,7 @@ function isRecoverableError(e: Error): boolean { // Returns true if code is consumed (no error/irrecoverable error). // Returns false if error is recoverable function evaluate(code: string): boolean { - const [result, errInfo] = libdeno.evalContext(code); + const [result, errInfo] = core.evalContext(code); if (!errInfo) { console.log(result); } else if (errInfo.isCompileError && isRecoverableError(errInfo.thrown)) { @@ -99,7 +99,7 @@ function evaluate(code: string): boolean { } else { if (errInfo.isNativeError) { const formattedError = formatError( - libdeno.errorToJSON(errInfo.thrown as Error) + core.errorToJSON(errInfo.thrown as Error) ); console.error(formattedError); } else { @@ -140,7 +140,7 @@ export async function replLoop(): Promise { if (err.message !== "Interrupted") { // e.g. this happens when we have deno.close(3). // We want to display the problem. - const formattedError = formatError(libdeno.errorToJSON(err)); + const formattedError = formatError(core.errorToJSON(err)); console.error(formattedError); } // Quit REPL anyways. @@ -162,7 +162,7 @@ export async function replLoop(): Promise { } else { // e.g. this happens when we have deno.close(3). // We want to display the problem. - const formattedError = formatError(libdeno.errorToJSON(err)); + const formattedError = formatError(core.errorToJSON(err)); console.error(formattedError); quitRepl(1); } diff --git a/libdeno/api.cc b/libdeno/api.cc index ab87382c..fa1fe92f 100644 --- a/libdeno/api.cc +++ b/libdeno/api.cc @@ -177,7 +177,7 @@ void deno_respond(Deno* d_, void* user_data, deno_buf buf) { auto recv_ = d->recv_.Get(d->isolate_); if (recv_.IsEmpty()) { - d->last_exception_ = "libdeno.recv_ has not been called."; + d->last_exception_ = "Deno.core.recv has not been called."; return; } diff --git a/libdeno/binding.cc b/libdeno/binding.cc index c291852d..ab633f46 100644 --- a/libdeno/binding.cc +++ b/libdeno/binding.cc @@ -232,7 +232,7 @@ void Recv(const v8::FunctionCallbackInfo& args) { v8::HandleScope handle_scope(isolate); if (!d->recv_.IsEmpty()) { - isolate->ThrowException(v8_str("libdeno.recv_ already called.")); + isolate->ThrowException(v8_str("Deno.core.recv already called.")); return; } @@ -485,33 +485,36 @@ void InitializeContext(v8::Isolate* isolate, v8::Local context) { auto global = context->Global(); auto deno_val = v8::Object::New(isolate); - CHECK(global->Set(context, deno::v8_str("libdeno"), deno_val).FromJust()); + CHECK(global->Set(context, deno::v8_str("Deno"), deno_val).FromJust()); + + auto core_val = v8::Object::New(isolate); + CHECK(deno_val->Set(context, deno::v8_str("core"), core_val).FromJust()); auto print_tmpl = v8::FunctionTemplate::New(isolate, Print); auto print_val = print_tmpl->GetFunction(context).ToLocalChecked(); - CHECK(deno_val->Set(context, deno::v8_str("print"), print_val).FromJust()); + CHECK(core_val->Set(context, deno::v8_str("print"), print_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()); + CHECK(core_val->Set(context, deno::v8_str("recv"), recv_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()); + CHECK(core_val->Set(context, deno::v8_str("send"), send_val).FromJust()); auto eval_context_tmpl = v8::FunctionTemplate::New(isolate, EvalContext); auto eval_context_val = eval_context_tmpl->GetFunction(context).ToLocalChecked(); - CHECK(deno_val->Set(context, deno::v8_str("evalContext"), eval_context_val) + CHECK(core_val->Set(context, deno::v8_str("evalContext"), eval_context_val) .FromJust()); auto error_to_json_tmpl = v8::FunctionTemplate::New(isolate, ErrorToJSON); auto error_to_json_val = error_to_json_tmpl->GetFunction(context).ToLocalChecked(); - CHECK(deno_val->Set(context, deno::v8_str("errorToJSON"), error_to_json_val) + CHECK(core_val->Set(context, deno::v8_str("errorToJSON"), error_to_json_val) .FromJust()); - CHECK(deno_val->SetAccessor(context, deno::v8_str("shared"), Shared) + CHECK(core_val->SetAccessor(context, deno::v8_str("shared"), Shared) .FromJust()); } diff --git a/libdeno/deno.h b/libdeno/deno.h index f3902985..37a302ca 100644 --- a/libdeno/deno.h +++ b/libdeno/deno.h @@ -23,8 +23,8 @@ typedef struct deno_s Deno; // A callback to receive a message from a libdeno.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, - deno_buf zerop_copy_buf); +typedef void (*denorecv_cb)(void* user_data, deno_buf control_buf, + deno_buf zerop_copy_buf); void deno_init(); const char* deno_v8_version(); @@ -34,7 +34,7 @@ typedef struct { int will_snapshot; // Default 0. If calling deno_get_snapshot 1. deno_buf load_snapshot; // Optionally: A deno_buf from deno_get_snapshot. deno_buf shared; // Shared buffer to be mapped to libdeno.shared - deno_recv_cb recv_cb; // Maps to libdeno.send() calls. + denorecv_cb recv_cb; // Maps to libdeno.send() calls. } deno_config; // Create a new deno isolate. @@ -57,13 +57,13 @@ void deno_unlock(Deno* d); void deno_execute(Deno* d, void* user_data, const char* js_filename, const char* js_source); -// deno_respond sends up to one message back for every deno_recv_cb made. +// deno_respond sends up to one message back for every denorecv_cb made. // -// If this is called during deno_recv_cb, the issuing libdeno.send() in +// If this is called during denorecv_cb, the issuing libdeno.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 +// If this is called after denorecv_cb has returned, the deno_respond // will call into the JS callback specified by libdeno.recv(). // // (Ideally, but not currently: After calling deno_respond(), the caller no diff --git a/libdeno/internal.h b/libdeno/internal.h index 71cf731b..54e84596 100644 --- a/libdeno/internal.h +++ b/libdeno/internal.h @@ -104,7 +104,7 @@ class DenoIsolate { const v8::FunctionCallbackInfo* current_args_; v8::SnapshotCreator* snapshot_creator_; void* global_import_buf_ptr_; - deno_recv_cb recv_cb_; + denorecv_cb recv_cb_; size_t next_zero_copy_id_; void* user_data_; @@ -170,7 +170,7 @@ static intptr_t external_references[] = { static const deno_buf empty_buf = {nullptr, 0, nullptr, 0, 0}; -Deno* NewFromSnapshot(void* user_data, deno_recv_cb cb); +Deno* NewFromSnapshot(void* user_data, denorecv_cb cb); void InitializeContext(v8::Isolate* isolate, v8::Local context); diff --git a/js/libdeno.ts b/libdeno/libdeno.d.ts similarity index 82% rename from js/libdeno.ts rename to libdeno/libdeno.d.ts index 485e67bb..1bc7367d 100644 --- a/js/libdeno.ts +++ b/libdeno/libdeno.d.ts @@ -1,8 +1,4 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { window } from "./window"; - -// The libdeno functions are moved so that users can't access them. -type MessageCallback = (msg: Uint8Array) => void; interface EvalErrorInfo { // Is the object thrown a native Error? @@ -16,7 +12,11 @@ interface EvalErrorInfo { thrown: any; } -interface Libdeno { +declare interface MessageCallback { + (msg: Uint8Array): void; +} + +declare interface DenoCore { recv(cb: MessageCallback): void; send( @@ -38,5 +38,3 @@ interface Libdeno { errorToJSON: (e: Error) => string; } - -export const libdeno = window.libdeno as Libdeno; diff --git a/libdeno/libdeno_test.cc b/libdeno/libdeno_test.cc index 90fceef7..8949e7f4 100644 --- a/libdeno/libdeno_test.cc +++ b/libdeno/libdeno_test.cc @@ -320,7 +320,7 @@ TEST(LibDenoTest, SharedAtomics) { deno_buf shared = {nullptr, 0, reinterpret_cast(s), sizeof s, 0}; Deno* d = deno_new(deno_config{0, empty, shared, nullptr}); deno_execute(d, nullptr, "a.js", - "Atomics.add(new Int32Array(libdeno.shared), 0, 1)"); + "Atomics.add(new Int32Array(Deno.core.shared), 0, 1)"); EXPECT_EQ(nullptr, deno_last_exception(d)); EXPECT_EQ(s[0], 1); EXPECT_EQ(s[1], 1); diff --git a/libdeno/libdeno_test.js b/libdeno/libdeno_test.js index 8b1ad2e0..b0040025 100644 --- a/libdeno/libdeno_test.js +++ b/libdeno/libdeno_test.js @@ -10,7 +10,7 @@ function assert(cond) { } global.CanCallFunction = () => { - libdeno.print("Hello world from foo"); + Deno.core.print("Hello world from foo"); return "foo"; }; @@ -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 = libdeno.send(m1); + const r1 = Deno.core.send(m1); assert(r1 == null); - const r2 = libdeno.send(m2); + const r2 = Deno.core.send(m2); assert(r2 == null); }; global.RecvReturnBar = () => { const m = new Uint8Array("abc".split("").map(c => c.charCodeAt(0))); - const r = libdeno.send(m); + const r = Deno.core.send(m); assert(r instanceof Uint8Array); assert(r.byteLength === 3); const rstr = String.fromCharCode(...r); @@ -44,10 +44,10 @@ global.RecvReturnBar = () => { }; global.DoubleRecvFails = () => { - // libdeno.recv is an internal function and should only be called once from the + // Deno.core.recv is an internal function and should only be called once from the // runtime. - libdeno.recv((channel, msg) => assert(false)); - libdeno.recv((channel, msg) => assert(false)); + Deno.core.recv((channel, msg) => assert(false)); + Deno.core.recv((channel, msg) => assert(false)); }; global.SendRecvSlice = () => { @@ -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 = libdeno.send(buf); + buf = Deno.core.send(buf); assert(buf.byteOffset === i * 11); assert(buf.byteLength === abLen - i * 30 - 19); assert(buf.buffer.byteLength == abLen); @@ -78,17 +78,17 @@ global.JSSendArrayBufferViewTypes = () => { const ab1 = new ArrayBuffer(4321); const u8 = new Uint8Array(ab1, 2468, 1000); u8[0] = 1; - libdeno.send(u8); + Deno.core.send(u8); // Send Uint32Array. const ab2 = new ArrayBuffer(4321); const u32 = new Uint32Array(ab2, 2468, 1000 / Uint32Array.BYTES_PER_ELEMENT); u32[0] = 0x02020202; - libdeno.send(u32); + Deno.core.send(u32); // Send DataView. const ab3 = new ArrayBuffer(4321); const dv = new DataView(ab3, 2468, 1000); dv.setUint8(0, 3); - libdeno.send(dv); + Deno.core.send(dv); }; // The following join has caused SnapshotBug to segfault when using kKeep. @@ -110,7 +110,7 @@ global.ZeroCopyBuf = () => { const b = zeroCopyBuf; // The second parameter of send should modified by the // privileged side. - const r = libdeno.send(a, b); + const r = Deno.core.send(a, b); assert(r == null); // b is different. assert(b[0] === 4); @@ -129,15 +129,15 @@ global.CheckPromiseErrors = () => { try { await fn(); } catch (e) { - libdeno.send(new Uint8Array([42])); + Deno.core.send(new Uint8Array([42])); } })(); }; global.Shared = () => { - const ab = libdeno.shared; + const ab = Deno.core.shared; assert(ab instanceof SharedArrayBuffer); - assert(libdeno.shared != undefined); + assert(Deno.core.shared != undefined); assert(ab.byteLength === 3); const ui8 = new Uint8Array(ab); assert(ui8[0] === 0); @@ -149,45 +149,46 @@ global.Shared = () => { }; global.LibDenoEvalContext = () => { - const [result, errInfo] = libdeno.evalContext("let a = 1; a"); + const [result, errInfo] = Deno.core.evalContext("let a = 1; a"); assert(result === 1); assert(!errInfo); - const [result2, errInfo2] = libdeno.evalContext("a = a + 1; a"); + const [result2, errInfo2] = Deno.core.evalContext("a = a + 1; a"); assert(result2 === 2); assert(!errInfo2); }; global.LibDenoEvalContextError = () => { - const [result, errInfo] = libdeno.evalContext("not_a_variable"); + const [result, errInfo] = Deno.core.evalContext("not_a_variable"); assert(!result); assert(!!errInfo); assert(errInfo.isNativeError); // is a native error (ReferenceError) assert(!errInfo.isCompileError); // is NOT a compilation error assert(errInfo.thrown.message === "not_a_variable is not defined"); - const [result2, errInfo2] = libdeno.evalContext("throw 1"); + const [result2, errInfo2] = Deno.core.evalContext("throw 1"); assert(!result2); assert(!!errInfo2); assert(!errInfo2.isNativeError); // is NOT a native error assert(!errInfo2.isCompileError); // is NOT a compilation error assert(errInfo2.thrown === 1); - const [result3, errInfo3] = - libdeno.evalContext("class AError extends Error {}; throw new AError('e')"); + const [result3, errInfo3] = Deno.core.evalContext( + "class AError extends Error {}; throw new AError('e')" + ); assert(!result3); assert(!!errInfo3); assert(errInfo3.isNativeError); // extend from native error, still native error assert(!errInfo3.isCompileError); // is NOT a compilation error assert(errInfo3.thrown.message === "e"); - const [result4, errInfo4] = libdeno.evalContext("{"); + const [result4, errInfo4] = Deno.core.evalContext("{"); assert(!result4); assert(!!errInfo4); assert(errInfo4.isNativeError); // is a native error (SyntaxError) assert(errInfo4.isCompileError); // is a compilation error! (braces not closed) assert(errInfo4.thrown.message === "Unexpected end of input"); - const [result5, errInfo5] = libdeno.evalContext("eval('{')"); + const [result5, errInfo5] = Deno.core.evalContext("eval('{')"); assert(!result5); assert(!!errInfo5); assert(errInfo5.isNativeError); // is a native error (SyntaxError) diff --git a/libdeno/modules_test.cc b/libdeno/modules_test.cc index 357c4864..9f922843 100644 --- a/libdeno/modules_test.cc +++ b/libdeno/modules_test.cc @@ -19,7 +19,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" - "libdeno.send(new Uint8Array([4]));"); + "Deno.core.send(new Uint8Array([4]));"); EXPECT_NE(a, 0); EXPECT_EQ(nullptr, deno_last_exception(d)); @@ -71,7 +71,7 @@ TEST(ModulesTest, ResolutionError) { static deno_mod a = deno_mod_new(d, true, "a.js", "import 'bad'\n" - "libdeno.send(new Uint8Array([4]));"); + "Deno.core.send(new Uint8Array([4]));"); EXPECT_NE(a, 0); EXPECT_EQ(nullptr, deno_last_exception(d)); @@ -105,7 +105,7 @@ TEST(ModulesTest, ImportMetaUrl) { static deno_mod a = deno_mod_new(d, true, "a.js", "if ('a.js' != import.meta.url) throw 'hmm'\n" - "libdeno.send(new Uint8Array([4]));"); + "Deno.core.send(new Uint8Array([4]));"); EXPECT_NE(a, 0); EXPECT_EQ(nullptr, deno_last_exception(d)); diff --git a/tsconfig.json b/tsconfig.json index bece2b31..e79023de 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,5 +22,11 @@ "target": "esnext", "types": [] }, - "files": ["js/lib.web_assembly.d.ts", "js/main.ts", "js/compiler.ts"] + "files": [ + "js/lib.web_assembly.d.ts", + "core/core.d.ts", + "libdeno/libdeno.d.ts", + "js/main.ts", + "js/compiler.ts" + ] } -- GitLab