1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 15:24:46 -05:00
This commit is contained in:
Bert Belder 2018-10-04 02:01:21 -07:00
parent 8ca082c508
commit b9cdf088e7
No known key found for this signature in database
GPG key ID: 7A77887B2E2ED461
4 changed files with 122 additions and 119 deletions

View file

@ -1,36 +1,32 @@
# deno
| **Linux & Mac** | **Windows** |
|:---------------:|:-----------:|
| :------------------------: | :------------------------: |
| [![][tci badge]][tci link] | [![][avy badge]][avy link] |
## A secure TypeScript runtime built on V8
* Supports TypeScript 3.0 out of the box. Uses V8 7.0. That is, it's
very modern JavaScript.
- Supports TypeScript 3.0 out of the box. Uses V8 7.0. That is, it's very modern
JavaScript.
* No `package.json`. No npm. Not explicitly compatible with Node.
- No `package.json`. No npm. Not explicitly compatible with Node.
* Imports reference source code URLs only.
```
import { test } from "https://unpkg.com/deno_testing@0.0.5/testing.ts"
import { log } from "./util.ts"
```
- Imports reference source code URLs only.
`import { test } from "https://unpkg.com/deno_testing@0.0.5/testing.ts" import { log } from "./util.ts"`
Remote code is fetched and cached on first execution, and never updated until
the code is run with the `--reload` flag. (So, this will still work on an
airplane. See `~/.deno/src` for details on the cache.)
* File system and network access can be controlled in order to run sandboxed
code. Defaults to read-only file system access and no network access.
Access between V8 (unprivileged) and Rust (privileged) is only done via
serialized messages defined in this
[flatbuffer](https://github.com/denoland/deno/blob/master/src/msg.fbs). This makes it
easy to audit.
To enable write access explicitly use `--allow-write` and `--allow-net` for
network access.
- File system and network access can be controlled in order to run sandboxed
code. Defaults to read-only file system access and no network access. Access
between V8 (unprivileged) and Rust (privileged) is only done via serialized
messages defined in this
[flatbuffer](https://github.com/denoland/deno/blob/master/src/msg.fbs). This
makes it easy to audit. To enable write access explicitly use `--allow-write`
and `--allow-net` for network access.
- Single executable:
* Single executable:
```
> ls -lh out/release/deno
-rwxr-xr-x 1 rld staff 48M Aug 2 13:24 out/release/deno
@ -43,11 +39,11 @@
>
```
* Always dies on uncaught errors.
- Always dies on uncaught errors.
* [Aims to support top-level `await`.](https://github.com/denoland/deno/issues/471)
- [Aims to support top-level `await`.](https://github.com/denoland/deno/issues/471)
* Aims to be browser compatible.
- Aims to be browser compatible.
## Install
@ -63,16 +59,18 @@ curl -sSf https://raw.githubusercontent.com/denoland/deno_install/master/install
iex (iwr https://raw.githubusercontent.com/denoland/deno_install/master/install.ps1)
```
_Note: Depending on your security settings, you may have to run `Set-ExecutionPolicy RemoteSigned -Scope CurrentUser` first to allow downloaded scripts to be executed._
_Note: Depending on your security settings, you may have to run
`Set-ExecutionPolicy RemoteSigned -Scope CurrentUser` first to allow downloaded
scripts to be executed._
Try it:
```
> deno http://deno.land/thumb.ts
```
See also [deno_install](https://github.com/denoland/deno_install).
## Status
Under development.
@ -82,14 +80,13 @@ We make binary releases [here](https://github.com/denoland/deno/releases).
Progress towards future releases is tracked
[here](https://github.com/denoland/deno/milestones).
Roadmap is [here](https://github.com/denoland/deno/blob/master/Roadmap.md).
Also see [this presentation](http://tinyclouds.org/jsconf2018.pdf).
Roadmap is [here](https://github.com/denoland/deno/blob/master/Roadmap.md). Also
see [this presentation](http://tinyclouds.org/jsconf2018.pdf).
[Benchmarks](https://denoland.github.io/deno/)
[Chat room](https://gitter.im/denolife/Lobby).
## Build instructions
To ensure reproducible builds, Deno has most of its dependencies in a git
@ -97,13 +94,17 @@ submodule. However, you need to install separately:
1. [Rust](https://www.rust-lang.org/en-US/install.html)
2. [Node](http://nodejs.org/)
3. Python 2. [Not 3](https://github.com/denoland/deno/issues/464#issuecomment-411795578).
4. [ccache](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/ccache) (Optional but helpful for speeding up rebuilds of V8.).
3. Python 2.
[Not 3](https://github.com/denoland/deno/issues/464#issuecomment-411795578).
4. [ccache](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/ccache)
(Optional but helpful for speeding up rebuilds of V8.).
5. Extra steps for Windows users:
1. Add `python.exe` to `PATH`. E.g. `set PATH=%PATH%;C:\Python27\python.exe`
2. Get [VS Community 2017](https://www.visualstudio.com/downloads/), make sure to select the option to install C++ tools and the Windows SDK
3. Enable `Debugging Tools for Windows`, Goto Control Panel -> Windows 10 SDK -> Right-Click -> Change -> Change -> Check Debugging Tools for Windows -> Change -> Finish
2. Get [VS Community 2017](https://www.visualstudio.com/downloads/), make
sure to select the option to install C++ tools and the Windows SDK
3. Enable `Debugging Tools for Windows`, Goto Control Panel -> Windows 10 SDK
-> Right-Click -> Change -> Change -> Check Debugging Tools for Windows ->
Change -> Finish
#### To build:
@ -144,13 +145,15 @@ Env vars: `DENO_BUILD_MODE`, `DENO_BUILD_PATH`, `DENO_BUILD_ARGS`.
## Contributing
1. Fork [this repository](https://github.com/denoland/deno) and create your branch from `master`.
1. Fork [this repository](https://github.com/denoland/deno) and create your
branch from `master`.
2. Make your change.
3. Ensure `./tools/test.py` passes.
4. Format your code with `./tools/format.py`.
5. Make sure `./tools/lint.py` passes.
6. Send a pull request.
7. Sign the [CLA](https://cla-assistant.io/denoland/deno), if you haven't already.
7. Sign the [CLA](https://cla-assistant.io/denoland/deno), if you haven't
already.
<!-- prettier-ignore -->
[avy badge]: https://ci.appveyor.com/api/projects/status/yel7wtcqwoy0to8x?branch=master&svg=true

View file

@ -42,29 +42,30 @@ https://github.com/denoland/deno/master/testing.js
## Security Model (partially implemented)
* We want to be secure by default; user should be able to run untrusted code,
- We want to be secure by default; user should be able to run untrusted code,
like the web.
* Threat model:
* Modifiying/deleting local files
* Leaking private information
* Disallowed default:
* Network access
* Local write access
* Non-JS extensions
* Subprocesses
* Env access
* Allowed default:
* Local read access.
* argv, stdout, stderr, stdin access always allowed.
* Maybe: temp dir write access. (But what if they create symlinks there?)
* The user gets prompted when the software tries to do something it doesn't have
- Threat model:
- Modifiying/deleting local files
- Leaking private information
- Disallowed default:
- Network access
- Local write access
- Non-JS extensions
- Subprocesses
- Env access
- Allowed default:
- Local read access.
- argv, stdout, stderr, stdin access always allowed.
- Maybe: temp dir write access. (But what if they create symlinks there?)
- The user gets prompted when the software tries to do something it doesn't have
the privilege for.
* Have an option to get a stack trace when access is requested.
* Worried that granting access per file will give a false sense of security due
- Have an option to get a stack trace when access is requested.
- Worried that granting access per file will give a false sense of security due
to monkey patching techniques. Access should be granted per program (js
context).
Example security prompts. Options are: YES, NO, PRINT STACK
```
Program requests write access to "~/.ssh/id_rsa". Grant? [yNs]
http://gist.github.com/asdfasd.js requests network access to "www.facebook.com". Grant? [yNs]
@ -72,9 +73,9 @@ Program requests access to environment variables. Grant? [yNs]
Program requests to spawn `rm -rf /`. Grant? [yNs]
```
* cli flags to grant access ahead of time --allow-all --allow-write --allow-net
- cli flags to grant access ahead of time --allow-all --allow-write --allow-net
--allow-env --allow-exec
* in version two we will add ability to give finer grain access
- in version two we will add ability to give finer grain access
--allow-net=facebook.com
## Milestone 1: Rust rewrite / V8 snapshot
@ -89,17 +90,15 @@ libdeno. libdeno will include the entire JS runtime as a V8 snapshot. It still
follows the message passing paradigm. Rust will be bound to this library to
implement the privileged part of Deno. See deno2/README.md for more details.
V8 Snapshots allow Deno to avoid recompiling the TypeScript compiler at
startup. This is already working.
V8 Snapshots allow Deno to avoid recompiling the TypeScript compiler at startup.
This is already working.
When the rewrite is at feature parity with the Go prototype, we will release
binaries for people to try.
## Milestone 2: Scale binding infrastructure
ETA: October 2018
https://github.com/denoland/deno/milestone/2
ETA: October 2018 https://github.com/denoland/deno/milestone/2
We decided to use Tokio https://tokio.rs/ to provide asynchronous I/O, thread
pool execution, and as a base for high level support for various internet
@ -110,11 +109,10 @@ it. We expect this to result in preliminary file system operations, fetch() for
http. Additionally we are working on CI, release, and benchmarking
infrastructure to scale development.
## libdeno C API.
Deno's privileged side will primarily be programmed in Rust. However there
will be a small C API that wraps V8 to 1) define the low-level message passing
Deno's privileged side will primarily be programmed in Rust. However there will
be a small C API that wraps V8 to 1) define the low-level message passing
semantics 2) provide a low-level test target 3) provide an ANSI C API binding
interface for Rust. V8 plus this C API is called libdeno and the important bits
of the API is specified here:
@ -148,41 +146,43 @@ const char* deno_last_exception(Deno* d);
## TypeScript API.
This section will not attempt to over all of the APIs
but give a general sense of them.
This section will not attempt to over all of the APIs but give a general sense
of them.
### Internal: libdeno
This is the lowest-level interface to the privileged side.
It provides little more than passing ArrayBuffers in and
out of the VM.
The libdeno API is more or less feature complete now.
See https://github.com/denoland/deno/blob/master/js/libdeno.ts
This is the lowest-level interface to the privileged side. It provides little
more than passing ArrayBuffers in and out of the VM. The libdeno API is more or
less feature complete now. See
https://github.com/denoland/deno/blob/master/js/libdeno.ts
### Internal: Shared data between Rust and V8
We use Flatbuffers to define common structs and enums between
TypeScript and Rust. These common data structures are defined in
https://github.com/denoland/deno/blob/master/src/msg.fbs
This is more or less working.
We use Flatbuffers to define common structs and enums between TypeScript and
Rust. These common data structures are defined in
https://github.com/denoland/deno/blob/master/src/msg.fbs This is more or less
working.
### Public API
This is the global variables and various built-in modules, namely the
`"deno"` module.
This is the global variables and various built-in modules, namely the `"deno"`
module.
Deno will provide common browser global utilities like `fetch()` and
`setTimeout()`.
Deno has typescript built-in. Users can access the built-in typescript
using:
Deno has typescript built-in. Users can access the built-in typescript using:
```ts
import * as ts from "typescript"
import * as ts from "typescript";
```
Deno has its own built-in module which is imported with:
```ts
import * as deno from "deno"
import * as deno from "deno";
```
The rest of this section discusses what will be in the `deno` module.
Within Deno this is the high-level user facing API. However, the intention is to
@ -201,17 +201,16 @@ compatibility with Node.
#471
This will be put off until at least deno2 Milestone1 is
complete. One of the major problems is that top-level await calls are not
syntactically valid TypeScript.
This will be put off until at least deno2 Milestone1 is complete. One of the
major problems is that top-level await calls are not syntactically valid
TypeScript.
#### I/O (Not Implemented) #721
There are many OS constructs that perform I/O: files, sockets, pipes.
Deno aims to provide a unified lowest common denominator interface to work with
these objects. Deno needs to operate on all of these asynchronously in order
to not block the event loop and it.
There are many OS constructs that perform I/O: files, sockets, pipes. Deno aims
to provide a unified lowest common denominator interface to work with these
objects. Deno needs to operate on all of these asynchronously in order to not
block the event loop and it.
Sockets and pipes support non-blocking reads and write. Generally file I/O is
blocking but it can be done in a thread pool to avoid blocking the main thread.
@ -220,8 +219,7 @@ non-blocking reads and writes that sockets and pipes do.
The following interfaces support files, socket, and pipes and are heavily
inspired by Go. The main difference in porting to JavaScript is that errors will
be handled by exceptions, modulo EOF, which is returned as part of
`ReadResult`.
be handled by exceptions, modulo EOF, which is returned as part of `ReadResult`.
```ts
// The bytes read during an I/O call and a boolean indicating EOF.
@ -256,7 +254,7 @@ interface Reader {
// does not indicate EOF.
//
// Implementations must not retain p.
async read(p: ArrayBufferView): Promise<ReadResult>;
read(p: ArrayBufferView): Promise<ReadResult>;
}
// Writer is the interface that wraps the basic write() method.
@ -269,7 +267,7 @@ interface Writer {
// slice data, even temporarily.
//
// Implementations must not retain p.
async write(p: ArrayBufferView): Promise<number>;
write(p: ArrayBufferView): Promise<number>;
}
// https://golang.org/pkg/io/#Closer
@ -290,29 +288,31 @@ interface Seeker {
// Seeking to an offset before the start of the file is an error. Seeking to
// any positive offset is legal, but the behavior of subsequent I/O operations
// on the underlying object is implementation-dependent.
async seek(offset: number, whence: number): Promise<void>;
seek(offset: number, whence: number): Promise<void>;
}
// https://golang.org/pkg/io/#ReadCloser
interface ReaderCloser extends Reader, Closer { }
interface ReaderCloser extends Reader, Closer {}
// https://golang.org/pkg/io/#WriteCloser
interface WriteCloser extends Writer, Closer { }
interface WriteCloser extends Writer, Closer {}
// https://golang.org/pkg/io/#ReadSeeker
interface ReadSeeker extends Reader, Seeker { }
interface ReadSeeker extends Reader, Seeker {}
// https://golang.org/pkg/io/#WriteSeeker
interface WriteSeeker extends Writer, Seeker { }
interface WriteSeeker extends Writer, Seeker {}
// https://golang.org/pkg/io/#ReadWriteCloser
interface ReadWriteCloser extends Reader, Writer, Closer { }
interface ReadWriteCloser extends Reader, Writer, Closer {}
// https://golang.org/pkg/io/#ReadWriteSeeker
interface ReadWriteSeeker extends Reader, Writer, Seeker { }
interface ReadWriteSeeker extends Reader, Writer, Seeker {}
```
These interfaces are well specified, simple, and have very nice utility
functions that will be easy to port. Some example utilites:
```ts
// copy() copies from src to dst until either EOF is reached on src or an error
// occurs. It returns the number of bytes copied and the first error encountered

View file

@ -57,12 +57,11 @@ const FG_RED = "\x1b[31m";
const FG_GREEN = "\x1b[32m";
function red_failed() {
return FG_RED + "FAILED" + RESET
return FG_RED + "FAILED" + RESET;
}
function green_ok() {
return FG_GREEN + "ok" + RESET
return FG_GREEN + "ok" + RESET;
}
async function runTests() {
@ -96,8 +95,8 @@ async function runTests() {
const result = failed > 0 ? red_failed() : green_ok();
console.log(
`\ntest result: ${result}. ${passed} passed; ${failed} failed; ` +
`${ignored} ignored; ${measured} measured; ${filtered} filtered out\n`);
`${ignored} ignored; ${measured} measured; ${filtered} filtered out\n`
);
if (failed === 0) {
// All good.

View file

@ -1,23 +1,24 @@
## About benchmark data
The benchmark chart supposes `//website/data.json` has the signature of `BenchmarkData[]` where `BenchmarkData` is defined like the below:
The benchmark chart supposes `//website/data.json` has the signature of
`BenchmarkData[]` where `BenchmarkData` is defined like the below:
```typescript
interface ExecTimeData {
mean: number
stddev: number
user: number
system: number
min: number
max: number
mean: number;
stddev: number;
user: number;
system: number;
min: number;
max: number;
}
interface BenchmarkData {
created_at: string,
sha1: string,
binary_size?: number,
created_at: string;
sha1: string;
binary_size?: number;
benchmark: {
[key: string]: ExecTimeData
}
[key: string]: ExecTimeData;
};
}
```