AST解web控制流平坦化

2024-03-17 05:20
文章标签 web ast 控制流 平坦

本文主要是介绍AST解web控制流平坦化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 此代码可以解决大部分 while if else 控制流平坦化
  • 原理:
    • 先将 if 语句转为 switch 语句,再将 switch 分支合并,最后删除已合并的分支(具体看代码)
  • 实现效果图
    在这里插入图片描述
  • 首先安装依赖:
npm install @babel/parser
npm install @babel/generator
npm install @babel/traverse        
npm install @babel/types

代码:

/*
* 控制流平坦化 if语句转 switch* */
function del_code(name, consequent) {// 删除合并分支后多余的 赋值和break代码let assignment_bool, break_bool;for (let i = consequent.length - 1; i >= 0; i--) {if (consequent[i].type === "BreakStatement") {if (break_bool) {consequent.splice(i, 1);} else {break_bool = true;}} else if (consequent[i].type === "ExpressionStatement" && consequent[i].expression.type === "AssignmentExpression" && consequent[i].expression.left.name === name) {if (assignment_bool) {consequent.splice(i, 1);} else {assignment_bool = true;}}}
}function merge_branch(name, key, cases_dict) {// 用于递归合并 switch 分支let {consequent} = cases_dict[key];let value = -1;for (let i in consequent) {if (consequent[i].type === "ExpressionStatement" && consequent[i].expression.type === "AssignmentExpression" && consequent[i].expression.left.name === name && consequent[i].expression.right.type === "NumericLiteral") {value = consequent[i].expression.right.value;break;}}if (value !== -1 && cases_dict.hasOwnProperty(value)) {del_cases_dict[value] = 1;return consequent.concat(merge_branch(name, value, cases_dict));    // 继续下一分支的合并}return consequent;
}const fs = require('fs');
const {parse} = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const generator = require("@babel/generator").default;
const types = require("@babel/types");const js_code = fs.readFileSync("./test.js", 'utf8');
const ast_code = parse(js_code);switch_cases_dict = {};
break_node = types.breakStatement();traverse(ast_code, {'IfStatement': {enter(path) {var name = path.node.test.left.name;if (path.node.test.operator === "===") {  // 如果判断符号是 ===if (switch_cases_dict[name] === undefined) {switch_cases_dict[name] = [];}path.node.consequent.body.push(break_node);switch_cases_dict[name].push(types.switchCase(path.node.test.right, path.node.consequent.body));if (path.node.alternate.type === 'BlockStatement') {path.node.alternate.body.push(break_node);let num = path.node.test.right.value + 1;switch_cases_dict[name].push(types.switchCase(types.numericLiteral(num),path.node.alternate.body,));}}},exit(path) {var name = path.node.test.left.name;if (path.parentPath.parentPath.type === "WhileStatement" && switch_cases_dict[name].length !== 0) {console.log(name, "if 已替换 switch");path.replaceWith(types.switchStatement(discriminant = types.identifier(name),cases = switch_cases_dict[name]));}}},'SwitchStatement': {enter(path) {del_cases_dict = {}; // 待删除的 分支语句let cases_dict = {};let cases_list = path.node.cases;let {name} = path.node.discriminant;if (switch_cases_dict.hasOwnProperty(name)) {console.log(name, "switch 分支合并");for (let i in cases_list) {cases_dict[cases_list[i].test.value] = cases_list[i]}for (let key in cases_dict) {   // 合并分支并删除多余代码cases_dict[key].consequent = merge_branch(name, key, cases_dict);del_code(name, cases_dict[key].consequent);}for (let key in del_cases_dict) {delete cases_dict[key]; // 删除多余分支}path.node.cases = Object.values(cases_dict);}},}
})// console.log(generator(ast_code).code)
fs.writeFileSync("./demo.js", generator(ast_code).code, 'utf8')

注:以上js解出来的代码在某些分支会出现多次 return 语句,当然,并不影响运行。我暂时没找到出现这种问题的原因在哪里,如果您找到请务必和我说下,另您也可以在 del_code 函数中删除多的 return 语句

这篇关于AST解web控制流平坦化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/817935

相关文章

Java Web指的是什么

Java Web指的是使用Java技术进行Web开发的一种方式。Java在Web开发领域有着广泛的应用,主要通过Java EE(Enterprise Edition)平台来实现。  主要特点和技术包括: 1. Servlets和JSP:     Servlets 是Java编写的服务器端程序,用于处理客户端请求和生成动态网页内容。     JSP(JavaServer Pages)

BUUCTF靶场[web][极客大挑战 2019]Http、[HCTF 2018]admin

目录   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 [web][HCTF 2018]admin 考点:弱密码字典爆破 四种方法:   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 访问环境 老规矩,我们先查看源代码

EasyPlayer.js网页H5 Web js播放器能力合集

最近遇到一个需求,要求做一款播放器,发现能力上跟EasyPlayer.js基本一致,满足要求: 需求 功性能 分类 需求描述 功能 预览 分屏模式 单分屏(单屏/全屏) 多分屏(2*2) 多分屏(3*3) 多分屏(4*4) 播放控制 播放(单个或全部) 暂停(暂停时展示最后一帧画面) 停止(单个或全部) 声音控制(开关/音量调节) 主辅码流切换 辅助功能 屏

9.8javaweb项目总结

1.主界面用户信息显示 登录成功后,将用户信息存储在记录在 localStorage中,然后进入界面之前通过js来渲染主界面 存储用户信息 将用户信息渲染在主界面上,并且头像设置跳转,到个人资料界面 这里数据库中还没有设置相关信息 2.模糊查找 检测输入框是否有变更,有的话调用方法,进行查找 发送检测请求,然后接收的时候设置最多显示四个类似的搜索结果

JavaWeb【day09】--(Mybatis)

1. Mybatis基础操作 学习完mybatis入门后,我们继续学习mybatis基础操作。 1.1 需求 需求说明: 根据资料中提供的《tlias智能学习辅助系统》页面原型及需求,完成员工管理的需求开发。 通过分析以上的页面原型和需求,我们确定了功能列表: 查询 根据主键ID查询 条件查询 新增 更新 删除 根据主键ID删除 根据主键ID批量删除

利用Django框架快速构建Web应用:从零到上线

随着互联网的发展,Web应用的需求日益增长,而Django作为一个高级的Python Web框架,以其强大的功能和灵活的架构,成为了众多开发者的选择。本文将指导你如何从零开始使用Django框架构建一个简单的Web应用,并将其部署到线上,让世界看到你的作品。 Django简介 Django是由Adrian Holovaty和Simon Willison于2005年开发的一个开源框架,旨在简

web群集--nginx配置文件location匹配符的优先级顺序详解及验证

文章目录 前言优先级顺序优先级顺序(详解)1. 精确匹配(Exact Match)2. 正则表达式匹配(Regex Match)3. 前缀匹配(Prefix Match) 匹配规则的综合应用验证优先级 前言 location的作用 在 NGINX 中,location 指令用于定义如何处理特定的请求 URI。由于网站往往需要不同的处理方式来适应各种请求,NGINX 提供了多种匹

构建高性能WEB之HTTP首部优化

0x00 前言 在讨论浏览器优化之前,首先我们先分析下从客户端发起一个HTTP请求到用户接收到响应之间,都发生了什么?知己知彼,才能百战不殆。这也是作为一个WEB开发者,为什么一定要深入学习TCP/IP等网络知识。 0x01 到底发生什么了? 当用户发起一个HTTP请求时,首先客户端将与服务端之间建立TCP连接,成功建立连接后,服务端将对请求进行处理,并对客户端做出响应,响应内容一般包括响应

(javaweb)mysql---DDL

一.数据模型,数据库操作 1.二维表:有行有列 2. 3.客户端连接数据库,发送sql语句给DBMS(数据库管理系统),DBMS创建--以文件夹显示 二.表结构操作--创建 database和schema含义一样。 这样就显示出了之前的内容。

org.hibernate.hql.ast.QuerySyntaxException:is not mapped 异常总结

org.hibernate.hql.ast.QuerySyntaxException: User is not mapped [select u from User u where u.userName=:userName and u.password=:password] 上面的异常的抛出主要有几个方面:1、最容易想到的,就是你的from是实体类而不是表名,这个应该大家都知道,注意