Skip to content

Commit

Permalink
engine262: runtime & agent, documentation, testing
Browse files Browse the repository at this point in the history
  • Loading branch information
rwaldron committed Apr 9, 2019
1 parent 52d5c1c commit e62d966
Show file tree
Hide file tree
Showing 11 changed files with 352 additions and 166 deletions.
26 changes: 21 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,27 @@ before_install:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
env:
- ESHOST_TARGET=node
- ESHOST_TARGET=firefox
# Shells
- ESHOST_TARGET=chakra
- ESHOST_TARGET=engine262
- ESHOST_TARGET=jsshell
- ESHOST_TARGET=node
# Browsers
- ESHOST_TARGET=firefox
- ESHOST_TARGET=chrome
# - ESHOST_TARGET=remote ESHOST_REMOTE_BROWSERNAME=firefox
install: |
# Shells
export ESHOST_SKIP_CH=1
export ESHOST_SKIP_D8=1
export ESHOST_SKIP_ENGINE262=1
export ESHOST_SKIP_JSC=1
export ESHOST_SKIP_CHROME=1
export ESHOST_SKIP_FIREFOX=1
export ESHOST_SKIP_JSSHELL=1
export ESHOST_SKIP_CH=1
export ESHOST_SKIP_NODE=1
# Browsers
export ESHOST_SKIP_CHROME=1
export ESHOST_SKIP_FIREFOX=1
export ESHOST_SKIP_REMOTE=1
function install_firefox {
Expand All @@ -35,8 +42,17 @@ install: |
unset TMP;
}
function install_engine262 {
git clone https://github.com/devsnek/engine262.git;
cd engine262 && npm install && npm run build && npm link;
cd $TRAVIS_BUILD_DIR;
}
if [[ "$ESHOST_TARGET" == "node" ]]; then
unset ESHOST_SKIP_NODE;
elif [[ "$ESHOST_TARGET" == "engine262" ]]; then
install_engine262;
unset ESHOST_SKIP_ENGINE262;
elif [[ "$ESHOST_TARGET" == "firefox" ]]; then
install_firefox;
export PATH=$(pwd)/firefox:$PATH;
Expand Down
35 changes: 20 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

Execute ECMAScript code uniformly across any ECMAScript host environment. See also [eshost-cli](https://github.com/bterlson/eshost-cli) for an easy way to use this library from the command line.

Using eshost, you can create an agent (eg. a web browser or a command-line ECMAScript host) and evaluate scripts within that agent. Code running within the agent has access to the eshost runtime API which enables code to evaluate scripts, create new realms, handle errors, and so forth all without worrying about the host-specific mechanisms for these capabilities are.
Using `eshost`, you can create an agent (eg. a web browser or a command-line ECMAScript host) and evaluate scripts within that agent. Code running within the agent has access to the `eshost` runtime API which enables code to evaluate scripts, create new realms, handle errors, and so forth all without worrying about the host-specific mechanisms for these capabilities are.

eshost consists of a wrapper around the various ways of executing a host and processing its output (called an Agent) and a runtime library for host-agnostic scripts to use.
`eshost` consists of a wrapper around the various ways of executing a host and processing its output (called an Agent) and a runtime library for host-agnostic scripts to use.

## Installation

Expand All @@ -18,23 +18,28 @@ npm install eshost

## Supported Hosts

| Host | Supported Platforms | Download | Notes |
|------|---------------------|----------|-------|
| node | Any | https://nodejs.org | |
| ch | Any | [Download](https://github.com/Microsoft/ChakraCore/releases) or [build](https://github.com/Microsoft/ChakraCore/wiki/Building-ChakraCore) | Chakra console host. |
| d8 | Any | Build [from source](https://github.com/v8/v8) | V8 console host. Errors are reported on stdout. Use `$.getGlobal` and `$.setGlobal` to get and set properties of global objects in other realms. |
| jsshell | Any | [Download](https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/) | SpiderMonkey console host. |
| jsc | Mac¹ | Build [from source](http://trac.webkit.org/wiki/JavaScriptCore)² | |
| xs | Any | Build [from source](https://github.com/Moddable-OpenSource/moddable-xst) | |
| nashorn | Any | Build [from source](https://wiki.openjdk.java.net/display/Nashorn/Building+Nashorn) | |
| edge | Windows | | Errors reported from Microsoft Edge are all of type Error. Requires [Microsoft WebDriver](https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/dev-guide/tools/webdriver/) in your path. |
| chrome | Any | | Requires [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/downloads) in your path.|
| firefox | Any | | Requires [GeckoDriver](https://github.com/mozilla/geckodriver/releases) in your path (possibly renamed to `wires`).|
| safari | Mac | | Requires (SafariDriver browser extension)[https://github.com/SeleniumHQ/selenium/wiki/SafariDriver]. |
| Host | Type | Supported Platforms | Download | Notes |
|------|------|---------------------|----------|-------|
| ch | CLI | Any | [Download](https://github.com/Microsoft/ChakraCore/releases) or [build](https://github.com/Microsoft/ChakraCore/wiki/Building-ChakraCore) | Chakra console host. |
| d8 | CLI | Any | Build [from source](https://github.com/v8/v8) | V8 console host. Errors are reported on stdout. Use `$.getGlobal` and `$.setGlobal` to get and set properties of global objects in other realms. |
| engine262 | CLI | Any | Build [from source](https://github.com/devsnek/engine262) | An implementation of ECMA-262 in JavaScript. |
| jsshell | CLI | Any | [Download](https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/) | SpiderMonkey console host. |
| jsc | CLI | Mac¹ | Build [from source](http://trac.webkit.org/wiki/JavaScriptCore)² | |
| nashorn | CLI | Any | Build [from source](https://wiki.openjdk.java.net/display/Nashorn/Building+Nashorn) | |
| node | CLI | Any | https://nodejs.org | |
| xs | CLI | Any | Build [from source](https://github.com/Moddable-OpenSource/moddable-xst) | |
| chrome | Browser | Any | | Requires [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/downloads) in your path.|
| edge | Browser | Windows | | Errors reported from Microsoft Edge are all of type Error. Requires [Microsoft WebDriver](https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/dev-guide/tools/webdriver/) in your path. |
| firefox | Browser | Any | | Requires [GeckoDriver](https://github.com/mozilla/geckodriver/releases) in your path (possibly renamed to `wires`).|
| safari | Browser | Mac | | Requires (SafariDriver browser extension)[https://github.com/SeleniumHQ/selenium/wiki/SafariDriver]. |

* 1: It is possible to build jsc on other platforms, but not supported.
* 2: Also available on your Mac system at `/System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc`.

## Use JSVU

[JSVU](https://github.com/GoogleChromeLabs/jsvu) is the recommended tool for maintaining JavaScript engines for testing purposes. Take a look at the [Supported engines](https://github.com/GoogleChromeLabs/jsvu#supported-engines) for more information.

## Example Usage

```js
Expand Down
37 changes: 26 additions & 11 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@ version: "{build}"
clone_depth: 1

environment:
# Shells
ESHOST_SKIP_CH: 1
ESHOST_SKIP_D8: 1
ESHOST_SKIP_ENGINE262: 1
ESHOST_SKIP_JSC: 1
ESHOST_SKIP_JSSHELL: 1
ESHOST_SKIP_NODE: 1
# Browsers
ESHOST_SKIP_CHROME: 1
ESHOST_SKIP_FIREFOX: 1
# These are not skipped
# ESHOST_SKIP_JSSHELL: 1
# ESHOST_SKIP_CH: 1
# ESHOST_SKIP_NODE: 1
ESHOST_SKIP_REMOTE: 1
matrix:
- nodejs_version: 8
- nodejs_version: 10
- nodejs_version: 11

platform:
- x64
Expand All @@ -24,25 +26,38 @@ install:
- ps: Install-Product node $env:nodejs_version
- set ESHOST_PATH=%CD%
- mkdir hosts
# Engine262: Clone, Build, Link and set PATH
- mkdir engine262
- git clone https://github.com/devsnek/engine262.git engine262
- cd %CD%\engine262
- npm install
- npm run build
- npm link
- set ESHOST_ENGINE262_PATH=C:\Users\appveyor\AppData\Roaming\npm\
- set PATH=%PATH%;C:\Users\appveyor\AppData\Roaming\npm\
- where engine262
- set ESHOST_SKIP_ENGINE262=0
- cd %ESHOST_PATH%\hosts
# SpiderMonkey: Curl, Unzip and set PATH
- mkdir spidermonkey
- curl -fsS -o spidermonkey\jsshell-win64.zip https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/jsshell-win64.zip
- 7z e -o%CD%\spidermonkey spidermonkey\jsshell-win64.zip
- set PATH=%PATH%;%CD%\spidermonkey\
- set ESHOST_JSSHELL_PATH=%CD%\spidermonkey\
- where js
- set ESHOST_SKIP_JSSHELL=0
# ChakraCore: Clone, Build and set PATH
- mkdir chakracore
# eventually, we want to have a pre-compiled debug build stored remotely
# - curl -fsSL -o chakracore\cc_windows_all_1_7_1.zip https://aka.ms/chakracore/cc_windows_all_1_7_1
# - 7z -y e -o%CD%\chakracore chakracore\cc_windows_all_1_7_1.zip
# - set PATH=%PATH%;%CD%\chakracore\
# - set ESHOST_CH_PATH=%CD%\chakracore\
- git clone https://github.com/Microsoft/ChakraCore.git chakracore
- msbuild /p:Platform=%PLATFORM% /p:Configuration=Debug %CD%\chakracore\Build\Chakra.Core.sln
- set PATH=%PATH%;%CD%\chakracore\Build\VcBuild\bin\%PLATFORM%_debug
- cd %CD%\chakracore\Build\VcBuild\bin\%PLATFORM%_debug
# - where ch
- where ch
- set ESHOST_SKIP_CH=0
# Return to eshost dir
- cd %ESHOST_PATH%
- where node
- set ESHOST_SKIP_NODE=0
- echo %PATH%
- node -v
- npm install -g npm
Expand Down
12 changes: 8 additions & 4 deletions lib/ConsoleAgent.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
const cp = require('child_process');
const fs = require('fs');
const path = require('path');
const cp = require('child_process');
const recast = require('recast');
const uniqueTempDir = require('unique-temp-dir');

Expand All @@ -16,8 +16,8 @@ const {
rawSource
} = require('./dependencies');

const cpSym = Symbol('cp');
const tpSym = Symbol('tp');
const cpSym = Symbol.for('cp');
const tpSym = Symbol.for('tp');

function generateTempFileName() {
const now = Date.now();
Expand All @@ -37,7 +37,11 @@ class ConsoleAgent extends Agent {

createChildProcess(args = [], options = {}) {
try {
return cp.spawn(this.hostPath, this.args.concat(args), options);
return cp.spawn(
this.hostPath,
this.args.concat(args),
Object.assign({}, this.cpOptions, options)
);
} catch (error) {
return this.createChildProcess(args, options);
}
Expand Down
1 change: 0 additions & 1 deletion lib/agents/d8.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ class D8Agent extends ConsoleAgent {
};
}


normalizeResult(result) {
const match = result.stdout.match(errorRe);

Expand Down
39 changes: 39 additions & 0 deletions lib/agents/engine262.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
'use strict';

const cp = require('child_process');
const fs = require('fs');
const runtimePath = require('../runtimePath');
const ConsoleAgent = require('../ConsoleAgent');

const isWindows = process.platform === 'win32' ||
process.env.OSTYPE === 'cygwin' ||
process.env.OSTYPE === 'msys';

class Engine262 extends ConsoleAgent {
evalScript(code, options = {}) {
if (options.module && this.args[0] !== '--module') {
this.args.unshift('--module');
}

if (!options.module && this.args[0] === '--module') {
this.args.shift();
}

return super.evalScript(code, options);
}

stop() {
if (isWindows && this[Symbol.for('cp')]) {
// This is necessary for killing a node.js .cmd process on windows
this[Symbol.for('cp')].then(child => cp.exec(`taskkill -F -T -PID ${child.pid}`));
} else {
super.stop();
}

return Promise.resolve();
}
}

Engine262.runtime = fs.readFileSync(runtimePath.for('engine262'), 'utf8');

module.exports = Engine262;
5 changes: 1 addition & 4 deletions lib/agents/xs.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,11 @@ class XSAgent extends ConsoleAgent {
return {
name: match[1],
message: match[2],
stack: [],
};
}
return null;
}

normalizeResult(result) {
return result;
}
}
XSAgent.runtime = fs.readFileSync(runtimePath.for('xs'), 'utf8');

Expand Down
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"author": "Brian Terlson",
"license": "MIT",
"devDependencies": {
"common-tags": "^1.8.0",
"eslint": "^4.18.1",
"hasbin": "^1.2.3",
"mocha": "^2.3.4",
Expand Down
50 changes: 50 additions & 0 deletions runtimes/engine262.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* Engine262 exposes a "$" object to its runtime */
/* Using this["\x24"]; prevents overwrite by ConsoleAgent */
var engine262 = this["\x24"];
var $ = {
global: engine262.global,
realm: null,
createRealm(options) {
options = options || {};
options.globals = options.globals || {};

var realm = engine262.createRealm();

realm.evalScript(this.source);
realm.getGlobal = this.getGlobal;
realm.setGlobal = this.setGlobal;
realm.source = this.source;
realm.destroy = function () {
if (options.destroy) {
options.destroy();
}
};

for (var glob in options.globals) {
realm.global[glob] = options.globals[glob];
}

this.realm = realm;

return realm;
},
evalScript(code) {
try {
(this.realm || engine262).evalScript(code);
return { type: 'normal', value: undefined };
} catch (e) {
return { type: 'throw', value: e };
}
},

detachArrayBuffer: engine262.detachArrayBuffer,
getGlobal(name) {
return this.global[name];
},
setGlobal(name, value) {
this.global[name] = value;
},
destroy() { /* noop */ },
IsHTMLDDA() { return {}; },
source: $SOURCE
};
Loading

0 comments on commit e62d966

Please sign in to comment.