mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 23:34:47 -05:00
Execute JS for the first time in Rust rewrite.
Implements code_fetch handler in Rust. Add ability to embed string assets (for typescript declaration files) Remove deno_cc and deno_cc_nosnapshot targets.
This commit is contained in:
parent
8a4e3dfda4
commit
3e51605bc9
17 changed files with 514 additions and 205 deletions
|
@ -47,7 +47,7 @@ script:
|
||||||
- ./tools/lint.py
|
- ./tools/lint.py
|
||||||
- $BUILD_PATH/test_cc
|
- $BUILD_PATH/test_cc
|
||||||
- $BUILD_PATH/handlers_test
|
- $BUILD_PATH/handlers_test
|
||||||
- $BUILD_PATH/deno_cc foo bar
|
- $BUILD_PATH/deno ./testdata/001_hello.js
|
||||||
- $BUILD_PATH/deno_cc_nosnapshot foo bar
|
- $BUILD_PATH/deno ./testdata/002_hello.ts
|
||||||
- $BUILD_PATH/deno meow
|
- $BUILD_PATH/deno_nosnapshot ./testdata/001_hello.js
|
||||||
- $BUILD_PATH/deno_nosnapshot meow
|
- $BUILD_PATH/deno_nosnapshot ./testdata/002_hello.ts
|
||||||
|
|
35
BUILD.gn
35
BUILD.gn
|
@ -8,8 +8,6 @@ group("all") {
|
||||||
testonly = true
|
testonly = true
|
||||||
deps = [
|
deps = [
|
||||||
":deno",
|
":deno",
|
||||||
":deno_cc",
|
|
||||||
":deno_cc_nosnapshot",
|
|
||||||
":deno_nosnapshot",
|
":deno_nosnapshot",
|
||||||
":handlers_test",
|
":handlers_test",
|
||||||
":test_cc",
|
":test_cc",
|
||||||
|
@ -61,35 +59,6 @@ rust_test("handlers_test") {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
executable("deno_cc") {
|
|
||||||
sources = [
|
|
||||||
"src/main.cc",
|
|
||||||
]
|
|
||||||
deps = [
|
|
||||||
":flatbufferjs",
|
|
||||||
":handlers",
|
|
||||||
":libdeno",
|
|
||||||
":msg_cpp",
|
|
||||||
]
|
|
||||||
configs += [ ":deno_config" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
# This target is for fast incremental development.
|
|
||||||
# When modifying the javascript runtime, this target will not go through the
|
|
||||||
# extra process of building a snapshot and instead load the bundle from disk.
|
|
||||||
executable("deno_cc_nosnapshot") {
|
|
||||||
sources = [
|
|
||||||
"src/main.cc",
|
|
||||||
]
|
|
||||||
deps = [
|
|
||||||
":flatbufferjs",
|
|
||||||
":handlers",
|
|
||||||
":libdeno_nosnapshot",
|
|
||||||
":msg_cpp",
|
|
||||||
]
|
|
||||||
configs += [ ":deno_config" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
executable("test_cc") {
|
executable("test_cc") {
|
||||||
testonly = true
|
testonly = true
|
||||||
sources = [
|
sources = [
|
||||||
|
@ -154,9 +123,12 @@ v8_source_set("deno_bindings") {
|
||||||
sources = [
|
sources = [
|
||||||
"src/flatbuffer_builder.cc",
|
"src/flatbuffer_builder.cc",
|
||||||
"src/flatbuffer_builder.h",
|
"src/flatbuffer_builder.h",
|
||||||
|
"src/reply.cc",
|
||||||
|
"src/reply.h",
|
||||||
]
|
]
|
||||||
deps = [
|
deps = [
|
||||||
":deno_base",
|
":deno_base",
|
||||||
|
":handlers",
|
||||||
":msg_cpp",
|
":msg_cpp",
|
||||||
]
|
]
|
||||||
public_deps = [
|
public_deps = [
|
||||||
|
@ -184,6 +156,7 @@ flatbuffer("msg_cpp") {
|
||||||
run_node("bundle") {
|
run_node("bundle") {
|
||||||
out_dir = "$target_gen_dir/bundle/"
|
out_dir = "$target_gen_dir/bundle/"
|
||||||
sources = [
|
sources = [
|
||||||
|
"js/assets.ts",
|
||||||
"js/console.ts",
|
"js/console.ts",
|
||||||
"js/deno.d.ts",
|
"js/deno.d.ts",
|
||||||
"js/dispatch.ts",
|
"js/dispatch.ts",
|
||||||
|
|
51
js/assets.ts
Normal file
51
js/assets.ts
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright 2018 Ryan Dahl <ry@tinyclouds.org>
|
||||||
|
// All rights reserved. MIT License.
|
||||||
|
|
||||||
|
// This file is formatted as it is because we are using the fact that Parcel
|
||||||
|
// statically evaluates fs.readFileSync.
|
||||||
|
import { readFileSync } from "fs";
|
||||||
|
|
||||||
|
// tslint:disable:max-line-length
|
||||||
|
// prettier-ignore
|
||||||
|
export const assetSourceCode: { [key: string]: string } = {
|
||||||
|
"deno.d.ts": readFileSync(__dirname + "/deno.d.ts", "utf8"),
|
||||||
|
"lib.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.d.ts", "utf8"),
|
||||||
|
//"lib.dom.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.dom.d.ts", "utf8"),
|
||||||
|
"lib.dom.iterable.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.dom.iterable.d.ts", "utf8"),
|
||||||
|
"lib.es2015.collection.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2015.collection.d.ts", "utf8"),
|
||||||
|
"lib.es2015.core.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2015.core.d.ts", "utf8"),
|
||||||
|
//"lib.es2015.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2015.d.ts", "utf8"),
|
||||||
|
"lib.es2015.generator.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2015.generator.d.ts", "utf8"),
|
||||||
|
"lib.es2015.iterable.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2015.iterable.d.ts", "utf8"),
|
||||||
|
"lib.es2015.promise.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2015.promise.d.ts", "utf8"),
|
||||||
|
"lib.es2015.proxy.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2015.proxy.d.ts", "utf8"),
|
||||||
|
"lib.es2015.reflect.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2015.reflect.d.ts", "utf8"),
|
||||||
|
"lib.es2015.symbol.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2015.symbol.d.ts", "utf8"),
|
||||||
|
"lib.es2015.symbol.wellknown.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts", "utf8"),
|
||||||
|
"lib.es2016.array.include.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2016.array.include.d.ts", "utf8"),
|
||||||
|
//"lib.es2016.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2016.d.ts", "utf8"),
|
||||||
|
//"lib.es2016.full.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2016.full.d.ts", "utf8"),
|
||||||
|
//"lib.es2017.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2017.d.ts", "utf8"),
|
||||||
|
//"lib.es2017.full.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2017.full.d.ts", "utf8"),
|
||||||
|
"lib.es2017.intl.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2017.intl.d.ts", "utf8"),
|
||||||
|
"lib.es2017.object.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2017.object.d.ts", "utf8"),
|
||||||
|
"lib.es2017.sharedmemory.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts", "utf8"),
|
||||||
|
"lib.es2017.string.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2017.string.d.ts", "utf8"),
|
||||||
|
"lib.es2017.typedarrays.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts", "utf8"),
|
||||||
|
"lib.es2018.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2018.d.ts", "utf8"),
|
||||||
|
//"lib.es2018.full.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2018.full.d.ts", "utf8"),
|
||||||
|
"lib.es2018.promise.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2018.promise.d.ts", "utf8"),
|
||||||
|
"lib.es2018.regexp.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es2018.regexp.d.ts", "utf8"),
|
||||||
|
//"lib.es5.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es5.d.ts", "utf8"),
|
||||||
|
//"lib.es6.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.es6.d.ts", "utf8"),
|
||||||
|
"lib.esnext.array.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.esnext.array.d.ts", "utf8"),
|
||||||
|
"lib.esnext.asynciterable.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.esnext.asynciterable.d.ts", "utf8"),
|
||||||
|
"lib.esnext.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.esnext.d.ts", "utf8"),
|
||||||
|
//"lib.esnext.full.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.esnext.full.d.ts", "utf8"),
|
||||||
|
//"lib.scripthost.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.scripthost.d.ts", "utf8"),
|
||||||
|
//"lib.webworker.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/lib.webworker.d.ts", "utf8"),
|
||||||
|
//"protocol.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/protocol.d.ts", "utf8"),
|
||||||
|
//"tsserverlibrary.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/tsserverlibrary.d.ts", "utf8"),
|
||||||
|
"typescript.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/typescript.d.ts", "utf8"),
|
||||||
|
//"typescriptServices.d.ts": readFileSync(__dirname + "/../third_party/node_modules/typescript/lib/typescriptServices.d.ts", "utf8"),
|
||||||
|
};
|
17
js/main.ts
17
js/main.ts
|
@ -1,12 +1,9 @@
|
||||||
// tslint:disable-next-line:no-reference
|
// tslint:disable-next-line:no-reference
|
||||||
/// <reference path="deno.d.ts" />
|
/// <reference path="deno.d.ts" />
|
||||||
import * as ts from "typescript";
|
|
||||||
|
|
||||||
import { flatbuffers } from "flatbuffers";
|
import { flatbuffers } from "flatbuffers";
|
||||||
import { deno as fbs } from "./msg_generated";
|
import { deno as fbs } from "./msg_generated";
|
||||||
import { assert } from "./util";
|
import { assert, log } from "./util";
|
||||||
|
import * as runtime from "./runtime";
|
||||||
// import * as runtime from "./runtime";
|
|
||||||
|
|
||||||
const globalEval = eval;
|
const globalEval = eval;
|
||||||
const window = globalEval("this");
|
const window = globalEval("this");
|
||||||
|
@ -31,8 +28,6 @@ function startMsg(cmdId: number): Uint8Array {
|
||||||
}
|
}
|
||||||
|
|
||||||
window["denoMain"] = () => {
|
window["denoMain"] = () => {
|
||||||
deno.print(`ts.version: ${ts.version}`);
|
|
||||||
|
|
||||||
// First we send an empty "Start" message to let the privlaged side know we
|
// First we send an empty "Start" message to let the privlaged side know we
|
||||||
// are ready. The response should be a "StartRes" message containing the CLI
|
// are ready. The response should be a "StartRes" message containing the CLI
|
||||||
// argv and other info.
|
// argv and other info.
|
||||||
|
@ -55,17 +50,15 @@ window["denoMain"] = () => {
|
||||||
assert(base.msg(startResMsg) != null);
|
assert(base.msg(startResMsg) != null);
|
||||||
|
|
||||||
const cwd = startResMsg.cwd();
|
const cwd = startResMsg.cwd();
|
||||||
deno.print(`cwd: ${cwd}`);
|
log("cwd", cwd);
|
||||||
|
|
||||||
const argv: string[] = [];
|
const argv: string[] = [];
|
||||||
for (let i = 0; i < startResMsg.argvLength(); i++) {
|
for (let i = 0; i < startResMsg.argvLength(); i++) {
|
||||||
argv.push(startResMsg.argv(i));
|
argv.push(startResMsg.argv(i));
|
||||||
}
|
}
|
||||||
deno.print(`argv ${argv}`);
|
log("argv", argv);
|
||||||
|
|
||||||
/* TODO(ry) Uncomment to test further message passing.
|
const inputFn = argv[1];
|
||||||
const inputFn = argv[0];
|
|
||||||
const mod = runtime.resolveModule(inputFn, `${cwd}/`);
|
const mod = runtime.resolveModule(inputFn, `${cwd}/`);
|
||||||
mod.compileAndRun();
|
mod.compileAndRun();
|
||||||
*/
|
|
||||||
};
|
};
|
||||||
|
|
32
js/os.ts
32
js/os.ts
|
@ -2,7 +2,8 @@
|
||||||
// All rights reserved. MIT License.
|
// All rights reserved. MIT License.
|
||||||
import { ModuleInfo } from "./types";
|
import { ModuleInfo } from "./types";
|
||||||
import { deno as fbs } from "./msg_generated";
|
import { deno as fbs } from "./msg_generated";
|
||||||
import { assert, typedArrayToArrayBuffer } from "./util";
|
import { assert } from "./util";
|
||||||
|
import * as util from "./util";
|
||||||
import { flatbuffers } from "flatbuffers";
|
import { flatbuffers } from "flatbuffers";
|
||||||
|
|
||||||
export function exit(exitCode = 0): void {
|
export function exit(exitCode = 0): void {
|
||||||
|
@ -19,8 +20,7 @@ export function codeFetch(
|
||||||
moduleSpecifier: string,
|
moduleSpecifier: string,
|
||||||
containingFile: string
|
containingFile: string
|
||||||
): ModuleInfo {
|
): ModuleInfo {
|
||||||
console.log("Hello from codeFetch");
|
util.log("os.ts codeFetch", moduleSpecifier, containingFile);
|
||||||
|
|
||||||
// Send CodeFetch message
|
// Send CodeFetch message
|
||||||
const builder = new flatbuffers.Builder();
|
const builder = new flatbuffers.Builder();
|
||||||
const moduleSpecifier_ = builder.createString(moduleSpecifier);
|
const moduleSpecifier_ = builder.createString(moduleSpecifier);
|
||||||
|
@ -33,23 +33,23 @@ export function codeFetch(
|
||||||
fbs.Base.addMsg(builder, msg);
|
fbs.Base.addMsg(builder, msg);
|
||||||
fbs.Base.addMsgType(builder, fbs.Any.CodeFetch);
|
fbs.Base.addMsgType(builder, fbs.Any.CodeFetch);
|
||||||
builder.finish(fbs.Base.endBase(builder));
|
builder.finish(fbs.Base.endBase(builder));
|
||||||
const payload = typedArrayToArrayBuffer(builder.asUint8Array());
|
const resBuf = deno.send(builder.asUint8Array());
|
||||||
const resBuf = deno.send("x", payload);
|
|
||||||
|
|
||||||
console.log("CodeFetch sent");
|
|
||||||
|
|
||||||
// Process CodeFetchRes
|
// Process CodeFetchRes
|
||||||
const bb = new flatbuffers.ByteBuffer(new Uint8Array(resBuf));
|
const bb = new flatbuffers.ByteBuffer(new Uint8Array(resBuf));
|
||||||
const baseRes = fbs.Base.getRootAsBase(bb);
|
const baseRes = fbs.Base.getRootAsBase(bb);
|
||||||
|
if (fbs.Any.NONE === baseRes.msgType()) {
|
||||||
|
throw Error(baseRes.error());
|
||||||
|
}
|
||||||
assert(fbs.Any.CodeFetchRes === baseRes.msgType());
|
assert(fbs.Any.CodeFetchRes === baseRes.msgType());
|
||||||
const codeFetchRes = new fbs.CodeFetchRes();
|
const codeFetchRes = new fbs.CodeFetchRes();
|
||||||
assert(baseRes.msg(codeFetchRes) != null);
|
assert(baseRes.msg(codeFetchRes) != null);
|
||||||
return {
|
const r = {
|
||||||
moduleName: codeFetchRes.moduleName(),
|
moduleName: codeFetchRes.moduleName(),
|
||||||
filename: codeFetchRes.filename(),
|
filename: codeFetchRes.filename(),
|
||||||
sourceCode: codeFetchRes.sourceCode(),
|
sourceCode: codeFetchRes.sourceCode(),
|
||||||
outputCode: codeFetchRes.outputCode()
|
outputCode: codeFetchRes.outputCode()
|
||||||
};
|
};
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function codeCache(
|
export function codeCache(
|
||||||
|
@ -57,28 +57,22 @@ export function codeCache(
|
||||||
sourceCode: string,
|
sourceCode: string,
|
||||||
outputCode: string
|
outputCode: string
|
||||||
): void {
|
): void {
|
||||||
|
util.log("os.ts codeCache", filename, sourceCode, outputCode);
|
||||||
const builder = new flatbuffers.Builder();
|
const builder = new flatbuffers.Builder();
|
||||||
|
|
||||||
const filename_ = builder.createString(filename);
|
const filename_ = builder.createString(filename);
|
||||||
const sourceCode_ = builder.createString(sourceCode);
|
const sourceCode_ = builder.createString(sourceCode);
|
||||||
const outputCode_ = builder.createString(outputCode);
|
const outputCode_ = builder.createString(outputCode);
|
||||||
|
|
||||||
fbs.CodeCache.startCodeCache(builder);
|
fbs.CodeCache.startCodeCache(builder);
|
||||||
fbs.CodeCache.addFilename(builder, filename_);
|
fbs.CodeCache.addFilename(builder, filename_);
|
||||||
fbs.CodeCache.addSourceCode(builder, sourceCode_);
|
fbs.CodeCache.addSourceCode(builder, sourceCode_);
|
||||||
fbs.CodeCache.addOutputCode(builder, outputCode_);
|
fbs.CodeCache.addOutputCode(builder, outputCode_);
|
||||||
const msg = fbs.CodeCache.endCodeCache(builder);
|
const msg = fbs.CodeCache.endCodeCache(builder);
|
||||||
|
|
||||||
fbs.Base.startBase(builder);
|
fbs.Base.startBase(builder);
|
||||||
fbs.Base.addMsg(builder, msg);
|
fbs.Base.addMsg(builder, msg);
|
||||||
|
fbs.Base.addMsgType(builder, fbs.Any.CodeCache);
|
||||||
builder.finish(fbs.Base.endBase(builder));
|
builder.finish(fbs.Base.endBase(builder));
|
||||||
|
const resBuf = deno.send(builder.asUint8Array());
|
||||||
// Maybe need to do another step?
|
assert(resBuf == null);
|
||||||
// Base.finishBaseBuffer(builder, base);
|
|
||||||
|
|
||||||
const payload = typedArrayToArrayBuffer(builder.asUint8Array());
|
|
||||||
const resBuf = deno.send("x", payload);
|
|
||||||
assert(resBuf === null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function readFileSync(filename: string): Uint8Array {
|
export function readFileSync(filename: string): Uint8Array {
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
import * as ts from "typescript";
|
import * as ts from "typescript";
|
||||||
import * as util from "./util";
|
import * as util from "./util";
|
||||||
import { log } from "./util";
|
import { log } from "./util";
|
||||||
|
import { assetSourceCode } from "./assets";
|
||||||
import * as os from "./os";
|
import * as os from "./os";
|
||||||
//import * as sourceMaps from "./v8_source_maps";
|
//import * as sourceMaps from "./v8_source_maps";
|
||||||
import { window, globalEval } from "./globals";
|
import { window, globalEval } from "./globals";
|
||||||
|
@ -22,9 +23,14 @@ const EOL = "\n";
|
||||||
export type AmdFactory = (...args: any[]) => undefined | object;
|
export type AmdFactory = (...args: any[]) => undefined | object;
|
||||||
export type AmdDefine = (deps: string[], factory: AmdFactory) => void;
|
export type AmdDefine = (deps: string[], factory: AmdFactory) => void;
|
||||||
|
|
||||||
/*
|
|
||||||
// Uncaught exceptions are sent to window.onerror by the privlaged binding.
|
// Uncaught exceptions are sent to window.onerror by the privlaged binding.
|
||||||
window.onerror = (message, source, lineno, colno, error) => {
|
window.onerror = (
|
||||||
|
message: string,
|
||||||
|
source: string,
|
||||||
|
lineno: number,
|
||||||
|
colno: number,
|
||||||
|
error: Error
|
||||||
|
) => {
|
||||||
// TODO Currently there is a bug in v8_source_maps.ts that causes a segfault
|
// TODO Currently there is a bug in v8_source_maps.ts that causes a segfault
|
||||||
// if it is used within window.onerror. To workaround we uninstall the
|
// if it is used within window.onerror. To workaround we uninstall the
|
||||||
// Error.prepareStackTrace handler. Users will get unmapped stack traces on
|
// Error.prepareStackTrace handler. Users will get unmapped stack traces on
|
||||||
|
@ -33,7 +39,6 @@ window.onerror = (message, source, lineno, colno, error) => {
|
||||||
console.log(error.message, error.stack);
|
console.log(error.message, error.stack);
|
||||||
os.exit(1);
|
os.exit(1);
|
||||||
};
|
};
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
export function setup(mainJs: string, mainMap: string): void {
|
export function setup(mainJs: string, mainMap: string): void {
|
||||||
|
@ -147,11 +152,31 @@ export function resolveModule(
|
||||||
): null | FileModule {
|
): null | FileModule {
|
||||||
util.log("resolveModule", { moduleSpecifier, containingFile });
|
util.log("resolveModule", { moduleSpecifier, containingFile });
|
||||||
util.assert(moduleSpecifier != null && moduleSpecifier.length > 0);
|
util.assert(moduleSpecifier != null && moduleSpecifier.length > 0);
|
||||||
// We ask golang to sourceCodeFetch. It will load the sourceCode and if
|
let filename: string, sourceCode: string, outputCode: string;
|
||||||
// there is any outputCode cached, it will return that as well.
|
if (
|
||||||
const fetchResponse = os.codeFetch(moduleSpecifier, containingFile);
|
moduleSpecifier.startsWith("/$asset$/") ||
|
||||||
const { filename, sourceCode, outputCode } = fetchResponse;
|
containingFile.startsWith("/$asset$/")
|
||||||
if (sourceCode.length === 0) {
|
) {
|
||||||
|
// Assets are compiled into the runtime javascript bundle.
|
||||||
|
const assetName = moduleSpecifier.split("/").pop();
|
||||||
|
sourceCode = assetSourceCode[assetName];
|
||||||
|
filename = "/$asset$/" + assetName;
|
||||||
|
} else {
|
||||||
|
// We query Rust with a CodeFetch message. It will load the sourceCode, and
|
||||||
|
// if there is any outputCode cached, will return that as well.
|
||||||
|
let fetchResponse;
|
||||||
|
try {
|
||||||
|
fetchResponse = os.codeFetch(moduleSpecifier, containingFile);
|
||||||
|
} catch (e) {
|
||||||
|
// TODO Only catch "no such file or directory" errors. Need error codes.
|
||||||
|
util.log("os.codeFetch error ignored", e.message);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
filename = fetchResponse.filename;
|
||||||
|
sourceCode = fetchResponse.sourceCode;
|
||||||
|
outputCode = fetchResponse.outputCode;
|
||||||
|
}
|
||||||
|
if (sourceCode == null || sourceCode.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
util.log("resolveModule sourceCode length ", sourceCode.length);
|
util.log("resolveModule sourceCode length ", sourceCode.length);
|
||||||
|
@ -293,7 +318,7 @@ class TypeScriptHost implements ts.LanguageServiceHost {
|
||||||
}
|
}
|
||||||
|
|
||||||
getDefaultLibFileName(options: ts.CompilerOptions): string {
|
getDefaultLibFileName(options: ts.CompilerOptions): string {
|
||||||
const fn = ts.getDefaultLibFileName(options);
|
const fn = "lib.d.ts"; // ts.getDefaultLibFileName(options);
|
||||||
util.log("getDefaultLibFileName", fn);
|
util.log("getDefaultLibFileName", fn);
|
||||||
const m = resolveModule(fn, "/$asset$/");
|
const m = resolveModule(fn, "/$asset$/");
|
||||||
return m.fileName;
|
return m.fileName;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// All rights reserved. MIT License.
|
// All rights reserved. MIT License.
|
||||||
|
|
||||||
//import { debug } from "./main";
|
//import { debug } from "./main";
|
||||||
const debug = true;
|
const debug = false;
|
||||||
|
|
||||||
import { TypedArray } from "./types";
|
import { TypedArray } from "./types";
|
||||||
|
|
||||||
|
|
|
@ -301,8 +301,20 @@ void deno_init() {
|
||||||
|
|
||||||
const char* deno_v8_version() { return v8::V8::GetVersion(); }
|
const char* deno_v8_version() { return v8::V8::GetVersion(); }
|
||||||
|
|
||||||
|
// TODO(ry) Remove these when we call deno_reply_start from Rust.
|
||||||
|
static char** global_argv;
|
||||||
|
static int global_argc;
|
||||||
|
char** deno_argv() { return global_argv; }
|
||||||
|
int deno_argc() { return global_argc; }
|
||||||
|
|
||||||
void deno_set_flags(int* argc, char** argv) {
|
void deno_set_flags(int* argc, char** argv) {
|
||||||
v8::V8::SetFlagsFromCommandLine(argc, argv, true);
|
v8::V8::SetFlagsFromCommandLine(argc, argv, true);
|
||||||
|
// TODO(ry) Remove these when we call deno_reply_start from Rust.
|
||||||
|
global_argc = *argc;
|
||||||
|
global_argv = reinterpret_cast<char**>(malloc(*argc * sizeof(char*)));
|
||||||
|
for (int i = 0; i < *argc; i++) {
|
||||||
|
global_argv[i] = strdup(argv[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* deno_last_exception(Deno* d) { return d->last_exception.c_str(); }
|
const char* deno_last_exception(Deno* d) { return d->last_exception.c_str(); }
|
||||||
|
|
|
@ -2,10 +2,12 @@
|
||||||
// All rights reserved. MIT License.
|
// All rights reserved. MIT License.
|
||||||
#ifndef HANDLERS_H_
|
#ifndef HANDLERS_H_
|
||||||
#define HANDLERS_H_
|
#define HANDLERS_H_
|
||||||
extern "C" {
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
void handle_code_fetch(uint32_t cmd_id, const char* module_specifier,
|
#include <stdint.h>
|
||||||
|
#include "deno.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void handle_code_fetch(Deno* d, uint32_t cmd_id, const char* module_specifier,
|
||||||
const char* containing_file);
|
const char* containing_file);
|
||||||
}
|
} // extern "C"
|
||||||
#endif // HANDLERS_H_
|
#endif // HANDLERS_H_
|
||||||
|
|
241
src/handlers.rs
241
src/handlers.rs
|
@ -1,36 +1,247 @@
|
||||||
// Copyright 2018 Ryan Dahl <ry@tinyclouds.org>
|
// Copyright 2018 Ryan Dahl <ry@tinyclouds.org>
|
||||||
// All rights reserved. MIT License.
|
// All rights reserved. MIT License.
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate log;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
|
||||||
use libc::c_char;
|
use libc::c_char;
|
||||||
|
use libc::uint32_t;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
use std::ffi::CString;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Read;
|
||||||
|
use std::path::Path;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
fn string_from_ptr(ptr: *const c_char) -> String {
|
// TODO(ry) Share this with the def in src/main.rs.
|
||||||
let cstr = unsafe { CStr::from_ptr(ptr as *const i8) };
|
#[repr(C)]
|
||||||
String::from(cstr.to_str().unwrap())
|
pub struct DenoC {
|
||||||
|
_unused: [u8; 0],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(ry) Share this extern block with those in main.rs.
|
||||||
|
// See src/reply.h
|
||||||
|
extern "C" {
|
||||||
|
pub fn deno_reply_error(d: *const DenoC, cmd_id: uint32_t, msg: *const c_char);
|
||||||
|
pub fn deno_reply_null(d: *const DenoC, cmd_id: uint32_t);
|
||||||
|
pub fn deno_reply_code_fetch(
|
||||||
|
d: *const DenoC,
|
||||||
|
cmd_id: uint32_t,
|
||||||
|
module_name: *const c_char,
|
||||||
|
filename: *const c_char,
|
||||||
|
source_code: *const c_char,
|
||||||
|
output_code: *const c_char,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(ry) SRC_DIR is just a placeholder for future caching functionality.
|
||||||
|
static SRC_DIR: &str = "/Users/rld/.deno/src/";
|
||||||
|
const ASSET_PREFIX: &str = "/$asset$/";
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_url() {
|
fn test_url() {
|
||||||
let issue_list_url = Url::parse("https://github.com/rust-lang").unwrap();
|
let issue_list_url = Url::parse("https://github.com/rust-lang").unwrap();
|
||||||
assert!(issue_list_url.scheme() == "https");
|
assert!(issue_list_url.scheme() == "https");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
fn string_from_ptr(ptr: *const c_char) -> String {
|
||||||
pub extern "C" fn handle_code_fetch(
|
let cstr = unsafe { CStr::from_ptr(ptr as *const i8) };
|
||||||
cmd_id: u32,
|
String::from(cstr.to_str().unwrap())
|
||||||
module_specifier: *const c_char,
|
}
|
||||||
containing_file: *const c_char,
|
|
||||||
) {
|
|
||||||
let module_specifier = string_from_ptr(module_specifier);
|
|
||||||
let containing_file = string_from_ptr(containing_file);
|
|
||||||
|
|
||||||
println!(
|
fn as_cstring(s: &String) -> CString {
|
||||||
"handle_code_fetch. cmd_id = {} module_specifier = {} containing_file = {}",
|
CString::new(s.as_str()).unwrap()
|
||||||
cmd_id, module_specifier, containing_file
|
}
|
||||||
|
|
||||||
|
// Prototype: https://github.com/ry/deno/blob/golang/os.go#L56-L68
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn src_file_to_url<P: AsRef<Path>>(filename: P) -> String {
|
||||||
|
assert!(SRC_DIR.len() > 0, "SRC_DIR shouldn't be empty");
|
||||||
|
|
||||||
|
let filename = filename.as_ref().to_path_buf();
|
||||||
|
let src = (SRC_DIR.as_ref() as &Path).to_path_buf();
|
||||||
|
|
||||||
|
if filename.starts_with(&src) {
|
||||||
|
let rest = filename.strip_prefix(&src).unwrap();
|
||||||
|
"http://".to_string() + rest.to_str().unwrap()
|
||||||
|
} else {
|
||||||
|
String::from(filename.to_str().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_src_file_to_url() {
|
||||||
|
assert_eq!("hello", src_file_to_url("hello"));
|
||||||
|
assert_eq!("/hello", src_file_to_url("/hello"));
|
||||||
|
let x = SRC_DIR.to_string() + "hello";
|
||||||
|
assert_eq!("http://hello", src_file_to_url(&x));
|
||||||
|
let x = SRC_DIR.to_string() + "/hello";
|
||||||
|
assert_eq!("http://hello", src_file_to_url(&x));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prototype: https://github.com/ry/deno/blob/golang/os.go#L70-L98
|
||||||
|
// Returns (module name, local filename)
|
||||||
|
fn resolve_module(
|
||||||
|
module_specifier: &String,
|
||||||
|
containing_file: &String,
|
||||||
|
) -> Result<(String, String), url::ParseError> {
|
||||||
|
info!(
|
||||||
|
"resolve_module before module_specifier {} containing_file {}",
|
||||||
|
module_specifier, containing_file
|
||||||
);
|
);
|
||||||
|
|
||||||
unimplemented!();
|
//let module_specifier = src_file_to_url(module_specifier);
|
||||||
|
//let containing_file = src_file_to_url(containing_file);
|
||||||
|
//let base_url = Url::parse(&containing_file)?;
|
||||||
|
|
||||||
|
let j: Url = if containing_file.as_str().ends_with("/") {
|
||||||
|
let base = Url::from_directory_path(&containing_file).unwrap();
|
||||||
|
base.join(module_specifier)?
|
||||||
|
} else if containing_file == "." {
|
||||||
|
Url::from_file_path(module_specifier).unwrap()
|
||||||
|
} else {
|
||||||
|
let base = Url::from_file_path(&containing_file).unwrap();
|
||||||
|
base.join(module_specifier)?
|
||||||
|
};
|
||||||
|
|
||||||
|
let p = j.to_file_path()
|
||||||
|
.unwrap()
|
||||||
|
.into_os_string()
|
||||||
|
.into_string()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let module_name = p.to_string();
|
||||||
|
let filename = p.to_string();
|
||||||
|
|
||||||
|
Ok((module_name, filename))
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/ry/deno/blob/golang/os_test.go#L16-L87
|
||||||
|
#[test]
|
||||||
|
fn test_resolve_module() {
|
||||||
|
let test_cases = [
|
||||||
|
(
|
||||||
|
"./subdir/print_hello.ts",
|
||||||
|
"/Users/rld/go/src/github.com/ry/deno/testdata/006_url_imports.ts",
|
||||||
|
"/Users/rld/go/src/github.com/ry/deno/testdata/subdir/print_hello.ts",
|
||||||
|
"/Users/rld/go/src/github.com/ry/deno/testdata/subdir/print_hello.ts",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"testdata/001_hello.js",
|
||||||
|
"/Users/rld/go/src/github.com/ry/deno/",
|
||||||
|
"/Users/rld/go/src/github.com/ry/deno/testdata/001_hello.js",
|
||||||
|
"/Users/rld/go/src/github.com/ry/deno/testdata/001_hello.js",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"/Users/rld/src/deno/hello.js",
|
||||||
|
".",
|
||||||
|
"/Users/rld/src/deno/hello.js",
|
||||||
|
"/Users/rld/src/deno/hello.js",
|
||||||
|
),
|
||||||
|
/*
|
||||||
|
(
|
||||||
|
"http://localhost:4545/testdata/subdir/print_hello.ts",
|
||||||
|
"/Users/rld/go/src/github.com/ry/deno/testdata/006_url_imports.ts",
|
||||||
|
"http://localhost:4545/testdata/subdir/print_hello.ts",
|
||||||
|
path.Join(SrcDir, "localhost:4545/testdata/subdir/print_hello.ts"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
path.Join(SrcDir, "unpkg.com/liltest@0.0.5/index.ts"),
|
||||||
|
".",
|
||||||
|
"http://unpkg.com/liltest@0.0.5/index.ts",
|
||||||
|
path.Join(SrcDir, "unpkg.com/liltest@0.0.5/index.ts"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"./util",
|
||||||
|
path.Join(SrcDir, "unpkg.com/liltest@0.0.5/index.ts"),
|
||||||
|
"http://unpkg.com/liltest@0.0.5/util",
|
||||||
|
path.Join(SrcDir, "unpkg.com/liltest@0.0.5/util"),
|
||||||
|
),
|
||||||
|
*/
|
||||||
|
];
|
||||||
|
for &test in test_cases.iter() {
|
||||||
|
let module_specifier = String::from(test.0);
|
||||||
|
let containing_file = String::from(test.1);
|
||||||
|
let (module_name, filename) = resolve_module(&module_specifier, &containing_file).unwrap();
|
||||||
|
assert_eq!(module_name, test.2);
|
||||||
|
assert_eq!(filename, test.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/ry/deno/blob/golang/os.go#L100-L154
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn handle_code_fetch(
|
||||||
|
d: *const DenoC,
|
||||||
|
cmd_id: u32,
|
||||||
|
module_specifier_: *const c_char,
|
||||||
|
containing_file_: *const c_char,
|
||||||
|
) {
|
||||||
|
// TODO(ry) Move this to main.
|
||||||
|
log::set_max_level(log::LevelFilter::Debug);
|
||||||
|
|
||||||
|
let module_specifier = string_from_ptr(module_specifier_);
|
||||||
|
let containing_file = string_from_ptr(containing_file_);
|
||||||
|
|
||||||
|
let result = resolve_module(&module_specifier, &containing_file);
|
||||||
|
if result.is_err() {
|
||||||
|
let err = result.unwrap_err();
|
||||||
|
let errmsg = format!("{} {} {}", err, module_specifier, containing_file);
|
||||||
|
let errmsg_c = as_cstring(&errmsg);
|
||||||
|
unsafe { deno_reply_error(d, cmd_id, errmsg_c.as_ptr()) };
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let (module_name, filename) = result.unwrap();
|
||||||
|
|
||||||
|
let mut source_code = String::new();
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
"code_fetch. module_name = {} module_specifier = {} containing_file = {} filename = {}",
|
||||||
|
module_name, module_specifier, containing_file, filename
|
||||||
|
);
|
||||||
|
|
||||||
|
if is_remote(&module_name) {
|
||||||
|
unimplemented!();
|
||||||
|
} else if module_name.starts_with(ASSET_PREFIX) {
|
||||||
|
assert!(false, "Asset resolution should be done in JS, not Rust.");
|
||||||
|
} else {
|
||||||
|
assert!(
|
||||||
|
module_name == filename,
|
||||||
|
"if a module isn't remote, it should have the same filename"
|
||||||
|
);
|
||||||
|
let result = File::open(&filename);
|
||||||
|
if result.is_err() {
|
||||||
|
let err = result.unwrap_err();
|
||||||
|
let errmsg = format!("{} {}", err, filename);
|
||||||
|
let errmsg_c = as_cstring(&errmsg);
|
||||||
|
unsafe { deno_reply_error(d, cmd_id, errmsg_c.as_ptr()) };
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mut f = result.unwrap();
|
||||||
|
let result = f.read_to_string(&mut source_code);
|
||||||
|
if result.is_err() {
|
||||||
|
let err = result.unwrap_err();
|
||||||
|
let errmsg = format!("{} {}", err, filename);
|
||||||
|
let errmsg_c = as_cstring(&errmsg);
|
||||||
|
unsafe { deno_reply_error(d, cmd_id, errmsg_c.as_ptr()) };
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let output_code = String::new(); //load_output_code_cache(filename, source_code);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
deno_reply_code_fetch(
|
||||||
|
d,
|
||||||
|
cmd_id,
|
||||||
|
as_cstring(&module_name).as_ptr(),
|
||||||
|
as_cstring(&filename).as_ptr(),
|
||||||
|
as_cstring(&source_code).as_ptr(),
|
||||||
|
as_cstring(&output_code).as_ptr(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_remote(_module_name: &String) -> bool {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,9 @@ struct deno_s {
|
||||||
deno_recv_cb cb;
|
deno_recv_cb cb;
|
||||||
void* data;
|
void* data;
|
||||||
};
|
};
|
||||||
|
// TODO(ry) Remove these when we call deno_reply_start from Rust.
|
||||||
|
char** deno_argv();
|
||||||
|
int deno_argc();
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace deno {
|
namespace deno {
|
||||||
|
|
104
src/main.cc
104
src/main.cc
|
@ -1,104 +0,0 @@
|
||||||
// Copyright 2018 Ryan Dahl <ry@tinyclouds.org>
|
|
||||||
// All rights reserved. MIT License.
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <direct.h>
|
|
||||||
#else
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "deno.h"
|
|
||||||
#include "flatbuffer_builder.h"
|
|
||||||
#include "flatbuffers/flatbuffers.h"
|
|
||||||
#include "src/handlers.h"
|
|
||||||
#include "src/msg_generated.h"
|
|
||||||
#include "third_party/v8/src/base/logging.h"
|
|
||||||
|
|
||||||
namespace deno {
|
|
||||||
|
|
||||||
static char** global_argv;
|
|
||||||
static int global_argc;
|
|
||||||
|
|
||||||
// Sends StartRes message
|
|
||||||
void HandleStart(Deno* d, uint32_t cmd_id) {
|
|
||||||
deno::FlatBufferBuilder builder;
|
|
||||||
|
|
||||||
char cwdbuf[1024];
|
|
||||||
// TODO(piscisaureus): support unicode on windows.
|
|
||||||
getcwd(cwdbuf, sizeof(cwdbuf));
|
|
||||||
auto start_cwd = builder.CreateString(cwdbuf);
|
|
||||||
|
|
||||||
std::vector<flatbuffers::Offset<flatbuffers::String>> args;
|
|
||||||
for (int i = 0; i < global_argc; ++i) {
|
|
||||||
args.push_back(builder.CreateString(global_argv[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto start_argv = builder.CreateVector(args);
|
|
||||||
auto start_msg = CreateStartRes(builder, start_cwd, start_argv);
|
|
||||||
auto base = CreateBase(builder, cmd_id, 0, Any_StartRes, start_msg.Union());
|
|
||||||
builder.Finish(base);
|
|
||||||
deno_set_response(d, builder.ExportBuf());
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleCodeFetch(Deno* d, uint32_t cmd_id, const CodeFetch* msg) {
|
|
||||||
auto module_specifier = msg->module_specifier()->c_str();
|
|
||||||
auto containing_file = msg->containing_file()->c_str();
|
|
||||||
printf("HandleCodeFetch module_specifier = %s containing_file = %s\n",
|
|
||||||
module_specifier, containing_file);
|
|
||||||
// Call into rust.
|
|
||||||
handle_code_fetch(cmd_id, module_specifier, containing_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessagesFromJS(Deno* d, deno_buf buf) {
|
|
||||||
flatbuffers::Verifier verifier(buf.data_ptr, buf.data_len);
|
|
||||||
DCHECK(verifier.VerifyBuffer<Base>());
|
|
||||||
|
|
||||||
auto base = flatbuffers::GetRoot<Base>(buf.data_ptr);
|
|
||||||
auto cmd_id = base->cmdId();
|
|
||||||
auto msg_type = base->msg_type();
|
|
||||||
const char* msg_type_name = EnumNamesAny()[msg_type];
|
|
||||||
printf("MessagesFromJS cmd_id = %d, msg_type = %d, msg_type_name = %s\n",
|
|
||||||
cmd_id, msg_type, msg_type_name);
|
|
||||||
switch (msg_type) {
|
|
||||||
case Any_Start:
|
|
||||||
HandleStart(d, base->cmdId());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Any_CodeFetch:
|
|
||||||
HandleCodeFetch(d, base->cmdId(), base->msg_as_CodeFetch());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Any_NONE:
|
|
||||||
CHECK(false && "Got message with msg_type == Any_NONE");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
printf("Unhandled message %s\n", msg_type_name);
|
|
||||||
CHECK(false && "Unhandled message");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int deno_main(int argc, char** argv) {
|
|
||||||
deno_init();
|
|
||||||
|
|
||||||
deno_set_flags(&argc, argv);
|
|
||||||
global_argv = argv;
|
|
||||||
global_argc = argc;
|
|
||||||
|
|
||||||
Deno* d = deno_new(NULL, MessagesFromJS);
|
|
||||||
bool r = deno_execute(d, "deno_main.js", "denoMain();");
|
|
||||||
if (!r) {
|
|
||||||
printf("%s\n", deno_last_exception(d));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
deno_delete(d);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace deno
|
|
||||||
|
|
||||||
int main(int argc, char** argv) { return deno::deno_main(argc, argv); }
|
|
10
src/main.rs
10
src/main.rs
|
@ -20,7 +20,7 @@ struct DenoC {
|
||||||
_unused: [u8; 0],
|
_unused: [u8; 0],
|
||||||
}
|
}
|
||||||
|
|
||||||
type DenoRecvCb = extern "C" fn(d: *const DenoC, buf: deno_buf);
|
type DenoRecvCb = unsafe extern "C" fn(d: *const DenoC, buf: deno_buf);
|
||||||
|
|
||||||
#[link(name = "deno", kind = "static")]
|
#[link(name = "deno", kind = "static")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -36,6 +36,8 @@ extern "C" {
|
||||||
fn deno_set_response(d: *const DenoC, buf: deno_buf);
|
fn deno_set_response(d: *const DenoC, buf: deno_buf);
|
||||||
fn deno_execute(d: *const DenoC, js_filename: *const c_char, js_source: *const c_char)
|
fn deno_execute(d: *const DenoC, js_filename: *const c_char, js_source: *const c_char)
|
||||||
-> c_int;
|
-> c_int;
|
||||||
|
|
||||||
|
fn deno_handle_msg_from_js(d: *const DenoC, buf: deno_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass the command line arguments to v8.
|
// Pass the command line arguments to v8.
|
||||||
|
@ -73,10 +75,6 @@ fn set_flags() -> Vec<String> {
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn on_message(_d: *const DenoC, _buf: deno_buf) {
|
|
||||||
println!("got message in rust");
|
|
||||||
}
|
|
||||||
|
|
||||||
type DenoException<'a> = &'a str;
|
type DenoException<'a> = &'a str;
|
||||||
|
|
||||||
struct Deno {
|
struct Deno {
|
||||||
|
@ -85,7 +83,7 @@ struct Deno {
|
||||||
|
|
||||||
impl Deno {
|
impl Deno {
|
||||||
fn new() -> Deno {
|
fn new() -> Deno {
|
||||||
let ptr = unsafe { deno_new(ptr::null(), on_message) };
|
let ptr = unsafe { deno_new(ptr::null(), deno_handle_msg_from_js) };
|
||||||
Deno { ptr: ptr }
|
Deno { ptr: ptr }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
120
src/reply.cc
Normal file
120
src/reply.cc
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
// Copyright 2018 Ryan Dahl <ry@tinyclouds.org>
|
||||||
|
// All rights reserved. MIT License.
|
||||||
|
|
||||||
|
// When Rust Flatbuffer support is complete this file should be ported
|
||||||
|
// to Rust and removed: https://github.com/google/flatbuffers/pull/3894
|
||||||
|
#include <vector>
|
||||||
|
// getcwd
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <direct.h>
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "flatbuffers/flatbuffers.h"
|
||||||
|
#include "src/deno.h"
|
||||||
|
#include "src/flatbuffer_builder.h"
|
||||||
|
#include "src/handlers.h"
|
||||||
|
#include "src/internal.h"
|
||||||
|
#include "src/msg_generated.h"
|
||||||
|
#include "src/reply.h"
|
||||||
|
#include "third_party/v8/src/base/logging.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
void deno_reply_error(Deno* d, uint32_t cmd_id, const char* error_msg) {
|
||||||
|
// printf("deno_reply_error: %s\n", error_msg);
|
||||||
|
deno::FlatBufferBuilder builder;
|
||||||
|
auto error_msg_ = error_msg ? builder.CreateString(error_msg) : 0;
|
||||||
|
auto base = deno::CreateBase(builder, cmd_id, error_msg_);
|
||||||
|
builder.Finish(base);
|
||||||
|
deno_set_response(d, builder.ExportBuf());
|
||||||
|
}
|
||||||
|
|
||||||
|
void deno_reply_null(Deno* d, uint32_t cmd_id) {
|
||||||
|
deno_reply_error(d, cmd_id, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deno_reply_code_fetch(Deno* d, uint32_t cmd_id, const char* module_name,
|
||||||
|
const char* filename, const char* source_code,
|
||||||
|
const char* output_code) {
|
||||||
|
deno::FlatBufferBuilder builder;
|
||||||
|
auto module_name_ = builder.CreateString(module_name);
|
||||||
|
auto filename_ = builder.CreateString(filename);
|
||||||
|
auto source_code_ = builder.CreateString(source_code);
|
||||||
|
auto output_code_ = builder.CreateString(output_code);
|
||||||
|
auto code_fetch_res = deno::CreateCodeFetchRes(
|
||||||
|
builder, module_name_, filename_, source_code_, output_code_);
|
||||||
|
auto base = deno::CreateBase(builder, cmd_id, 0, deno::Any_CodeFetchRes,
|
||||||
|
code_fetch_res.Union());
|
||||||
|
builder.Finish(base);
|
||||||
|
deno_set_response(d, builder.ExportBuf());
|
||||||
|
}
|
||||||
|
|
||||||
|
void deno_reply_start(Deno* d, uint32_t cmd_id, int argc, char* argv[],
|
||||||
|
char* cwd) {
|
||||||
|
deno::FlatBufferBuilder builder;
|
||||||
|
auto start_cwd = builder.CreateString(cwd);
|
||||||
|
std::vector<flatbuffers::Offset<flatbuffers::String>> args;
|
||||||
|
for (int i = 0; i < argc; ++i) {
|
||||||
|
args.push_back(builder.CreateString(argv[i]));
|
||||||
|
}
|
||||||
|
auto start_argv = builder.CreateVector(args);
|
||||||
|
auto start_msg = deno::CreateStartRes(builder, start_cwd, start_argv);
|
||||||
|
auto base = deno::CreateBase(builder, cmd_id, 0, deno::Any_StartRes,
|
||||||
|
start_msg.Union());
|
||||||
|
builder.Finish(base);
|
||||||
|
deno_set_response(d, builder.ExportBuf());
|
||||||
|
}
|
||||||
|
|
||||||
|
void deno_handle_msg_from_js(Deno* d, deno_buf buf) {
|
||||||
|
flatbuffers::Verifier verifier(buf.data_ptr, buf.data_len);
|
||||||
|
DCHECK(verifier.VerifyBuffer<deno::Base>());
|
||||||
|
|
||||||
|
auto base = flatbuffers::GetRoot<deno::Base>(buf.data_ptr);
|
||||||
|
auto cmd_id = base->cmdId();
|
||||||
|
auto msg_type = base->msg_type();
|
||||||
|
const char* msg_type_name = deno::EnumNamesAny()[msg_type];
|
||||||
|
switch (msg_type) {
|
||||||
|
case deno::Any_Start: {
|
||||||
|
char cwdbuf[1024];
|
||||||
|
// TODO(piscisaureus): support unicode on windows.
|
||||||
|
getcwd(cwdbuf, sizeof(cwdbuf));
|
||||||
|
deno_reply_start(d, cmd_id, deno_argc(), deno_argv(), cwdbuf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case deno::Any_CodeFetch: {
|
||||||
|
auto msg = base->msg_as_CodeFetch();
|
||||||
|
auto module_specifier = msg->module_specifier()->c_str();
|
||||||
|
auto containing_file = msg->containing_file()->c_str();
|
||||||
|
handle_code_fetch(d, cmd_id, module_specifier, containing_file);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case deno::Any_CodeCache: {
|
||||||
|
// TODO(ry) Call into rust.
|
||||||
|
/*
|
||||||
|
auto filename = msg->filename()->c_str();
|
||||||
|
auto source_code = msg->source_code()->c_str();
|
||||||
|
auto output_code = msg->output_code()->c_str();
|
||||||
|
printf(
|
||||||
|
"HandleCodeCache (not implemeneted) filename %s source_code %s "
|
||||||
|
"output_code %s\n",
|
||||||
|
filename, source_code, output_code);
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case deno::Any_NONE:
|
||||||
|
CHECK(false && "Got message with msg_type == Any_NONE");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("Unhandled message %s\n", msg_type_name);
|
||||||
|
CHECK(false && "Unhandled message");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // extern "C"
|
29
src/reply.h
Normal file
29
src/reply.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2018 Ryan Dahl <ry@tinyclouds.org>
|
||||||
|
// All rights reserved. MIT License.
|
||||||
|
|
||||||
|
// TODO(ry) This library handles parsing and sending Flatbuffers. It's written
|
||||||
|
// in C++ because flatbuffer support for Rust is not quite there. However, once
|
||||||
|
// flatbuffers are supported in Rust, all of this code should be ported back to
|
||||||
|
// Rust.
|
||||||
|
|
||||||
|
#ifndef REPLY_H_
|
||||||
|
#define REPLY_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "deno.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
void deno_reply_null(Deno* d, uint32_t cmd_id);
|
||||||
|
void deno_reply_error(Deno* d, uint32_t cmd_id, const char* error_msg);
|
||||||
|
|
||||||
|
void deno_reply_start(Deno* d, uint32_t cmd_id, int argc, char* argv[],
|
||||||
|
char* cwd);
|
||||||
|
void deno_reply_code_fetch(Deno* d, uint32_t cmd_id, const char* module_name,
|
||||||
|
const char* filename, const char* source_code,
|
||||||
|
const char* output_code);
|
||||||
|
|
||||||
|
// Parse incoming messages with C++ Flatbuffers, call into rust handlers.
|
||||||
|
void deno_handle_msg_from_js(Deno* d, deno_buf buf);
|
||||||
|
}
|
||||||
|
#endif // REPLY_H_
|
1
testdata/001_hello.js
vendored
Normal file
1
testdata/001_hello.js
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
console.log("Hello World");
|
1
testdata/002_hello.ts
vendored
Normal file
1
testdata/002_hello.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
console.log("Hello World");
|
Loading…
Reference in a new issue