Log of the #nice channel on irc.freenode.net

Using timezone: Central European Time
* flospie joins01:00
* flospie leaves01:02
* arjanb leaves01:43
* zzorn joins07:53
* zzorn_away leaves08:22
* ChanServ leaves09:03
* ChanServ joins09:14
* byron leaves12:31
* arjanb joins12:40
* arjanb leaves15:25
* Gummi_log leaves15:27
* arjanb joins16:38
* zzorn joins18:56
* zzorn leaves19:55
* ArtemGr joins23:09
<arjanb>hi23:11
<ArtemGr>Hi : )23:12
<arjanb>seems i forgot to comment on the bug report
<ArtemGr>Nevermind.23:13
<arjanb>the problem is with the codegeneration of 'assert false'
nicec knows it never returns but the bytecode verifier can't know that from the generated bytecode23:15
a simple workaround in this case is to use throw someException23:17
your bug report is very extensive :)23:27
compiled classes aren't needed most of the time
<ArtemGr>That I was thinking to ask about separately. In what assertion guides I've seen it is recommended to mark the code that should not be reached with "assert false". (For example, see http://java.sun.com/j2se/1.4.2/docs/guide/lang/assert.html "Control-Flow Invariants")23:29
I am using this approach too, but in Java I try to provide a sound "backup" logic even for those "unreachable" code branches. Thus, when assertions are disabled and the "unreachable" code gets reached, the program still works. Java compiler and Eclipse build-in compiler both seem understand this notion, allowing me to have a code after an "assert false". But the Nice compiler will report an "unrea
chable code" error when there is a code after the "assert false". BTW, it even seems to me not logical to treat the code after an "assert false" as unreachable, since it is practically "if( class.assertionsEnables ) throw new AssertionError;" and not just "throw new AssertionError"... ?
<arjanb>i'm now changing the codegeneration of 'assert false' to 'throw new AssertionError' as a workaround23:33
whether code after an assert false is reachable or not needs to be reconsidered if java has different behaviour23:35
though i tend to view assertions as always enabled because disabling makes only sense for optimalization23:38
<ArtemGr>The program with assertions is safer, but at the cost of 24x7 functionality. When programming defensively, assertion "contracts" are not always true. The very point in assertions (to me) is that "it should be so, but I don't know if it will be so". The point is that the program should NOT work when testing it, so that I forced to fix things, but that the program SHOULD work when deploying it, so t23:48
hat my clients aren't forced to wait for the fixes (or loose data and money from unexpected error).
I should have said: When programming defensively, but still doing a lot of refactoring in the existing code, assertion "contracts" are not always true.23:52
<arjanb>i understand23:55
* ArtemGr leaves23:58
* ArtemGr joins23:59
* ArtemGr leaves00:00
<CIA-3>03arjanb * 10Nice/stdlib/nice/lang/inline/Assert.java: Workaround for bug #111326300:02
* ArtemGr joins00:05
<arjanb>i will point Daniel to this issue00:10
i hope this isn't blocking you00:11
<ArtemGr>I've just received your follow-up on the bug report from sourceforge. : )00:12
BTW, how is that "assert false" doesn't produce the VerifyError when replacing "let (TreeNode,Composite)->void obtainIndex;" with "var (TreeNode,Composite)?->void obtainIndex = null;"?00:14
<arjanb>it haven't found out that yet00:19
<ArtemGr>It isn't blocking me in any way, since I've applied the workaround mentioned when I found it, and, BTW, I've redesigned the code already, and as a side effect it is cleaner and doesn't trigger the bug.
<arjanb>that VerifyError seems a corner case since i couldn't create a testcase without deriving from yours00:21
<ArtemGr>I have an idea why verification fails, although it is just a wild guess, I've no experience or knowledge in verification.00:52
Should I share it (the idea)?00:53
<arjanb>why not? :)00:54
<ArtemGr>I'm checking my assumptions with the book I have: "Programming for the Java? Virtual Machine" By Joshua Engel.01:10
There is the following statement (in "Other Safety Requirements"): When invoking a method, or setting or getting a field, the receiver reference must not be null (checked by the invokespecial, invokevirtual, invokeinterface, getfield, and putfield instructions).
Java verification doesn't like the variable "5"...01:11
And on the offset "113" of the "bad" bytecode we have:01:12
113: aload 5
115: aload 9
117: aload 10
119: invokevirtual #113; //Method gnu/mapping/Procedure.apply2:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
Thus, "5" is the "reference" for "invokevirtual", which according to the statement above should be guaranteed not to be null.01:13
Now:
Nice thinks, that "assert false" is the end of the code.01:14
But it is not represented in the bytecode. In the bytecode there is a
64: getstatic #51; //Field $assertionsEnabled:Z
67: ifeq 82
70: iconst_0
71: ifne 82
<arjanb>i see and variable 5 can be null when going through the if branch with 'assert false'01:15
<ArtemGr>Therefore, variable "5" might indeed be null without it being cheched.01:16
Yes.
I'll even try to prove it empirically.01:26
<arjanb>it's clear to me now so no need for that01:40
<ArtemGr>Empirical corrections to the theory: : )
Bytecode verifier isn't concerned with null-ness, adding "if( null != obtainIndex )" before invocation doesn't remove the error.
What bytecode verifier seems to be concerned with is that variable used without being initialized.
var (TreeNode,Composite)->void obtainIndex; // error...
var (TreeNode,Composite)->void obtainIndex = cast( null ); // no error!
I've compared bytecodes with and without cast(null) initializer - they are absolutely the same with only
17: aconst_null
18: astore 5
introduced into the working one.
* zzorn joins01:51
* ArtemGr leaves02:15
* ArtemGr joins02:20
* zzorn leaves02:24
* ArtemGr leaves02:28
* ArtemGr joins02:35
* ArtemGr leaves02:37
* ArtemGr joins02:38
* arjanb leaves03:07