烟花
在希腊神话中是流浪星Areios的神,与行星火星相识别. Pyroeis (古希腊语:Πυρόεις).
{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''.
Pyroeis是一个独立项目,来源于 冯加里,由datamoc维护. 装作 @datamoc/pyroeis。 。 。 .
A 类 卢亚 5.4 VM 以 JavaScript ES6 写成, 目标都针对 节点.js 财务报告和审定财务报表 浏览器 环境。 这个软件包执行Lua 5.4.6,包括扩展辅助库(lauxlib功能和综合测试覆盖。 与Lua 5.5.1的对接工作正在进行中,并在 文件/lua-5.5.1还没有完成任何里程碑 Lua 5.4.6 结束 lua.lua_version 财务报告和审定财务报表 _VERSION。 。 。 .
特征
- 5.4.6 遵守情况:执行Lua 5.4语言和标准图书馆,外加一个扩展辅助图书馆(
lauxlib) (中文(简体) ). - 横线: 在Node.js和现代浏览器中运行.
- 广泛: 容易与现有的JavaScript项目集成.
- 综合测试:包括所有核心和扩展功能的测试.
- 5.5.1 正在调整: 移徙计划、差异预告和合规跟踪 文件/lua-5.5.1。 。 。 .
- 内存会计钩数字 :
lua_setallocf让嵌入器观察、绑定或拒绝 VM 的内部字符串和缓冲分配;拒绝像一个失败的 C 分配器(LUA_ERRMEM) (中文(简体) ).
业绩
Pyroeis在JavaScript中解释Lua,因此在紧数圈上比原生JavaScript慢得多. docs/benchmark 是一个自成一体的页面,在Lua (Pyroeis) 和 Plain JavaScript 在自己的浏览器中运行相同的算法,并报告测量到的减速. 服务于 docs/ 带有 GitHub 页面以发布,并运行 npm run bench:build 重新生成 docs/benchmark/pyroeis.bundle.js 更改后 src/。 。 。 .
可选数字汇编
PyroeisVm.compile(pathOrLuaRef) 抓取 Lua 函数并返回可重用
JavaScript 可调用. 生成的合格纯数字函数执行
JavaScript, 包括完整的嵌入数字 for 循环 :
const { PyroeisVm } = require('@datamoc/pyroeis/src/pyroeis-vm.js');
const vm = new PyroeisVm();
vm.run(`
function sum(n)
local s = 0
for i = 1, n do s = s + i end
return s
end
`);
const sum = vm.compile('sum');
console.log(sum.compiled, sum(100000)); // true, 5000050000
sum.release(); // optional: release the captured Lua function immediately
此选入编译器支持数字常数, 参数, 局部, 任务,
+, (中文(简体) ), -, (中文(简体) ), *, (中文(简体) ), /, (中文(简体) ), ^数字 for 循环.
呼叫、全局/更新值、表格、比较/比值、变位符和其他字节码
使用口译。 不支持的输入类型, 整数计算
安全数字范围、浮动回路控制、调试钩和活性执行限制
还使用翻译。 保留了光整数外溢和浮点类型;
使用情况 LuaFloat 如现有的VM API那样,明确通过整体浮标.
可调用返回第一个结果, 在编译时抓取函数
时间;重新定义其全局性并不能取而代之. compiled 报告资格,
reason 解释不支持的代码,以及 source 曝光生成的 JavaScript
躯体。 资格并不能保证每次援引都走捷径.
生成的代码被缓存每个Lua原型. 禁止的环境
new Function (例如没有 unsafe-eval)使用翻译.
没有生成的代码包含 Lua 源文本或标识符名称 .
运行 node tools/benchmark-numeric.js 校验的比较
翻译,在您的机器上编译了Lua和本地JavaScript.
汇编和执行限制
compile 被故意禁用时 limits 活动:可调用
总是在翻译中运行。 生成的 JavaScript 不会被
指令计数钩、图案匹配中断点或分配点
钩子,所以它必须执行 预算自己,这是第二
正确执行机制(每个循环形状,一个预算与
译员,在警卫返回越共后没有新的预算. 跳过它保持
沙盒在一个地方保证。 这不是一个差距 围绕:
- 运行你不信任的代码
run编号 :call与limits(和sandbox(三); - 如果你需要速度,请打电话
compile只针对您所写或审查的函数, a 无limits,并保留一个单独的,有限的VM上的不可信脚本.
limits.coroutines, (中文(简体) ), limits.tables 财务报告和审定财务报表 limits.closures 计算对象的脚本
创建每个顶级呼叫,而不是活的(垃圾收集器不是)
(可观察). 在一次越狱的越狱中 剧本还能跟上
每个调用许多新对象: 对于不可信脚本, 使用每个脚本的新 VM, 或者丢弃
越战结束 超过任何限制的呼叫失败 LimitError 谁
limit 说吧instructions, (中文(简体) ), time, (中文(简体) ), memory, (中文(简体) ), coroutines, (中文(简体) ), tables, (中文(简体) ),
closures和谁的信息是 <limit> limit exceeded打开 run, (中文(简体) ), call, (中文(简体) ), callRef, (中文(简体) ),
Coroutine#resume 财务报告和审定财务报表 protect 相同(memory 保留 not enough memory) (中文(简体) ).
离线 Lua 到 JavaScript 翻译
离开卢阿, lua2js 将Lua源变成JavaScript,开发者可以读取并不断编辑. 它与上面的运行时数编译器是分开的:它从不运行Lua,从源头打印出平面的JavaScript并标记它无法翻译的东西.
npx lua2js game.lua -o game.js --format esm # none (default) | esm | cjs
const { transpile } = require('@datamoc/pyroeis/src/ltranspile.js');
const { code, warnings, exports, freeGlobals } = transpile(luaSource, { format: 'cjs' });
function stats(t)
local sum = 0
for i, v in ipairs(t) do sum = sum + v end
return sum, sum / #t
end
function stats(t) {
let sum = 0;
for (let i = 1; i <= t.length; i++) {
const v = t[i - 1];
sum += v;
}
return [sum, sum / t.length];
}
翻译内容:当地人const编号 :let,在"阴影"或"JS"保留词上被更名),功能和关闭(单词表达时的缩写), if编号 :while编号 :repeat/数字和通用 for, (中文(简体) ), goto continue, (中文(简体) ), and编号 :or 三角偶数,字符串接合(template literal),表格作为数组或对象(从使用中推导出),多返回(阵列,每个函数推断出),活字,方法,有字形图案字符串的Lua图案(find, (中文(简体) ), match, (中文(简体) ), gmatch, (中文(简体) ), gsub转换为 RegExp),和共同部分 math, (中文(简体) ), string, (中文(简体) ), table, (中文(简体) ), os 财务报告和审定财务报表 io。 。 。 .
一个在线版本生活在 docs/lua2js/index.html:粘贴Lua,读取JavaScript,并在浏览器中标出两者的基准.
信任输出前需要知道的事情:
- 每个无法忠实翻译的构造都得到
// TODO(lua2js): ...注释和条目warnings覆盖元件、皮层、没有RegExp等值单位(%b, (中文(简体) ),%f或不是弦词,goto其他continue,比特运算符(JavaScript使用32个比特)和不返回数组的延时器.freeGlobals列出主机必须提供的全局 。 一个警告unsafe: true标记到达 JavaScript 环境的构造(eval, (中文(简体) ),Function, (中文(简体) ),globalThis, (中文(简体) ),process, (中文(简体) ),fetch...)或原型机(英语:t.__proto__, (中文(简体) ),t.constructor:被翻译的代码是平版JavaScript,不是沙盒,所以不要运行未信任的Lua的翻译. - Lua 阵列为 1- 基数, JavaScript 阵列为 0- 基数: 索引被转移(
t[i]变成t[i - 1]),当表或索引已知为数字;否则该索引将单独被标出并标出. nil实值undefined。 。 。 .if x变成truthy(x)(卢亚请)0财务报告和审定财务报表""除非x已知为布尔.a or b保持Lua的意义(truthy(a) ? a : b,或a ?? b何时a已经知道永远false; 计 数nullishOr选项(--nullish-or总是发出短的a ?? b,这只与Lua不同a实值false。 。 。 .- 整数和浮数都是JavaScript数字:
2^53及以后,1.0打印为1,以及弦与数的强迫("10" + 1)没有保留. - 小型帮助者(
truthy, (中文(简体) ),mod, (中文(简体) ),format,.)只有在使用时才会在输出的顶端放出.
安装
npm install @datamoc/pyroeis
使用量
基本示例
const { lua, lauxlib, lualib } = require('@datamoc/pyroeis');
// Create a new Lua state
const L = lauxlib.luaL_newstate();
lualib.luaL_openlibs(L); // Load standard libraries
// Execute Lua code
lauxlib.luaL_dostring(L, lua.to_luastring("print('Hello from Lua 5.4!')"));
// Close the Lua state
lua.lua_close(L);
类型脚本
货包载有其申报src/pyroeis.d.ts: import { PyroeisVm, LuaToJsOptions } from '@datamoc/pyroeis' 输入时没有 @ts-expect-error。C-API命名空间(lua, (中文(简体) ), lauxlib, (中文(简体) ), lualib输入为 any。 。 。 .
为什么Pyroeis有自己的 JavaScript QQ Lua 交换 API
Pyroeis 将 Lua 用于应用程序规则、游戏策略和主机脚本
控制可用的操作. PyroeisVm 因此转换为普通
JavaScript 对象、阵列和地图输入 Lua 表格,将 Lua 表格读回
JavaScript 数据, 并打开主机操作 defineFunction复制
表格不为原JavaScript对象提供活控.
fengari-interop 服务a
不同的集成模式: JavaScript 对象仍然可以通过
用户数据,Lua值可以被从 JavaScript 中包裹使用,以及它的 js
库包括访问 JavaScript 全球环境。 那个模型是
对于需要直接与JavaScript API合作的可信任的Lua代码有用.
我们的默认接口保留了与 Lua 数据合作的脚本和选择的主机
而不是授予一般桥梁.
这个选择还保留了呼叫、Lua参考、皮层、错误处理和
在同一VM API范围内执行预算. BigInt二进制字符串,
LuaFloat, (中文(简体) ), Multi 财务报告和审定财务报表 Yield 有明确的转换。 函数、 线程
并使用全部用户数据 LuaRef 手柄;普通表格为快照.
MWG演示进一步采用了这种方法:将目标描述传送到一个
工人和接受一个有效的目标指数, 而主机保留地图,
路径搜索器和渲染对象.
权衡是转换工作,没有自动共享对象
身份、原型或复制数据的可变行为。 Java 脚本周期
无法当前按下表格; Lua 表格周期在读取时保留.
回调仍然是信任的主机代码: 执行预算不能预先防止任意性
JavaScript 或覆盖其全部分配. 这个API不是完全孤立
机制,以及 fengari-interop 不仅仅是因为它本身就不安全
提供更广泛的准入.
上游桥梁进口 fengari 并宣布其为同龄人;
这不是一个支持的倒车桥 @datamoc/pyroeis。使用或移植
它要求验证 VM 和 C-API 兼容性以及
权威接触到脚本。 见 详细设计和实例
和上游 执行
财务报告和审定财务报表 软件包显示。 。 。 .
扩展辅助图书馆lauxlib(中文(简体) )
const { lauxlib } = require('@datamoc/pyroeis');
// Example: Using luaL_addgsub for string substitution
const B = new lauxlib.luaL_Buffer();
lauxlib.luaL_buffinit(L, B);
lauxlib.luaL_addgsub(B, lua.to_luastring("hello world"), lua.to_luastring("world"), lua.to_luastring("Lua"));
lauxlib.luaL_pushresult(B);
记忆会计钩( T)lua_setallocf(中文(简体) )
lua_setallocf(L, allocf, ud) 同步安装每个状态的钩子
allocf(ud, nsize) 在每一个内部之前 Uint8Array 拨款
nsize 字节(包含全新大小,增长再分配). 正在返回
通常允许分配; 扔出拒绝, 从而中止
附加有状态的受保护呼叫 LUA_ERRMEM 和标准
"内存不足"出错对象,使状态可用. lua_getallocf(L)
返回时 [allocf, ud]。 。 。 .
const { lua, lauxlib, lualib } = require('@datamoc/pyroeis');
const L = lauxlib.luaL_newstate();
lualib.luaL_openlibs(L);
let budget = 1024;
lua.lua_setallocf(L, (ud, nsize) => {
if (nsize > ud.budget) throw new Error('over budget');
}, { budget });
lauxlib.luaL_dostring(L, lua.to_luastring('return ("x"):rep(10)'));
console.log(lua.lua_tojsstring(L, -1)); // xxxxxxxxxx
这是C Lua的JavaScript形状 lua_Alloc 扩展点: 是
会计而不是所有权(JavaScript引擎拥有内存,并且有
没有免费通知)。 未被起诉:无国籍者 to_luastring 转换
嵌入式驱动器本身,零大小分配,以及少量内部
工地没有的临时工 lua_State 在手边。 见 src/lmem.js 联 合 国
确切的合同.
测试
运行测试套件 :
npm test
用于扩展测试(例如辅助库功能):
npm run test:extended
文档
许可证
麻省理工学院 米歇尔·魏纳赫特(达塔莫克), (中文(简体) ), 比诺伊特·吉安纳赫利, (中文(简体) ), 显示器,和贡献者.
从 @ datamoc/ fengari 迁移
安装 @datamoc/pyroeis 并更新您的进口。 使用 PyroeisVm 高级VM API。 遗产 src/fengari* 入境点和入境点 FengariVm 删除了别名; 使用 src/pyroeis.js 编号 : src/pyroeis-vm.js 财务报告和审定财务报表 PyroeisVm。浏览器捆绑会曝光 Pyroeis 只有这个 0.6.0版本删除了剩余的冯加里名: Lua 库 fengari 现在 pyroeis,常数 FENGARI_* 为: PYROEIS_* (并描述花花鸟,而不是花花鸟), luaopen_fengari 实值 luaopen_pyroeis, (中文(简体) ), LUA_FENGARILIBNAME 实值 LUA_PYROEISLIBNAME,则 libs 选项 'pyroeis',然后从 PYROEISCONF 环境变量( JSON 对象, 如 {"LUAI_MAXSTACK":100000}改为 FENGARICONF。 。 。 .
交互式演示
这个 平罗艾斯网站 包含 执行限制复制, (中文(简体) ), 四模式基准,则 Lua-to-Java脚本翻译器 (单位:千美元) Lua 控制的 MWG 机器人。 。 。 .
运行 npm run pages:build 用 SHA-512 验证生成浏览器捆绑并检索被绑定的演示依赖,然后服务 docs/ 超过HTTP(例如, python -m http.server 8765 --directory docs) (中文(简体) ). GitHub Pages 工作流程构建并部署同样的文件夹 master。 。 。 .