作者:手机用户2602933165 | 来源:互联网 | 2023-05-24 18:58
问题如下; Java代码中的方法是:
Rule foo()
{
return sequence(foo(), x());
}
这将引发解析循环,当然应该避免; 但是,这是合法的:
Rule foo()
{
return sequence(x(), foo());
}
现在,代码中的其他地方我可以访问a RuleMethod
,这是一个扩展的类MethodNode
,因此我可以访问以下信息:
ruleMethod.name
:foo
; (定义于MethodNode
)
ruleMethod.desc
:( ()Lorg/parboiled/Rule;
定义于MethodNode
)
ruleMethod.ownerClass
:( com.github.fge.grappa.experiments.SelfReferringRule.MyParser
定义于RuleMethod
上面第一个代码提取的字节码如下:
Method 'foo':
0 L0
1 ALOAD 0
2 ALOAD 0
3 INVOKEVIRTUAL com/github/fge/grappa/experiments/SelfReferringRule$MyParser.foo ()Lorg/parboiled/Rule;
4 ALOAD 0
5 INVOKEVIRTUAL com/github/fge/grappa/experiments/SelfReferringRule$MyParser.x ()Lorg/parboiled/Rule;
6 ICONST_0
7 ANEWARRAY java/lang/Object
8 INVOKEVIRTUAL com/github/fge/grappa/experiments/SelfReferringRule$MyParser.sequence (Ljava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;)Lorg/parboiled/Rule;
9 ARETURN
10 L1
这意味着我必须提供给我的每一个信息,能够发现,至少在上面的字节码,这foo()
是第一个参数的的sequence()
调用,因为构造函数接受三个参数,并有在堆栈上三个要素.
但当然我不能在运行时"眼睛检查".因此我需要一种方法来做到这一点......
看起来我需要的是a MethodVisitor
和some visitInsn()
,然后看看有什么参数并适当检测......
但我没有任何想法从哪里开始; 在网上搜索似乎只是举例说明如何修改字节码,而不是检测这种情况:/
我从哪里开始?