在最近的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", "v29", "v30", "v31", "v32",
"v33", "v34", "v35", "v36", "v37", "v38", "v39", "v40",
"v41", "v42", "v43", "v44", "v45", "v46", "v47", "v48",
"v49", "v50", "v51", "v52", "v53", "v54", "v55", "v56",
"v57", "v58", "v59", "v60", "v61", "v62", "v63", "v64",
"v65", "v66", "v67", "v68", "v69", "v70", "v71", "v72",
"v73", "v74", "v75", "v76", "v77", "v78", "v79", "v80",
"v81", "v82", "v83", "v84", "v85", "v86", "v87", "v88",
"v89", "v90", "v91", "v92", "v93", "v94", "v95", "v96",
"v97", "v98", "v99", "v100", "v101", "v102", "v103", "v104",
"v105", "v106", "v107", "v108", "v109", "v110", "v111", "v112",
"v113", "v114", "v115", "v116", "v117", "v118", "v119", "v120",
"v121", "v122", "v123", "v124", "v125", "v126", "v127", "v128",
"v129", "v130", "v131", "v132", "v133", "v134", "v135", "v136",
"v137", "v138", "v139", "v140", "v141", "v142", "v143", "v144",
"v145", "v146", "v147", "v148", "v149", "v150", "v151", "v152",
"v153", "v154", "v155", "v156", "v157", "v158", "v159", "v160",
"v161", "v162", "v163", "v164", "v165", "v166", "v167", "v168",
"v169", "v170", "