NutzCN Logo
问答 ClassMetaReader.build() 按变量声明顺序获取变量名的调整建议
发布于 6天前 作者 MingzFan 43 次浏览 复制 上一个帖子 下一个帖子
标签:

ClassMetaReader.build() 中获取变量名的那部分代码原本是按照本地变量表字节码的写入顺序获取变量名的,但由于在写入本地变量表的时候,形参与局部变量写入的顺序是不可控的,所以导致会导致后续按形参的下标获取对应的形参名称时会出现错乱,故建议按本地变量表的Slot属性升序排列。调整如下:

if ("LocalVariableTable".equals(codeAttrName)) {//形参在LocalVariableTable属性中
                            int local_variable_table_length = dis.readUnsignedShort();
                            //按本地变量表的Slot属性升序排列,保证形参名称的下标与所对应参数的下标一致
                            TreeMap<Integer, String> varSlotNameMap = new TreeMap<Integer, String>();
                            for (int l = 0; l < local_variable_table_length; l++) {
                                dis.skipBytes(2);
                                dis.skipBytes(2);
                                String varName = strs.get(dis.readUnsignedShort());
                                dis.skipBytes(2);
                                int varSlot = dis.readUnsignedShort();//这是变量的下标
                                if (!"this".equals(varName)) //非静态方法,第一个参数是this
                                    varSlotNameMap.put(varSlot, varName);//varNames.add(varName);
                            }

                            List<String> varNames = new ArrayList<String>(varSlotNameMap.values());
                            if (!names.containsKey(key))
                                names.put(key, varNames);
                        } 

另附上部分反编译后的字节码信息(局部变量在形参之前写入本地变量表):

public com.xxx.xxx.transport.Response saveContent(java.lang.String, com.xxx.xxx.nutz.entity.config.NutzContent, org.nutz.plugins.validation.Errors);
...
LocalVariableTable:
      Start  Length  Slot  Name   Signature
           114      55     9 definition   Lcom/xxx/xxx/entity/config/Definition;
            92      80     8    i$   Ljava/util/Iterator;
            58     126     5 definitions   Ljava/util/List;
            80     104     6 contentMap   Ljava/util/Map;
            83     101     7   msg   Ljava/lang/String;
             0     216     0  this   Lcom/xxx/xxx/nutz/module/ConfigModule;
             0     216     1  path   Ljava/lang/String;
             0     216     2 content   Lcom/xxx/xxx/nutz/entity/config/NutzContent;
             0     216     3 errors   Lorg/nutz/plugins/validation/Errors;
            30     186     4 response   Lcom/xxx/xxx/transport/Response;
4 回复

good, 发个pull req可以吗?

Git新手,我得研究下如下pull req,昨天尝试的时候发现失败了...

@wendal 兽总,请求一下IDEA里面如何pull request?

在github/码云上创建pull request的

添加回复
请先登陆
回到顶部