Lua5.1.1的一个隐藏BUG

本文详细探讨了Lua 5.1.1版本中一个隐藏的bug,当函数体内的全局变量和常量超过255个时,会导致由数字常量和访问table表达式组成的复合表达式产生错误结果。通过示例代码和深入的虚拟机指令分析,揭示了该问题的根源在于寄存器分配算法,并解释了为何在某些情况下会出现意外的结果。
摘要由CSDN通过智能技术生成

在最近的lua maillist上,三巨头之一的Roberto Ierusalimschy报告了一个5.1.1版本的bug:当一个函数里用到了超过 255个不同的全局变量和常量时,由数字常量和访问table的表达式组成的复合表达式(比如"2*a.x")就有可能产生很奇怪的结果。比如 下面这段程序:
kkk = 2;
v1=2;  v2=2;  v3=2;  v4=2;  v5=2;  v6=2;  v7=2;  v8=2;
v9=2; v10=2; v11=2; v12=2; v13=2; v14=2; v15=2; v16=2;
v17=2; v18=2; v19=2; v20=2; v21=2; v22=2; v23=2; v24=2;
v25=2; v26=2; v27=2; v28=2; v29=2; v30=2; v31=2; v32=2;
v33=2; v34=2; v35=2; v36=2; v37=2; v38=2; v39=2; v40=2;
v41=2; v42=2; v43=2; v44=2; v45=2; v46=2; v47=2; v48=2;
v49=2; v50=2; v51=2; v52=2; v53=2; v54=2; v55=2; v56=2;
v57=2; v58=2; v59=2; v60=2; v61=2; v62=2; v63=2; v64=2;
v65=2; v66=2; v67=2; v68=2; v69=2; v70=2; v71=2; v72=2;
v73=2; v74=2; v75=2; v76=2; v77=2; v78=2; v79=2; v80=2;
v81=2; v82=2; v83=2; v84=2; v85=2; v86=2; v87=2; v88=2;
v89=2; v90=2; v91=2; v92=2; v93=2; v94=2; v95=2; v96=2;
v97=2; v98=2; v99=2; v100=2; v101=2; v102=2; v103=2; v104=2;
v105=2; v106=2; v107=2; v108=2; v109=2; v110=2; v111=2; v112=2;
v113=2; v114=2; v115=2; v116=2; v117=2; v118=2; v119=2; v120=2;
v121=2; v122=2; v123=2; v124=2; v125=2; v126=2; v127=2; v128=2;
v129=2; v130=2; v131=2; v132=2; v133=2; v134=2; v135=2; v136=2;
v137=2; v138=2; v139=2; v140=2; v141=2; v142=2; v143=2; v144=2;
v145=2; v146=2; v147=2; v148=2; v149=2; v150=2; v151=2; v152=2;
v153=2; v154=2; v155=2; v156=2; v157=2; v158=2; v159=2; v160=2;
v161=2; v162=2; v163=2; v164=2; v165=2; v166=2; v167=2; v168=2;
v169=2; v170=2; v171=2; v172=2; v173=2; v174=2; v175=2; v176=2;
v177=2; v178=2; v179=2; v180=2; v181=2; v182=2; v183=2; v184=2;
v185=2; v186=2; v187=2; v188=2; v189=2; v190=2; v191=2; v192=2;
v193=2; v194=2; v195=2; v196=2; v197=2; v198=2; v199=2; v200=2;
v201=2; v202=2; v203=2; v204=2; v205=2; v206=2; v207=2; v208=2;
v209=2; v210=2; v211=2; v212=2; v213=2; v214=2; v215=2; v216=2;
v217=2; v218=2; v219=2; v220=2; v221=2; v222=2; v223=2; v224=2;
v225=2; v226=2; v227=2; v228=2; v229=2; v230=2; v231=2; v232=2;
v233=2; v234=2; v235=2; v236=2; v237=2; v238=2; v239=2; v240=2;
v241=2; v242=2; v243=2; v244=2; v245=2; v246=2; v247=2; v248=2;
v249=2; v250=2; v251=2; v252=2; v253=2; v254=2; v255=2; v256=2;

obj = { kkk = 7 };
print(5 * obj.kkk)
 

它打印出的值不是35而是49。有的朋友可能会认为上面这一大堆代码并没有处于某个函数体中。其实不然,一个lua文件里的所有代码 组成了一个主代码块(chunk),编译器会为主代码块隐式地生成一个函数定义,随后虚拟机调用这个函数完成对该lua文件的解释执行, 所以上面的代码确实是处于一个(编译器为我们自动生成的)函数体中的。由于全局变量名实际上就是一个常量字符串(参见[ 1]),因此下面的代码也会出现同样的bug。
local g_vars = {
"kkk",
"v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8",
"v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16",
"v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24",
"v25", "v26", "v27", "v28", &#

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值