How to waste a weekend

I spent half of Friday tracking down a GWT problem that caused problems in both Opera and IE. By trial and error I kind of isolated it to my use of syntactic sugar (yeah, I know…) Then I spent most of Saturday trying to come up with a pithy reproducible case. Here it is
(posted to http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/ae307a25041f3a7e/, reproducing here for my own reference):

Consider the following source (made with -style pretty):

package x.y.z;

import com.google.gwt.core.client.*;
import com.google.gwt.user.client.ui.*;

public class WastedWeekend extends Label implements EntryPoint {
public void onModuleLoad() {
foo();
}

void foo() {
Button[] stuff = new Button[1];
doNothing(stuff[0] = new Button());
}

void doNothing(Widget w) {
RootPanel.get().add(w);
}

The foo() function translates into the following:


function _$foo(_this$static){
var _stuff;
_stuff = _initDims('[Lcom.google.gwt.user.client.ui.Button;', [0],
[5], [1], null);
_$doNothing(_this$static, _stuff[0] = _$Button(new _Button()));

}

This is all well and good. But now let me change, in foo() the type of “stuff” to Label
(that is, the superclass of WastedWeekend). That is, as follows:


void foo() {
Label[] stuff = new Label[1];
doNothing(stuff[0] = new Label());

}

Now the translation is:


functionfunction _$foo(_this$static){
var _stuff;
_stuff = _initDims('[Lcom.google.gwt.user.client.ui.Label;', [0],
[7], [1], null);
_$doNothing(_this$static, _setCheck(_stuff, 0, _$Label(new
_Label())));

}

Notice the difference? What’s going on?

This is reproducible whenever this sample WastedWeekend class is the same subclass of the same
Widget as the stuff variable.
(I did not go into more details as far as inheritance tree, so I don’t know what happens if they are siblings or something)…

Now, should I spend Sunday trying to actually figure this out?

4 thoughts on “How to waste a weekend

  1. My new motto is … “the compiler is NOT your friend”. From an OOP standpoint, your code should work in either case. It doesn’t appear to matter. I was going to say that you have interface compatible objects, but you actually don’t — you’re just not using the interface at all. So why try to fix a compiler type check for something that is being used in a typeless context? Since the compiler is hurting you, not helping, I would bypass it by using Object references. πŸ™‚ Not really: I’d just take apart the assignment and the function call first, but I do think it’s *valid* to demote the reference to a typeless one. The compiler cannot handle the typed reference for no good reason. Put in runtime checks, or type cast exception catches, and be done with it. Next problem; this one is not one you need to , nor should you have to solve.

    Like

    • I can work around it by not using the sugar of assignment as value passed into doNothin(). That works fine. I just want to know what’s going on here πŸ™‚

      Like

      • Yeah, I know. πŸ™‚ But when the compiler is misbehaving because of something to do with type checking, I have to laugh. “Just suck it up and compile my code!”. Spit out a warning if you must — but the fact remains that the bytecode to make the function call, or make the assignment, ought to be the same regardless as to whether the type check is correct or not. Types only matter when using their interfaces, (and in the absence of public member variables, only when calling their methods). Either the recipient of the function call is in the virtual function table or not, and if it’s not, it throws a runtime exception anyway. Now, I don’t know what setCheck actually does — but it should conceptually do one of two things : throw an exception, or pass data through. That’s what a runtime type check ought to be. If it’s doing a third thing, which is to mess up your code, then that’s bad on yet another count. Not only has the compiler built bytecode differently for a simple assignment, but it built bytecode that doesn’t work. So, no, I would say that you *Don’t* want to know what’s really going on. πŸ™‚

        Like

      • No, actually, I *DO* want to know πŸ™‚ See the newsgroup exchange; they confirmed it’s a bug, but I am curious as to why different translations…

        Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.