Squeak Smalltalk中withArgs:executeMethod:方法作用及入参咨询
withArgs: executeMethod: 核心功能与作用 这是Squeak Smalltalk由虚拟机直接支撑的底层反射原语,核心作用是跳过常规消息发送的查找、拦截流程,直接让当前消息接收者执行你指定的已编译方法对象,同时完成参数和方法形参的绑定。
它和常见的perform:系列方法的核心区别是:perform:仍然会走完整的消息查找链路(从接收者类的方法字典开始向上遍历找方法、触发doesNotUnderstand:逻辑、执行代理/方法包装的拦截逻辑),但withArgs:executeMethod:会直接把指定方法压入当前执行栈运行,不会做额外的查找步骤。
这个方法基本不会出现在普通业务代码里,大多用在框架层、调试工具的实现场景:比如Squeak调试器的单步执行、AOP方法拦截的原方法调用、Mock对象的行为模拟、Block闭包的底层求值、异常栈回溯生成这些场景。
合法传入参数要求
这个方法的选择子带两个参数,两个参数的合法性要求非常严格,不符合要求会直接触发原语失败,甚至导致镜像崩溃:
- 第一个参数(对应
withArgs:入参位):必须是Array类型的实例,数组长度、元素顺序必须和待执行方法的形参列表完全匹配:- 如果待执行的是无参数方法,这里必须传入空数组
#(),不能传nil - 如果待执行方法有n个位置形参,数组长度必须严格等于n,多一个少一个都会报错
- 不要传入
OrderedCollection等其他集合类型,虚拟机原语只识别Array实例
- 如果待执行的是无参数方法,这里必须传入空数组
- 第二个参数(对应
executeMethod:入参位):必须是合法的、未失效的CompiledMethod(编译后方法对象)实例,同时要求该方法的定义类和当前接收者的类型兼容——简单说就是你不能拿一个属于Integer类的方法,要求String类的实例去执行,否则会出现内存访问错误。一般建议直接从目标类的方法字典中取对应方法对象,不要手动构造CompiledMethod实例传入。
提示:这是非常底层的VM接口,没有常规消息发送的安全校验逻辑,除非你明确知道自己在做什么,否则不要随意调用。
内容的提问来源于stack exchange,提问作者moran
相关产品推荐
相关产品推荐

