请在2024 Clojure调查问卷!中分享您的想法。

欢迎!请参阅关于页面以获取更多有关它是如何工作的信息。

0
编译器

最小示例,使用 1.9.0-alpha11

`
user=> (set! warn-on-reflection true)
true
user=> (defn foo ^String [^long x] "")

'user/foo

user=> (.length (foo 10))
反射警告,(...)- 无法解析对java.lang.Object的length字段的引用。
0
`

只有当禁用直接链接时,才会出现该警告。

解释
这是 CLJ-1533 的另一种表现-由于编译器在通过 invokePrim 路由调用时执行的词法转换,arglists 类型提示丢失了。当启用 DL 时不会发生此情况,因为 invokeStatic 不是通过词法转换编译的,而是通过 StaticInvokeExpr 编译的,它正确地跟踪了原始 var 的类型提示。

补丁: 0001-CLJ-2005-assoc-arglist-ret-tag-as-tag-in-constructed.patch

3 个答案

0
by

评论者:bronsa

启用 DL 时
public static java.lang.Object invokeStatic();  descriptor: ()Ljava/lang/Object;    flags: ACC_PUBLIC, ACC_STATIC    Code:      stack=2, locals=0, args_size=0         0: ldc2_w        #12                 // long 10l         3: invokestatic  #18                 // Method test$foo.invokeStatic:(J)Ljava/lang/Object;         6: checkcast     #20                 // class java/lang/String         9: invokevirtual #24                 // Method java/lang/String.length:()I        12: invokestatic  #30                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;        15: areturn      LineNumberTable:        line 5: 0        line 5: 9

禁用 DL 时

公共静态的 java.lang.Object invokeStatic();    描述符: ()Ljava/lang/Object;    标志: ACC_PUBLIC, ACC_STATIC    代码:      栈帧=3,局部变量数=0,参数长度=0         0: getstatic     #15                 // 字段 const__0:Lclojure/lang/Var;         3: invokevirtual #20                 // 方法 clojure/lang/Var.getRawRoot:()Ljava/lang/Object;         6: checkcast     #22                 // 类 clojure/lang/IFn$LO         9: ldc2_w        #23                 // long 10l        12: invokeinterface #28,  3           // 接口方法 clojure/lang/IFn$LO.invokePrim:(J)Ljava/lang/Object;        17: ldc           #30                 // 字符串 length        19: iconst_0        20: invokestatic  #36                 // 方法 clojure/lang/Reflector.invokeNoArgInstanceMember:(Ljava/lang/Object;Ljava/lang/String;Z)Ljava/lang/Object;        23: areturn      行号表:        line 5: 0        line 5: 12        line 5: 17

0
by

评论者:bronsa

启用DL偏移和当前补丁的字节码

`

public static java.lang.Object invokeStatic();

descriptor: ()Ljava/lang/Object;
flags: ACC_PUBLIC, ACC_STATIC
Code:
  stack=3, locals=0, args_size=0
     0: getstatic     #15                 // Field const__0:Lclojure/lang/Var;
     3: invokevirtual #20                 // Method clojure/lang/Var.getRawRoot:()Ljava/lang/Object;
     6: checkcast     #22                 // class clojure/lang/IFn$LO
     9: ldc2_w        #23                 // long 10l
    12: invokeinterface #28,  3           // InterfaceMethod clojure/lang/IFn$LO.invokePrim:(J)Ljava/lang/Object;
    17: checkcast     #30                 // class java/lang/String
    20: invokevirtual #34                 // Method java/lang/String.length:()I
    23: invokestatic  #40                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
    26: areturn
  LineNumberTable:
    line 5: 0
    line 5: 12
    line 5: 20

`

0
by
参考:https://clojure.atlassian.net/browse/CLJ-2005(由 moxaj 报告)
...