博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
switch的指令流水线处理
阅读量:6879 次
发布时间:2019-06-26

本文共 3418 字,大约阅读时间需要 11 分钟。

hot3.png

//标签A://条件不满足  && $goto(B);//A代码段//$goto(END);//标签B://条件不满足  && $goto(C);//B代码段//$goto(END);//标签C://条件不满足  && $goto(END);//C代码段//条件END://空代码

不同的宿主语言的语法形式和底层的支持不同, 如果我们的翻译的目标是lua, 众所周知在lua中是没有switch 语句的, 也没有goto或者jmp

这种跳转命令的。

如果在lua中我们要使用状态转移类似的指令可以通过字典的hash特性,每个标识是字典的一个key, 执行字典的内联函数来替换多个if的丑陋的代码。 因为swich的分支是可以预测的, 所以我们在做分析预测的时候要加入一个如果全部都不命中分支。

对比之前的代码:

cls.SwitchCase = function (e) {            var test;            if(e.test) {                test =  exports.GetValueByType(                    e.test.type,                    e.test);            }            var codes = [];                         if(e.consequent) {                 var consequent = e.consequent;                 var len = consequent.length;                                                  for(var i =0;i< len;i++) {                     codes.push(exports.GetValueByType(                    consequent[i].type,                    consequent[i]) + "\n");                 }            }            var code  = "";            var len   = exports.stack_switch.length;            if(!exports.stack_switch[0]) {                console.log("[error] switch stack error.");            }                                                if(!test) {                 var label = exports.stack_switch.pop();                 code += label+":\n";                 code +=  codes.join("");            } else {                 if(codes.length == 0) {                     exports.merge_switch.push("$istrue("+exports.stack_switch[0]+"!="+test+")");                     return "";                 }                                  var label = exports.stack_switch.pop();                 code += label+":\n";                 if(len-1 < 0) {                    var next  = exports.stack_switch[0];                 }else {                    var next  = exports.stack_switch[exports.stack_switch.length-1];                 }                             if(exports.merge_switch.length != 0) {                     test = exports.merge_switch.join("&&") + "&& $istrue("+exports.stack_switch[0]+"!="+test+")";                     exports.merge_switch = [];                 } else {                     test = "$istrue("+exports.stack_switch[0]+"!="+test+")";                 }                 code += test + " && $goto("+next+");\n " + codes.join("");            }                                   return code;        } ///end of SwitchCaseCODE318790496971174301H:$istrue(a!=1) && $goto(CODE318790431625819229L); print (1)CODE318790431625819229L:$istrue(a!=1) && $goto(CODE31879087087226576H); print (2)

利用hash的代码性能要比这种顺序分支的性能要好。特别是在分支条件很多的情况。测试代码。。。

switch (a) {    case 1:    print(1)    break;    case 2:    print(2)    break;    default:    print(3)    break;}

生成:

local exports=exportslocal CODE080090262481404737L = {[1]="CODE080090481865709301H",[2]="CODE080090448711626623L",["default"]="CODE08009020260687113H"}if exports["CODE08009020260687113H"] == nil thenexports["CODE080090481865709301H"]=function ()print (1)endexports["CODE080090448711626623L"]=function ()print (2)endexports["CODE08009020260687113H"]=function ()print (3)endendlocal __indexer__ = CODE080090262481404737L[a]if __indexer__ == nil then __indexer__=CODE080090262481404737L["default"]endexports[__indexer__]()

好了。。这个问题就解决了。 其实我们可以预处理这些函数块, 并且让这些函数脱离标准流水线, 作为预处理的代码,但是为了得到函数生命周期内的上下文(只在定义的时候继承) 必须定义在代码自省的位置。 如果是这样就不得不加上一个code 缓存的判断。 多次一举。

转载于:https://my.oschina.net/littlemonkeyc/blog/1859579

你可能感兴趣的文章
利用SVG制作不规矩背景的链接导航
查看>>
Linux - 一次运行多个命令
查看>>
10.C# -- 函数参数,参数数组,值传递函数,引用传递函数,输出函数,无参函数...
查看>>
BT5设置ip地址
查看>>
Effective Java读后感
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
德国博世百年风雨启示录(下):实业强国
查看>>
(整理)用Elixir做一个多人扑克游戏 4
查看>>
qcom 跨平台的串口调试工具 PKGBUILD
查看>>
Delphi 时间格式化,动态显示时间,显示最新时间
查看>>
在JAVA中将NEW一分为2,分步进行[反射机制产生类]
查看>>
Java多态性的两个特殊情况
查看>>
我的友情链接
查看>>
怎么改变Win7登陆背景图片
查看>>
虚拟带库和物理带库比较
查看>>
AD委派加域权限
查看>>
在Delphi 7中使用加密的SQLite
查看>>
wordpress 无用的RSS Feed Cache
查看>>
Linux Vi编辑器的基本使用方法
查看>>