Organize libdeno functions.

This commit is contained in:
Ryan Dahl 2018-08-06 18:37:32 -04:00
parent 4a1ccdeadb
commit 51380bf399
12 changed files with 94 additions and 77 deletions

View file

@ -97,10 +97,14 @@ function stringifyArgs(args: any[]): string {
return out.join(" ");
}
type PrintFunc = (x: string) => void;
export class Console {
constructor(private printFunc: PrintFunc) {}
// tslint:disable-next-line:no-any
log(...args: any[]): void {
deno.print(stringifyArgs(args));
this.printFunc(stringifyArgs(args));
}
debug = this.log;
@ -108,7 +112,7 @@ export class Console {
// tslint:disable-next-line:no-any
warn(...args: any[]): void {
deno.print(`ERROR: ${stringifyArgs(args)}`);
this.printFunc(`ERROR: ${stringifyArgs(args)}`);
}
error = this.warn;

View file

@ -2,4 +2,5 @@
// Public deno module.
// TODO get rid of deno.d.ts
// export { pub, sub } from "./dispatch";
export { readFileSync, writeFileSync } from "./os";
export { readFileSync } from "./os";
export { libdeno } from "./globals";

View file

@ -1,22 +1,14 @@
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
import { Console } from "./console";
import { RawSourceMap } from "./types";
declare global {
type MessageCallback = (msg: Uint8Array) => void;
interface Deno {
print(text: string): void;
recv(cb: MessageCallback): void;
send(msg: ArrayBufferView): Uint8Array | null;
}
interface Window {
console: Console;
}
const console: Console;
const deno: Readonly<Deno>;
const window: Window;
}
@ -28,10 +20,21 @@ declare global {
export const globalEval = eval;
// A reference to the global object.
// TODO The underscore is because it's conflicting with @types/node.
export const window = globalEval("this");
window.window = window;
// The libdeno functions are moved so that users can't access them.
type MessageCallback = (msg: Uint8Array) => void;
interface Libdeno {
recv(cb: MessageCallback): void;
send(msg: ArrayBufferView): null | Uint8Array;
print(x: string): void;
mainSource: string;
mainSourceMap: RawSourceMap;
}
export const libdeno = window.libdeno as Libdeno;
window.libdeno = null;
window["window"] = window; // Create a window object.
// import "./url";
// import * as timer from "./timers";
@ -40,7 +43,7 @@ window["window"] = window; // Create a window object.
// window["clearTimeout"] = timer.clearTimer;
// window["clearInterval"] = timer.clearTimer;
window["console"] = new Console();
window.console = new Console(libdeno.print);
// import { fetch } from "./fetch";
// window["fetch"] = fetch;

16
js/lib.globals.d.ts vendored
View file

@ -1,19 +1,5 @@
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
// This file contains the default TypeScript libraries for the runtime
// This file contains the default TypeScript libraries for the deno runtime.
/// <reference no-default-lib="true"/>
/// <reference lib="esnext" />
import "gen/js/globals";
interface Window {
// TODO(ry) These shouldn't be global.
mainSource: string;
setMainSourceMap(sm: string): void;
}
// TODO(ry) These shouldn't be global.
declare let mainSource: string;
declare function setMainSourceMap(sm: string): void;

View file

@ -1,9 +1,9 @@
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
// tslint:disable-next-line:no-reference
import { flatbuffers } from "flatbuffers";
import { deno as fbs } from "gen/msg_generated";
import { assert, log, assignCmdId } from "./util";
import * as runtime from "./runtime";
import { libdeno } from "./globals";
function startMsg(cmdId: number): Uint8Array {
const builder = new flatbuffers.Builder();
@ -25,7 +25,7 @@ export default function denoMain() {
// are ready. The response should be a "StartRes" message containing the CLI
// argv and other info.
const cmdId = assignCmdId();
const res = deno.send(startMsg(cmdId));
const res = libdeno.send(startMsg(cmdId));
// TODO(ry) Remove this conditional once main.rs gets up to speed.
if (res == null) {

View file

@ -10,7 +10,7 @@ function assert(cond) {
}
global.CanCallFunction = () => {
deno.print("Hello world from foo");
libdeno.print("Hello world from foo");
return "foo";
};
@ -26,13 +26,13 @@ global.TypedArraySnapshots = () => {
};
global.SendSuccess = () => {
deno.recv(msg => {
deno.print("SendSuccess: ok");
libdeno.recv(msg => {
libdeno.print("SendSuccess: ok");
});
};
global.SendWrongByteLength = () => {
deno.recv(msg => {
libdeno.recv(msg => {
assert(msg.byteLength === 3);
});
};
@ -40,15 +40,15 @@ global.SendWrongByteLength = () => {
global.RecvReturnEmpty = () => {
const m1 = new Uint8Array("abc".split("").map(c => c.charCodeAt(0)));
const m2 = m1.slice();
const r1 = deno.send(m1);
const r1 = libdeno.send(m1);
assert(r1 == null);
const r2 = deno.send(m2);
const r2 = libdeno.send(m2);
assert(r2 == null);
};
global.RecvReturnBar = () => {
const m = new Uint8Array("abc".split("").map(c => c.charCodeAt(0)));
const r = deno.send(m);
const r = libdeno.send(m);
assert(r instanceof Uint8Array);
assert(r.byteLength === 3);
const rstr = String.fromCharCode(...r);
@ -56,10 +56,10 @@ global.RecvReturnBar = () => {
};
global.DoubleRecvFails = () => {
// deno.recv is an internal function and should only be called once from the
// libdeno.recv is an internal function and should only be called once from the
// runtime.
deno.recv((channel, msg) => assert(false));
deno.recv((channel, msg) => assert(false));
libdeno.recv((channel, msg) => assert(false));
libdeno.recv((channel, msg) => assert(false));
};
global.SendRecvSlice = () => {
@ -70,7 +70,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.send(buf);
buf = libdeno.send(buf);
assert(buf.byteOffset === i * 11);
assert(buf.byteLength === abLen - i * 30 - 19);
assert(buf.buffer.byteLength == abLen);
@ -90,17 +90,17 @@ global.JSSendArrayBufferViewTypes = () => {
const ab1 = new ArrayBuffer(4321);
const u8 = new Uint8Array(ab1, 2468, 1000);
u8[0] = 1;
deno.send(u8);
libdeno.send(u8);
// Send Uint32Array.
const ab2 = new ArrayBuffer(4321);
const u32 = new Uint32Array(ab2, 2468, 1000 / Uint32Array.BYTES_PER_ELEMENT);
u32[0] = 0x02020202;
deno.send(u32);
libdeno.send(u32);
// Send DataView.
const ab3 = new ArrayBuffer(4321);
const dv = new DataView(ab3, 2468, 1000);
dv.setUint8(0, 3);
deno.send(dv);
libdeno.send(dv);
};
global.JSSendNeutersBuffer = () => {
@ -109,7 +109,7 @@ global.JSSendNeutersBuffer = () => {
assert(u8.byteLength === 1);
assert(u8.buffer.byteLength === 1);
assert(u8[0] === 42);
const r = deno.send(u8);
const r = libdeno.send(u8);
assert(u8.byteLength === 0);
assert(u8.buffer.byteLength === 0);
assert(u8[0] === undefined);
@ -124,19 +124,19 @@ global.SnapshotBug = () => {
global.ErrorHandling = () => {
global.onerror = (message, source, line, col, error) => {
deno.print(`line ${line} col ${col}`);
libdeno.print(`line ${line} col ${col}`);
assert("ReferenceError: notdefined is not defined" === message);
assert(source === "helloworld.js");
assert(line === 3);
assert(col === 1);
assert(error instanceof Error);
deno.send(new Uint8Array([42]));
libdeno.send(new Uint8Array([42]));
};
eval("\n\n notdefined()\n//# sourceURL=helloworld.js");
};
global.SendNullAllocPtr = () => {
deno.recv(msg => {
libdeno.recv(msg => {
assert(msg instanceof Uint8Array);
assert(msg.byteLength === 4);
assert(msg[0] === "a".charCodeAt(0));

View file

@ -4,6 +4,7 @@ import { deno as fbs } from "gen/msg_generated";
import { assert } from "./util";
import * as util from "./util";
import { flatbuffers } from "flatbuffers";
import { libdeno } from "./globals";
export function exit(exitCode = 0): never {
const builder = new flatbuffers.Builder();
@ -14,7 +15,7 @@ export function exit(exitCode = 0): never {
fbs.Base.addMsg(builder, msg);
fbs.Base.addMsgType(builder, fbs.Any.Exit);
builder.finish(fbs.Base.endBase(builder));
deno.send(builder.asUint8Array());
libdeno.send(builder.asUint8Array());
throw Error("Unreachable");
}
@ -35,7 +36,7 @@ export function codeFetch(
fbs.Base.addMsg(builder, msg);
fbs.Base.addMsgType(builder, fbs.Any.CodeFetch);
builder.finish(fbs.Base.endBase(builder));
const resBuf = deno.send(builder.asUint8Array());
const resBuf = libdeno.send(builder.asUint8Array());
// Process CodeFetchRes
const bb = new flatbuffers.ByteBuffer(new Uint8Array(resBuf));
const baseRes = fbs.Base.getRootAsBase(bb);
@ -73,7 +74,7 @@ export function codeCache(
fbs.Base.addMsg(builder, msg);
fbs.Base.addMsgType(builder, fbs.Any.CodeCache);
builder.finish(fbs.Base.endBase(builder));
const resBuf = deno.send(builder.asUint8Array());
const resBuf = libdeno.send(builder.asUint8Array());
// Expect null or error.
if (resBuf != null) {
const bb = new flatbuffers.ByteBuffer(new Uint8Array(resBuf));

View file

@ -13,8 +13,9 @@ import { log } from "./util";
import { assetSourceCode } from "./assets";
import * as os from "./os";
import * as sourceMaps from "./v8_source_maps";
import { window, globalEval } from "./globals";
//import * as deno from "./deno";
import { libdeno, window, globalEval } from "./globals";
import * as deno from "./deno";
import { RawSourceMap } from "./types";
const EOL = "\n";
const ASSETS = "/$asset$/";
@ -40,26 +41,16 @@ window.onerror = (
os.exit(1);
};
// This is called during snapshot creation with the contents of
// out/debug/gen/bundle/main.js.map.
import { RawSourceMap } from "source-map";
let mainSourceMap: RawSourceMap = null;
function setMainSourceMap(rawSourceMap: RawSourceMap) {
util.assert(Number(rawSourceMap.version) === 3);
mainSourceMap = rawSourceMap;
}
window["setMainSourceMap"] = setMainSourceMap;
export function setup(): void {
sourceMaps.install({
installPrepareStackTrace: true,
getGeneratedContents: (filename: string): string | RawSourceMap => {
util.log("getGeneratedContents", filename);
if (filename === "gen/bundle/main.js") {
util.assert(window["mainSource"].length > 0);
return window["mainSource"];
util.assert(libdeno.mainSource.length > 0);
return libdeno.mainSource;
} else if (filename === "main.js.map") {
return mainSourceMap;
return libdeno.mainSourceMap;
} else if (filename === "deno_main.js") {
return "";
} else {

13
js/types.d.ts vendored
View file

@ -116,6 +116,19 @@ export interface CallSite {
isConstructor(): boolean;
}
export interface StartOfSourceMap {
file?: string;
sourceRoot?: string;
}
export interface RawSourceMap extends StartOfSourceMap {
version: string;
sources: string[];
names: string[];
sourcesContent?: string[];
mappings: string;
}
declare global {
// Declare "static" methods in Error
interface ErrorConstructor {

View file

@ -3,10 +3,9 @@
// Originated from source-map-support but has been heavily modified for deno.
import { SourceMapConsumer, MappedPosition } from "source-map";
import { RawSourceMap } from "source-map";
import * as base64 from "base64-js";
import { arrayToStr } from "./util";
import { CallSite } from "./types";
import { CallSite, RawSourceMap } from "./types";
const consumers = new Map<string, SourceMapConsumer>();

View file

@ -103,6 +103,7 @@ void HandleException(v8::Local<v8::Context> context,
d->last_exception = exception_str;
} else {
printf("Pre-Deno Exception %s\n", exception_str.c_str());
exit(1);
}
}
@ -278,7 +279,7 @@ void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context,
auto global = context->Global();
auto deno_val = v8::Object::New(isolate);
CHECK(global->Set(context, deno::v8_str("deno"), deno_val).FromJust());
CHECK(global->Set(context, deno::v8_str("libdeno"), deno_val).FromJust());
auto print_tmpl = v8::FunctionTemplate::New(isolate, Print);
auto print_val = print_tmpl->GetFunction(context).ToLocalChecked();
@ -295,17 +296,34 @@ void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context,
skip_onerror = true;
{
auto source = deno::v8_str(js_source.c_str());
CHECK(global->Set(context, deno::v8_str("mainSource"), source).FromJust());
CHECK(
deno_val->Set(context, deno::v8_str("mainSource"), source).FromJust());
bool r = deno::ExecuteV8StringSource(context, js_filename, source);
CHECK(r);
if (source_map != nullptr) {
CHECK_GT(source_map->length(), 1u);
std::string set_source_map = "setMainSourceMap( " + *source_map + " )";
CHECK_GT(set_source_map.length(), source_map->length());
r = deno::Execute(context, "set_source_map.js", set_source_map.c_str());
CHECK(r);
v8::TryCatch try_catch(isolate);
v8::ScriptOrigin origin(v8_str("set_source_map.js"));
std::string source_map_parens = "(" + *source_map + ")";
auto source_map_v8_str = deno::v8_str(source_map_parens.c_str());
auto script = v8::Script::Compile(context, source_map_v8_str, &origin);
if (script.IsEmpty()) {
DCHECK(try_catch.HasCaught());
HandleException(context, try_catch.Exception());
return;
}
auto source_map_obj = script.ToLocalChecked()->Run(context);
if (source_map_obj.IsEmpty()) {
DCHECK(try_catch.HasCaught());
HandleException(context, try_catch.Exception());
return;
}
CHECK(deno_val
->Set(context, deno::v8_str("mainSourceMap"),
source_map_obj.ToLocalChecked())
.FromJust());
}
}
skip_onerror = false;

View file

@ -189,7 +189,8 @@ impl DenoDir {
base.join(module_specifier)?
};
let mut p = j.to_file_path()
let mut p = j
.to_file_path()
.unwrap()
.into_os_string()
.into_string()