发动机262
在JavaScript中实施ECMA-262
目标
- 100%的光谱遵守率
- 回顾
- 修改的便利
非目标
- 以牺牲任何目标为代价的速度
这个项目受 行为守则。 。 。 .
加入我们 #engine262:matrix.org。 。 。 .
从主线更改
- 增加了更多的发电机,以便通过仅仅拨打
.next()在返回的传动器上.- 应该可以步入大多数用户代码,包括标准库函数的回调.
- 大多得不到支持的情景正在从标准库函数内步入代理获取器/发送器.
例如,目前无法在使用代理服务器时步入代理获取器
thisValue用于标准库函数. - 使这些特性能够步入的过程相当简单:你寻找一些情况
unwind()函数被使用并替换为yield*。 。 。 . 棘手的部分是使用yield*强制您使包含的函数成为生成函数,这意味着该函数的调用者现在也需要使用yield*或者说unwind()。 。 。 .
为什么会这样
在帮助开发JavaScript的新功能的同时,我发现了其中之一 最有用的方法 找出什么是可行的什么是不能 实际使用新特性运行代码. 宝贝 这真是太棒了 但是 有时候,一些特征只是不能 很好地代表它。 同样, 实施其中一种发动机的特性是一项大型工作,涉及 长编译时间和有优化编译器的烦扰错误.
引擎262是一个工具,允许 JavaScript 开发者在新位置有一个沙盒 特性可以迅速被原型和探索. 例如,添加: 执行表达式 至此引擎与以下 diff 一样简单:
--- a/src/evaluator.mjs
+++ b/src/evaluator.mjs
@@ -232,6 +232,8 @@ export function* Evaluate(node) {
case 'GeneratorBody':
case 'AsyncGeneratorBody':
return yield* Evaluate_AnyFunctionBody(node);
+ case 'DoExpression':
+ return yield* Evaluate_Block(node.Block);
default:
throw new OutOfRange('Evaluate', node);
}
--- a/src/parser/ExpressionParser.mjs
+++ b/src/parser/ExpressionParser.mjs
@@ -579,6 +579,12 @@ export class ExpressionParser extends FunctionParser {
return this.parseRegularExpressionLiteral();
case Token.LPAREN:
return this.parseParenthesizedExpression();
+ case Token.DO: {
+ const node = this.startNode();
+ this.next();
+ node.Block = this.parseBlock();
+ return this.finishNode(node, 'DoExpression');
+ }
default:
return this.unexpected();
}
这种简单适用于许多其他建议,例如: 可选链条, (中文(简体) ), 模式匹配, (中文(简体) ), 管道操作员还有更多 这个引擎也有 用于在ECMA-262和 测试262,用于 符合 JavaScript 执行.
所需资源
要运行引擎262本身, 支持最近 ECMAScript 特性的引擎
这是需要的。 此外,《国家行动倡议》bin/engine262.js)和试验262跑道
(单位:千美元)test/test262/test262.js)需要最新版本的Node.js.
使用引擎262
在线使用 : https://engine262.js.org (英语)
您可以从 GitHub 软件包。 。 。 .
如果您在全球安装, 您可以像这样使用 CLI :
$ engine262
或者,你可以在本地安装并使用API:
'use strict';
const {
Agent,
setSurroundingAgent,
ManagedRealm,
Value,
CreateDataProperty,
inspect,
} = require('engine262');
const agent = new Agent({
// onDebugger() {},
// ensureCanCompileStrings() {},
// hasSourceTextAvailable() {},
// onNodeEvaluation() {},
// features: [],
});
setSurroundingAgent(agent);
const realm = new ManagedRealm({
// promiseRejectionTracker() {},
// resolveImportedModule() {},
// getImportMetaProperties() {},
// finalizeImportMeta() {},
// randomSeed() {},
});
realm.scope(() => {
// Add print function from host
const print = new Value((args) => {
console.log(...args.map((tmp) => inspect(tmp)));
return Value.undefined;
});
CreateDataProperty(realm.GlobalObject, new Value('print'), print);
});
realm.evaluateScript(`
'use strict';
async function* numbers() {
let i = 0;
while (true) {
const n = await Promise.resolve(i++);
yield n;
}
}
(async () => {
for await (const item of numbers()) {
print(item);
}
})();
`);
// a stream of numbers fills your console. it fills you with determination.
测试引擎262
此项目可针对 测试262,这特别有用 用于开发新的特性和/或测试:
$ # build engine262
$ npm build
$ # update local test262 in test/test262/test262
$ git submodule update --init --recursive
$ # update local test262 to a pull request
$ pushd test/test262/test262
$ git fetch origin refs/pull/$PR_NUMBER/head && git checkout FETCH_HEAD
$ popd
$ # run specific tests
$ npm run test:test262 built-ins/AsyncGenerator*
$ # run all tests
$ npm run test:test262
产出将显示全部测试、通过测试、失败测试和跳过测试的计数.
相关项目
许多人和组织试图撰写 JavaScript 解释器 在JavaScript中很像引擎262,目标不同. 其中一些是 虽然引擎262并非基于其中任何一种,但在此列出以供参考.