
google-web-toolkit - issue #3455
GWT 1.5 & 1.6 produces lines that are too long for WebKit browser when hosted in Adobe Air Runtime
Found in GWT Release: 1.5.3, 1.6.1
Detailed description: I'm building a GWT app that is running under the Adobe Air runtime. Air has a WebKit browser build in. At runtime I get an exception, which originates from WebKit: 'Syntax Error: Expression Too Deep'. After a few hours of research, I've found that it is caused by the line of Javascript which GWT generates to internalize strings; I believe this is the first line of the javascript: something like this. <script><!-- var $intern_3 = '', $intern_279 = '\n', ..... etc...
The problem is that the line is too long; in my case it's just over 32k (in DETAILED mode). I also get the problem when in OBFUSCATED mode, where the same line is about 20k long; maybe it's todo with the number of variables being declared rather than the length of the line.
Workaround if you have one: The workaround requires me to manually edit the javascript produced by gwt, so that this line is split across multiple lines. Obviously this is quite inconvenient.
Links to the relevant GWT Developer Forum posts:
Comment #1
Posted on Mar 6, 2009 by Swift DogI've found that the issue can be workaround by compiling in PRETTY mode, which will do me fine for now.
Comment #2
Posted on Mar 6, 2009 by Grumpy HorseThis issue seems to have more to do with the Adobe Air Runtime rather than the JS produced by the GWT compiler (both Chrome and Safari work fine with GWT generated JS in both OBFUSCATED and DETAILED mode).
I suggest filing this at the link below: http://adobe.com/go/wish
Comment #3
Posted on Mar 7, 2009 by Swift RhinoSame here, same workaround (compile in -style PRETTY).
I don't know however if it's because of WebKit or the JS engine, as it appears only in AIR 1.5 and 1.5.1, which has switched to using Squirrelfish instead of Tamarin. And as a side note, Safari 4 is OK with the JS generated by GWT (AFAIK) because it doesn't use Squirrelfish but Nitro (previously known as Squirrelfish Extreme).
I didn't think it could be a "statement length" issue though...
Comment #4
Posted on Mar 7, 2009 by Swift DogThanks, I will report it to Adobe as an issue. However, I'm guessing the likelihood and ease of getting this modified in GWT is much greater than any fix in the Air browser. I'm also guessing that it would be fairly trivial to put some additional checks in the GWT compiler to prevent an excessive number of variable decls on the same line. My code stops working when about 1045 variables appear on the same line;
I'm really hopeful this can be fixed in GWT: The app I'm writing is a desktop client for Twitter, and as I'm a big fan of GWT I'd love to be able to complete the project using GWT, and preferably with the code obfuscated. Otherwise I shall probably rewrite from scratch using Flex or something.... Thanks,
Comment #5
Posted on Mar 9, 2009 by Swift DogI noticed that this issue seems to be closed, without any resolution. I'm disappointed. Is there a way to get this re-opened or reviewed by a Project Owner? It really makes no sense to me that the GWT would want to limit its compatibility with other browsers when fixing this problem is, I expect, a relatively minor undertaking.... Thanks.
Comment #6
Posted on Mar 9, 2009 by Grumpy HorseAs per the latest comments, I'm re-opening for investigation. Sorry for the couple days of inactivity on the issue, it hadn't been actioned on since last comments because I just now got a chance to take another look at it.
I'm not sure that this is a trivial fix, and it would probably involve a bunch of special casing in the GWT compilation process. It also seems like this is outside the scope of the browsers GWT supports. But if this issue is actually caused by the JS engine used (e.g. SquirrelFish versus Tamarin), then this might be worth investigating down to a fix.
Comment #7
Posted on Mar 9, 2009 by Grumpy DogShould consider for a 1.6 update.
Comment #8
Posted on Mar 9, 2009 by Swift Dogbrilliant! Thank you :)
Comment #9
Posted on Mar 13, 2009 by Happy KangarooI am also running into this issue with the AIR 1.5 runtime. Initially I was able to work around it with a PRETTY compile. The project has a large number of classes and after adding some new classes yesterday it's now failing with the same "Expression too deep" error near the end of the generated HTML file. It's a single line generated by the GWT compiler that declares a bunch of class literal vars by stringing the declarations together with commas. I am currently working around it by doing a string replace on the line to make them individual var declarations separated with semicolons (still on the same line though).
I found where it generates the error in the public WebKit source and it seems that the JavaScript byte code generator has a hard coded limit of 10000 nodes while it's processing a single statement. So it's not really the length of the line that's the issue but the amount of internal byte code that a single statement generates.
Comment #10
Posted on Mar 13, 2009 by Happy KangarooJust as a temporary / quick fix I changed visit(JsVars x, JsContext ctx) in JsToStringGenerationVisitor to limit the max number of variables declared in a single statement to 100 and that seems to resolve the problem. Not a complete fix because you wouldn't want to break up the var statement inside of a for statement for example. There's probably other places it might cause an issue as well, not sure. Maybe it gives some insight on what a real fix might be though.
Comment #11
Posted on Apr 18, 2009 by Swift BearI'm getting this error now using Safari 4 Beta in our app at http://www.clarityaccounting.com ... Launch the demo in Safari 4 Beta and you'll see what I mean (tested in Window Safari 4 Beta 528.16)
Strangely, this cropped up recently when I upgraded to GWT 1.6.4. Previously with 1.5.3 I didn't have this problem. I'm not sure if this is directly caused by GWT 1.6.4 or if I simultaneous crossed some threshold, but our Safari early adopters are having problems.
Using PRETTY might be an option, but doesn't that hurt performance a lot? I wouldn't want to hurt everyone else's performance to support the few Safari 4 users ... so I'm hoping there's a better workaround.
Comment #12
Posted on Apr 21, 2009 by Grumpy HorseIf anyone on this issue report could boil this down to a reproducible code snippet, that would be a great help in working out a fix.
Comment #13
Posted on Apr 22, 2009 by Massive ElephantI saw this once on an internal application, but then it seemed to magically go away, so I've not been able to reproduce it again recently.
Looks like we were stepping across a threshold in the new JSCore bytecode compiler. The specific error I saw was "Syntax Error: Expression Too Deep", as someone else mentioned earlier. It appears to happen whenever we cross an expression-length threshold in JSCore. A quick codesearch (I love codesearch) yields some context (see the following url):
RegisterID* emitNode(RegisterID* dst, Node* n)
{
// Node::emitCode assumes that dst, if provided, is either a local or a
referenced temporary. ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount()); if (!m_codeBlock->lineInfo.size() || m_codeBlock->lineInfo.last().lineNumber != n->lineNo()) { LineInfo info = { instructions().size(), n->lineNo() }; m_codeBlock->lineInfo.append(info); } if (m_emitNodeDepth >= s_maxEmitNodeDepth) return emitThrowExpressionTooDeepException(); ++m_emitNodeDepth; RegisterID* r = n->emitCode(*this, dst); --m_emitNodeDepth; return r; }
Note that it's the "return emitThrowExpressionTooDeepException();" that's the source of our troubles.
Comment #14
Posted on Apr 25, 2009 by Swift BearDo you think that if I found some long lines and put a few newlines in there it would fix the problem? If so I could use this as a workaround until someone fixes it more permanently somewhere.
Comment #15
Posted on Apr 25, 2009 by Massive ElephantFrom what I noticed, it appeared that it wasn't long lines per se, but extremely large expressions. I've seen two expressions trigger this: 1. The constant variable list near the top of the compiled output. 2. The list of class literal declarations at the bottom.
Try breaking these up into multiple var decls, as in: var a, b, c, d; => var a, b; var c, d;
Comment #16
Posted on Apr 25, 2009 by Swift RhinoI believe it has nothing to do with line length (so CR/LF won't help) but with "statement length".
As a side note, it will probably affect Android Cupcake too, now that it uses SquirrelFish.
(I think I didn't originally notice the issue with Safari 4 because my AIR build has some specific features --using GWT-in-the-AIR with File.browse, File.upload and DropPanel--, so I'll try to make a test case based on those differences)
Comment #17
Posted on Apr 25, 2009 by Swift BearYes, breaking that initial string table up into separate var lines did the trick.
Now, how I can get this going so that I don't have to manually edit that file for
Safari before it will work?
For what it's worth, this sed script can be helpful to fix it:
cp 727DBFA7240E60B076A0A328EBA280FE.cache.html 727DBFA7240E60B076A0A328EBA280FE.cache.html.bak
sed "s/',([A-Za-z0-9]+)='/';var \1='/g" < 727DBFA7240E60B076A0A328EBA280FE.cache.html.bak > 727DBFA7240E60B076A0A328EBA280FE.cache.html.fix
Comment #18
Posted on Apr 27, 2009 by Grumpy Dog(No comment was entered for this change.)
Comment #19
Posted on May 12, 2009 by Grumpy Bird(No comment was entered for this change.)
Comment #20
Posted on May 19, 2009 by Grumpy BirdNice digging, Joel! Looking at the nodes data structure in a nearby file to the one you point to, it looks like a vars statement is encoded in a way such that the depth of the AST is roughly twice the number of variables in the statement. Looking at the line you point to, the limit on the depth is 10,000 nodes. As a result, any vars statement with more than about 5,000 nodes is going to trigger this limit. We have verified this by generating some test files and then loading them into Safari 4; right at 5000 variables the error message starts appearing.
A simple way to fix this would be to have a JsVisitor go through and break up any super-long vars lines so that they have a maximum of, say, 4900 variables in each one. Since only ~6 characters are added per breakup, it is probably worth enabling this by default and not bothering to enable it only for Safari.
Comment #21
Posted on May 21, 2009 by Grumpy BirdA vars-splitting fix is committed at r5459.
One of the review comments notes that this could still bite us in other contexts than long vars lines. If that's an issue in practice, e.g. with very long chains of + operations on strings, then we might need to implement a more general solution.
Comment #22
Posted on Jun 9, 2009 by Helpful HippoWe just got bit by this yesterday with the official release of Safari 4 (the Safari 4 Beta worked fine). This is a huge issue for us as we are pretty much dead in the water with respect to Safari users. Is there any chance of getting a 1.5.4 patch release containing this fix?
Thanks!
Comment #23
Posted on Jun 9, 2009 by Quick ElephantComment deleted
Comment #24
Posted on Jun 9, 2009 by Quick ElephantOur project also stopped working with official Safari 4. We're on GWT 1.6.4.
Comment #25
Posted on Jun 9, 2009 by Massive ElephantWe're currently working on a 1.6 update that will deal with this and full IE8 support as well. We'll post on the public fora as soon as it's ready ("real soon now").
Comment #26
Posted on Jun 9, 2009 by Helpful HippoWe would love to upgrade to 1.6. Unfortunately there are some breaking changes for us (specifically the new HasValue interface collides with some of our own databinding methods) and the the new project structure requires us to re-do our build scripts. So the upgrade is not trivial, unfortunately. I am sure this is the case for other users as well. Is there any chance to get an update to 1.5?
Comment #27
Posted on Jun 9, 2009 by Happy KangarooRegarding your build scripts, you can continue to use the GWTCompiler and GWTShell entry points rather than the new ones added in 1.6 (though they may go away in 2.0).
Comment #28
Posted on Jun 10, 2009 by Quick GiraffeDon't mean to reiterate the other comments, but our project also stopped with the new release of Safari 4. It worked fine with Safari 4 Beta. We're running 1.5.3 about to update to 1.6.4.
Comment #29
Posted on Jun 13, 2009 by Swift BearHere's a workflow that I'm using now:
- Compile in PRETTY
- grep 'safari' *.nocache.js
- Copy the indicated *.cache.html file(s) to a safe location
- Compile in OBFUSCATED
- Open the app in Safari 4 to figure out which *.cache.html file(s) it is using
- Copy the PRETTY files I previously copied away over those files
- Feel glad I worked around the issue, but wish fervently for the next release of GWT to come as soon as possible.
Comment #30
Posted on Jun 15, 2009 by Quick GiraffeJust finished implementing the above workaround and it works fine (thanks!) except in one case. If I ever tried to refresh a page in Safari, the entire browser crashed. It could be something in my code, but I have never had this problem before. Anyone else with this problem?
Comment #31
Posted on Jun 19, 2009 by Helpful Hippoping! Any updates on this issue from the GWT folk? thanks..
Comment #32
Posted on Jun 19, 2009 by Swift RhinoYou mean, apart from being already fixed on the SVN?
Comment #33
Posted on Jun 19, 2009 by Helpful Hippoi guess i mean the update to 1.6 that includes this fix.
Comment #34
Posted on Jun 21, 2009 by Happy ElephantHi Joel & Bruce & ??? What are you waiting for to release an 1.6.5 update ? Our application (and many other large scale applications) aren't working anymore under Safari 4 (I know, it's fundamentally a Safari issue...). Workarounds are not realistic with a large number of i18n permutations.
Thanks,
Luc
Comment #35
Posted on Jul 8, 2009 by Helpful HippoStill waiting for fix to be released...
Comment #36
Posted on Jul 26, 2009 by Helpful MonkeyWith the 1.7 release, my GWT project runs under Safari 4, but still does not work with Adobe AIR 1.5.1. The status says this fix has not yet been released, although it was submitted well before 1.7 was released. Not sure now if it'll ever work on AIR 1.5!
Comment #37
Posted on Jul 27, 2009 by Massive Elephant@alxdark: Are you getting the exact same error, or could it be failing on Air for other reasons? Air is not part of our normal test suite (it's already quite large), so it's not inconceivable that something else could have slipped by, especially if they've done anything strange to their WebKit build.
We know that we fixed the too-long-line issue that relates to the later WebKit version (it's the Javascript VM, to be precise). To see if this actually is the problem you're experiencing, try adding this configuration property to your module:
The default's 2400, which is well under the limit in the Nitro Javascript engine, but perhaps Adobe configured it differently. If this doesn't fix the problem, then it's most likely an unrelated issue.
Comment #38
Posted on Jul 27, 2009 by Helpful Monkey@jgw: I'll try this and report back. I believe it is the same issue because the error message is the same at runtime: 'Syntax Error: Expression Too Deep'.
Comment #39
Posted on Jul 28, 2009 by Helpful MonkeyThe 'compiler.max.vars.per.var' property fixes the build on AIR 1.5.1, thanks so much for your help! For those who have a similar issue, the largest value I was able to use for this (assuming that longer lines are better) was 995.
Comment #40
Posted on Jul 29, 2009 by Swift Elephant(No comment was entered for this change.)
Comment #41
Posted on Nov 15, 2009 by Helpful Lion(No comment was entered for this change.)
Status: Fixed
Labels:
Category-Compiler
Type-Defect
Priority-High
Milestone-1_7