diff --git a/README.md b/README.md index b65e141fa5..2694437da4 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,12 @@ [![Build Status](https://travis-ci.com/ry/deno.svg?branch=master)](https://travis-ci.com/ry/deno) -A secure TypeScript runtime on V8 +## A secure TypeScript runtime built on V8 * Supports TypeScript 2.8 out of the box. Uses V8 6.8.275.3. 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. ``` @@ -15,14 +15,14 @@ A secure TypeScript runtime on V8 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 + 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 Golang (privileged) is only done via serialized messages defined in this - [protobuf](https://github.com/ry/deno/blob/master/msg.proto), this makes it + [protobuf](https://github.com/ry/deno/blob/master/msg.proto). This makes it easy to audit. To enable write access explicitly use `--allow-write` and `--allow-net` for network access. @@ -43,7 +43,7 @@ A secure TypeScript runtime on V8 * Always dies on uncaught errors. -* Supports top-level await. +* Supports top-level `await`. * Aims to be browser compatible. @@ -61,17 +61,18 @@ And examples are around here: [testdata/004_set_timeout.ts](https://github.com/r Roadmap is [here](https://github.com/ry/deno/blob/master/TODO.txt). -Also see this preentation http://tinyclouds.org/jsconf2018.pdf +Also see this presentation: http://tinyclouds.org/jsconf2018.pdf ## Compile instructions -I will release binaries at some point but for now you have to build it +I will release binaries at some point, but for now you have to build it yourself. -You will need [Go](https://golang.org/) with `$GOPATH` defined and -`$GOPATH/bin` in your `$PATH`. You will also need -[yarn](https://yarnpkg.com/lang/en/docs/install/) installed. +You will need [Go](https://golang.org) with `$GOPATH` defined and +`$GOPATH/bin` in your `$PATH`. + +You will also need [yarn](https://yarnpkg.com/lang/en/docs/install/) installed. You need Protobuf 3. On Linux this might work: @@ -111,9 +112,9 @@ go get -u github.com/ry/v8worker2 cd $GOPATH/src/github.com/ry/v8worker2 ./build.py --use_ccache ``` -Maybe also run `git submodule update --init` in the v8worker2 dir. +Maybe also run `git submodule update --init` in the `v8worker2/` dir. -Finally you can get `deno` and its other Go deps. +Finally, you can get `deno` and its other Go deps. ``` bash go get -u github.com/ry/deno/... @@ -129,7 +130,7 @@ make # Wait for redacted ./deno testdata/001_hello.js # Output: Hello World ``` -## make commands +## `make` commands ``` bash make deno # Builds the deno executable. diff --git a/deno_dir.go b/deno_dir.go index 166fcb8270..2df1f74b4b 100644 --- a/deno_dir.go +++ b/deno_dir.go @@ -56,7 +56,7 @@ func FetchRemoteSource(remoteUrl string, localFilename string) ([]byte, error) { return nil, err } - // Write to to file. Need to reopen it for writing. + // Write to local file. Need to reopen it for writing. file, err = os.OpenFile(localFilename, os.O_RDWR|os.O_CREATE, 0700) if err != nil { return nil, err diff --git a/main.go b/main.go index 465c8b5ea3..37cfd022d4 100644 --- a/main.go +++ b/main.go @@ -5,15 +5,17 @@ package deno import ( "flag" "fmt" - "github.com/ry/v8worker2" "os" "runtime/pprof" + + "github.com/ry/v8worker2" ) var flagReload = flag.Bool("reload", false, "Reload cached remote source code.") var flagV8Options = flag.Bool("v8-options", false, "Print V8 command line options.") var flagDebug = flag.Bool("debug", false, "Enable debug output.") -var flagGoProf = flag.String("goprof", "", "Write golang cpu profile to file.") +var flagCPUProf = flag.String("cpuprof", "", "Write golang cpu profile to file.") +var flagMemProf = flag.String("memprof", "", "Write golang memory profile to file.") var flagAllowRead = flag.Bool("allow-read", true, "Allow program to read file system.") @@ -22,6 +24,8 @@ var flagAllowWrite = flag.Bool("allow-write", false, var flagAllowNet = flag.Bool("allow-net", false, "Allow program to make network connection.") +var memProfile *os.File + var Perms struct { FsRead bool FsWrite bool @@ -72,14 +76,9 @@ func Init() { os.Exit(1) } - // Maybe start Golang CPU profiler. + // Maybe start Golang profilers. // Use --prof for profiling JS. - if *flagGoProf != "" { - f, err := os.Create(*flagGoProf) - check(err) - pprof.StartCPUProfile(f) - defer pprof.StopCPUProfile() - } + StartProfiling() createDirs() InitOS() @@ -95,6 +94,29 @@ func Init() { main_map = stringAsset("main.map") } +func StartProfiling() { + if *flagCPUProf != "" { + cpuProfile, err := os.Create(*flagCPUProf) + check(err) + check(pprof.StartCPUProfile(cpuProfile)) + } + if *flagMemProf != "" { + var err error + memProfile, err = os.Create(*flagMemProf) + check(err) + check(pprof.WriteHeapProfile(memProfile)) + } +} + +func stopProfiling() { + if *flagCPUProf != "" { + pprof.StopCPUProfile() + } + if *flagMemProf != "" { + check(memProfile.Close()) + } +} + // It's up to library users to call // deno.Eval("deno_main.js", "denoMain()") func Eval(filename string, code string) { @@ -114,4 +136,5 @@ func Loop() { StartMainMap: main_map, }) DispatchLoop() + stopProfiling() } diff --git a/runtime.ts b/runtime.ts index 6bc09dd89e..8929b7112c 100644 --- a/runtime.ts +++ b/runtime.ts @@ -59,7 +59,7 @@ export function setup(mainJs: string, mainMap: string): void { // FileModule.load(). FileModules are NOT executed upon first load, only when // compileAndRun is called. export class FileModule { - scriptVersion: string = undefined; + scriptVersion: string; readonly exports = {}; private static readonly map = new Map(); @@ -80,7 +80,7 @@ export class FileModule { compileAndRun(): void { if (!this.outputCode) { - // If there is no cached outputCode, the compile the code. + // If there is no cached outputCode, then compile the code. util.assert( this.sourceCode != null && this.sourceCode.length > 0, `Have no source code from ${this.fileName}` diff --git a/timers.ts b/timers.ts index cddb859d9a..ed65128cda 100644 --- a/timers.ts +++ b/timers.ts @@ -81,6 +81,7 @@ export function setInterval( } export function clearTimer(id: number) { + timers.delete(id); pubInternal("timers", { command: pb.Msg.Command.TIMER_CLEAR, timerClearId: id