网易首页 > 网易号 > 正文 申请入驻

JavaScript黑科技:实现一个AST解释器

0
分享至

JavaScript黑科技:直接运行AST(抽象语法树)

实现一个AST解释器

一段JavaScript代码,经过语法分析、语法分析等编译过程之后,会形成一个对应的AST(抽象语法树),形如:

AST是一个JSON格式的大字符串,包含有代码相关信息,如:成员表达式调用、参数、标识符、字符串字面量等等。如:

{"type":"File","program":{"type":"Program","body":[{"type":"ExpressionStatement","expression":{"type":"CallExpression","callee":{"type":"MemberExpression","object":{"type":"Identifier","name":"console"},"property":{"type":"Identifier","name":"log"}},"arguments":[{"type":"StringLiteral","value":"jshaman"}]}}]}}

上面,是一段AST。

本文将要实现的目标的:直接运行这段AST。

先展示运行效果,如下:

即,运行后,输出一了个字符串。

功能意义

其实,如果直接要输出这样一个字符串,在JavaScript中是极为简单的,只需简单的一句:console.log('jshaman')。

那么,为什么要转化为复杂的AST,再执行AST呢?

其意义在于:我们将要实现一个AST解释器,引申而言,实现一个JavaScript解释器。在很多场景中,具有非常实用的意义。

比如,在小程序中屏蔽了Eval函数,而如果我们自己实现解释器,将可突破这个限制。

又比如,JShaman研发团队中,将它用于JavaScript代码加密。

Tip:JShaman是国内专业的JavaScript代码保护研究团队,拥有众多自主的JS代码加密方案,此为其一。

实现方案

要让这个AST能被执行,即要依JavaScript代码标准解释AST。

首先,尝试理解console.log('jshaman')这句代码的AST。通过astexplorer查看:

可以看到,这一句代码转成的AST中,包含7个节点。

那么,要执行这个AST,就要能正确处理这7种节点类型。

由于AST是JSON结构,处理时,可遍历其所有的成员节点。参考astexplorer展示的节点,分别处理:File、Program、ExpressionStatement、CallExpression等,代码如下:

当遇到CallExpression时,获取其对应的参数、方法名等,如下图:

并用apply的方式进行执行,以返回结果。

原理即如此。

编码时,对照着AST节点类型,完成相应的操作即可,为方便调试,可输出节点类型加以分析,如下图:

完整源码

完整源码如下,保存为JS,在NodeJS环境中即可运行。也可在浏览器中直接运行代码,更为方便。

//各节点处理器var visitors = {//File节点,JS代码AST的根节点File(node, scope) {ast_excute(node.program, scope);},//File的次节点,其Body下对应各行JS代码Program(program, scope) {for (i=0; i< program.body.length;i++) {//执行各行代码的ASTast_excute(program.body[i], scope);}},//Call调用AST之外会包裹有一层表达式语句结构ExpressionStatement(node, scope) {return ast_excute(node.expression, scope);},//Call调用CallExpression(node, scope){//遍历callee获取函数体var func = ast_excute(node.callee, scope);//获取参数var args = node.arguments.map( function(arg){return ast_excute(arg, scope)});var value;if (node.callee.type === 'MemberExpression') {value = ast_excute(node.callee.object, scope);}//返回函数运行结果return func.apply(value, args)},//成员表达式MemberExpression(node, scope){//获取对象,如consolevar obj = ast_excute(node.object, scope);//获取对象的方法,如logvar name = node.property.name//返回表达式,如console.logreturn obj[name]},//标识符Identifier(node, scope) {return scope[node.name];},//字符串字面量StringLiteral(node) {return node.value;},};//执行function ast_excute(node, scope) {var _evalute = visitors[node.type];if (!_evalute) {throw new Error("未知的AST类型:" , node.type);}// 递归调用return _evalute(node, scope);}var ast = {"type":"File","program":{"type":"Program","body":[{"type":"ExpressionStatement","expression":{"type":"CallExpression","callee":{"type":"MemberExpression","object":{"type":"Identifier","name":"console"},"property":{"type":"Identifier","name":"log"}},"arguments":[{"type":"StringLiteral","value":"jshaman"}]}}]}};ast_excute(ast, {console});

AST简化

以上代码中,使用的是简化过的AST。astexplorer默认生成的AST,内容较多,如下图:

其包含有代码行号、起始、结束等位置信息:

但这些冗长的位置信息对于执行是无用的,可以将其去除,实现简化的AST:

这样就成为了代码中使用的、较简短的AST。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
两大车企官宣大降价!

两大车企官宣大降价!

电动知家
2024-04-29 17:15:53
中超最新积分榜:北京国安客胜攀升第3,山东泰山逆转豪取3连胜!

中超最新积分榜:北京国安客胜攀升第3,山东泰山逆转豪取3连胜!

英超这些事儿
2024-04-30 22:15:04
深夜通报:5人遇难33人受伤!

深夜通报:5人遇难33人受伤!

家在栖霞
2024-05-01 18:51:29
好家伙!《维和防暴队》上映差评一片,观众的差评理由出奇一致

好家伙!《维和防暴队》上映差评一片,观众的差评理由出奇一致

娱乐圈笔娱君
2024-05-01 15:46:28
广东梅大高速塌方致19人死30人伤,现场有车辆爆炸起火,场景曝出

广东梅大高速塌方致19人死30人伤,现场有车辆爆炸起火,场景曝出

胡侃社会百态
2024-05-01 14:26:49
以总理:无论停火谈判如何,都将进攻拉法!拉法军事行动最终计划已获批!欧委会主席:完全不可接受

以总理:无论停火谈判如何,都将进攻拉法!拉法军事行动最终计划已获批!欧委会主席:完全不可接受

每日经济新闻
2024-04-30 21:06:23
违规吃喝,4人被通报

违规吃喝,4人被通报

锡望
2024-04-30 16:28:21
婚礼现场,新娘美丽动人新郎却不敢牵手,知情人:他们才认识14天

婚礼现场,新娘美丽动人新郎却不敢牵手,知情人:他们才认识14天

佑宛故事汇
2024-04-30 13:53:08
笑麻了!女子戴8万的卡地亚项链白衣服变黑,我却笑死在评论区

笑麻了!女子戴8万的卡地亚项链白衣服变黑,我却笑死在评论区

都靓AmBerr
2024-05-01 17:50:48
将被抹除!哈马斯再度求饶:珍视和平,希望回到加沙帮助重建家园

将被抹除!哈马斯再度求饶:珍视和平,希望回到加沙帮助重建家园

娱宙观
2024-04-28 14:52:33
揭秘华晨宇香港“消失”之谜,央视正片揭穿真相!

揭秘华晨宇香港“消失”之谜,央视正片揭穿真相!

胡图图聊日常
2024-05-01 11:59:04
回顾:张阳畏罪自杀,刘源评价“五毒俱全,问题比郭、徐更严重”

回顾:张阳畏罪自杀,刘源评价“五毒俱全,问题比郭、徐更严重”

李姐历史
2024-04-26 09:31:58
成人片之王xxx,网飞尺度炸出新高

成人片之王xxx,网飞尺度炸出新高

独立鱼
2024-03-15 23:46:54
两亿股民请注意,无论接下来有没有牛市,这个方向都千万不要碰了

两亿股民请注意,无论接下来有没有牛市,这个方向都千万不要碰了

静守时光落日
2024-05-01 17:00:01
可圈可点!徐昕半场2中2拿到8分4板 罚球5中4

可圈可点!徐昕半场2中2拿到8分4板 罚球5中4

直播吧
2024-05-01 20:47:17
快收藏!乒乓球5月赛程出炉:王曼昱、陈梦竞争奥运单打最后一战

快收藏!乒乓球5月赛程出炉:王曼昱、陈梦竞争奥运单打最后一战

知轩体育
2024-04-30 21:43:03
抗疫英雄李兰娟百亿产业曝光,儿子竟占股百分之百,引发民众热议

抗疫英雄李兰娟百亿产业曝光,儿子竟占股百分之百,引发民众热议

寻梦小真
2024-04-15 22:35:58
月薪5万的豪宅管家:“老板花上亿并购公司,但水电费多了会破防”

月薪5万的豪宅管家:“老板花上亿并购公司,但水电费多了会破防”

ELLEMEN 睿士
2024-04-29 16:04:25
放弃争4阻击死敌?摩根:热刺球迷竟愿球队输曼城 真是小球队心态

放弃争4阻击死敌?摩根:热刺球迷竟愿球队输曼城 真是小球队心态

直播吧
2024-05-01 19:54:15
看完《歌手》曝光的阵容,内心五味杂陈,想问:这选人是认真的吗

看完《歌手》曝光的阵容,内心五味杂陈,想问:这选人是认真的吗

娱乐圈十三太保
2024-04-30 17:11:41
2024-05-01 21:54:44
javascript知识园
javascript知识园
javascript编程知识分享,JS加密、JS混淆等等。
189文章数 419关注度
往期回顾 全部

科技要闻

余承东卸任华为终端CEO 新任命为董事长

头条要闻

上海男子被流浪猫绊倒投喂者被判赔24万 案件将迎再审

头条要闻

上海男子被流浪猫绊倒投喂者被判赔24万 案件将迎再审

体育要闻

"意甲最佳"金玟哉 踢回了中超水平...

娱乐要闻

黄子韬被曝求婚徐艺洋 大量亲密照曝光

财经要闻

万科突发!王石,放弃了!

汽车要闻

预售2.89-3.49万 奔腾小马正式开启预售

态度原创

艺术
健康
本地
旅游
公开课

艺术要闻

用耳朵看展览?西岸美术馆最新特展关注声音艺术

春天野菜不知不识莫乱吃

本地新闻

食味印象 | 潍坊:碳水脑袋的人间乐园

旅游要闻

假期最受欢迎的小众目的地 会玩的人已经去了

公开课

父亲年龄越大孩子越不聪明?

无障碍浏览 进入关怀版