Per issue 3455, split up very long var lines to avoid a bug in
the beta version of Safari 4.
This also adds a CompilerParameters module. It looks useful for testing to be
able to tune way down compiler settings such as this one.
Review by: jgw
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@5459 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/CompilePerms.java b/dev/core/src/com/google/gwt/dev/CompilePerms.java
index abf1646..e3bd98d 100644
--- a/dev/core/src/com/google/gwt/dev/CompilePerms.java
+++ b/dev/core/src/com/google/gwt/dev/CompilePerms.java
@@ -184,7 +184,8 @@
Permutation permutation, UnifiedAst unifiedAst)
throws UnableToCompleteException {
return JavaToJavaScriptCompiler.compilePermutation(logger, unifiedAst,
- permutation.getRebindAnswers(), permutation.getId());
+ permutation.getRebindAnswers(), permutation.getPropertyOracles(),
+ permutation.getId());
}
/**
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
index 4f60974..7b0de33 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -15,6 +15,7 @@
*/
package com.google.gwt.dev.jjs;
+import com.google.gwt.core.ext.PropertyOracle;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.linker.ArtifactSet;
@@ -81,6 +82,7 @@
import com.google.gwt.dev.jjs.impl.TypeMap;
import com.google.gwt.dev.jjs.impl.TypeTightener;
import com.google.gwt.dev.js.EvalFunctionsAtTopScope;
+import com.google.gwt.dev.js.JsBreakUpLargeVarStatements;
import com.google.gwt.dev.js.JsIEBlockSizeVisitor;
import com.google.gwt.dev.js.JsInliner;
import com.google.gwt.dev.js.JsNormalizer;
@@ -173,13 +175,14 @@
* {@link #precompile(TreeLogger, WebModeCompilerFrontEnd, String[], JJSOptions, boolean)}
* @param rebindAnswers the set of rebind answers to resolve all outstanding
* rebind decisions
+ * @param propertyOracles All property oracles corresponding to this permutation.
* @return the output JavaScript
* @throws UnableToCompleteException if an error other than
* {@link OutOfMemoryError} occurs
*/
public static PermutationResult compilePermutation(TreeLogger logger,
UnifiedAst unifiedAst, Map<String, String> rebindAnswers,
- int permutationId) throws UnableToCompleteException {
+ PropertyOracle[] propertyOracles, int permutationId) throws UnableToCompleteException {
try {
if (JProgram.isTracingEnabled()) {
System.out.println("------------------------------------------------------------");
@@ -292,6 +295,8 @@
// http://code.google.com/p/google-web-toolkit/issues/detail?id=1440
JsIEBlockSizeVisitor.exec(jsProgram);
+ JsBreakUpLargeVarStatements.exec(jsProgram, propertyOracles);
+
// (12) Generate the final output text.
String[] js = new String[jsProgram.getFragmentCount()];
List<Map<Range, SourceInfo>> sourceInfoMaps = options.isSoycEnabled()
diff --git a/dev/core/src/com/google/gwt/dev/js/JsBreakUpLargeVarStatements.java b/dev/core/src/com/google/gwt/dev/js/JsBreakUpLargeVarStatements.java
new file mode 100644
index 0000000..39b4132
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/js/JsBreakUpLargeVarStatements.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.js;
+
+import com.google.gwt.core.ext.BadPropertyValueException;
+import com.google.gwt.core.ext.ConfigurationProperty;
+import com.google.gwt.core.ext.PropertyOracle;
+import com.google.gwt.dev.jjs.InternalCompilerException;
+import com.google.gwt.dev.js.ast.JsContext;
+import com.google.gwt.dev.js.ast.JsModVisitor;
+import com.google.gwt.dev.js.ast.JsProgram;
+import com.google.gwt.dev.js.ast.JsStatement;
+import com.google.gwt.dev.js.ast.JsVars;
+import com.google.gwt.dev.js.ast.JsVars.JsVar;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Divides large var statements into smaller ones. Very long var statements have
+ * trouble on some browsers, including the initial Safari 4 beta. See Issue
+ * 3455.
+ */
+public class JsBreakUpLargeVarStatements extends JsModVisitor {
+ private static final String CONFIG_PROP_MAX_VARS = "compiler.max.vars.per.var";
+
+ public static void exec(JsProgram program, PropertyOracle[] propertyOracles) {
+ (new JsBreakUpLargeVarStatements(propertyOracles)).accept(program);
+ }
+
+ private static JsVars last(List<JsVars> list) {
+ return list.get(list.size() - 1);
+ }
+
+ private final int maxVarsPerStatement;
+
+ private JsBreakUpLargeVarStatements(PropertyOracle[] propertyOracles) {
+ maxVarsPerStatement = getMaxVarsPerStatement(propertyOracles[0]);
+ }
+
+ @Override
+ public void endVisit(JsVars x, JsContext<JsStatement> context) {
+ if (maxVarsPerStatement < 0) {
+ return;
+ }
+
+ if (x.getNumVars() > maxVarsPerStatement) {
+ // compute a list of smaller JsVars statements
+ List<JsVars> smallerVars = new ArrayList<JsVars>();
+ smallerVars.add(makeNewChildVars(x));
+
+ for (JsVar var : x) {
+ if (last(smallerVars).getNumVars() >= maxVarsPerStatement) {
+ // Previous statement is full; start a new one
+ smallerVars.add(makeNewChildVars(x));
+ }
+ last(smallerVars).add(var);
+ }
+
+ // replace x by the sequence smallerVars
+ for (JsVars sv : smallerVars) {
+ context.insertBefore(sv);
+ }
+ context.removeMe();
+ }
+ }
+
+ /**
+ * Look up in the specified property oracle the maximum number of variables to
+ * allow per var statement.
+ */
+ private int getMaxVarsPerStatement(PropertyOracle propertyOracle)
+ throws InternalCompilerException, NumberFormatException {
+ ConfigurationProperty prop;
+ try {
+ prop = propertyOracle.getConfigurationProperty(CONFIG_PROP_MAX_VARS);
+ } catch (BadPropertyValueException e) {
+ throw new InternalCompilerException("Could not find property "
+ + CONFIG_PROP_MAX_VARS, e);
+ }
+ int t = Integer.parseInt(prop.getValues().get(0));
+ return t;
+ }
+
+ /**
+ * Make a new, empty {@link JsVars} that is a child of x.
+ */
+ private JsVars makeNewChildVars(JsVars x) {
+ return new JsVars(x.getSourceInfo().makeChild(
+ JsBreakUpLargeVarStatements.class,
+ "breaking up a large vars statement into smaller ones"));
+ }
+}
diff --git a/user/src/com/google/gwt/core/CompilerParameters.gwt.xml b/user/src/com/google/gwt/core/CompilerParameters.gwt.xml
new file mode 100644
index 0000000..44cde7e
--- /dev/null
+++ b/user/src/com/google/gwt/core/CompilerParameters.gwt.xml
@@ -0,0 +1,26 @@
+<!-- -->
+<!-- Copyright 2009 Google Inc. -->
+<!-- Licensed under the Apache License, Version 2.0 (the "License"); you -->
+<!-- may not use this file except in compliance with the License. You may -->
+<!-- may obtain a copy of the License at -->
+<!-- -->
+<!-- http://www.apache.org/licenses/LICENSE-2.0 -->
+<!-- -->
+<!-- Unless required by applicable law or agreed to in writing, software -->
+<!-- distributed under the License is distributed on an "AS IS" BASIS, -->
+<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -->
+<!-- implied. License for the specific language governing permissions and -->
+<!-- limitations under the License. -->
+
+<!-- Compiler parameters that can be overridden for test cases . -->
+<!-- -->
+<module>
+ <!--
+ This is the maximum number of variables in any var statement GWT
+ will emit. This avoids a bug in some browsers including
+ the initial beta of Safari 4. See Issue 3455. If it is set to -1,
+ then there is no limit.
+ -->
+ <define-configuration-property name='compiler.max.vars.per.var' is-multi-valued='false' />
+ <set-configuration-property name='compiler.max.vars.per.var' value='2400' />
+</module>
diff --git a/user/src/com/google/gwt/core/Core.gwt.xml b/user/src/com/google/gwt/core/Core.gwt.xml
index ad0a148..9f35631 100644
--- a/user/src/com/google/gwt/core/Core.gwt.xml
+++ b/user/src/com/google/gwt/core/Core.gwt.xml
@@ -21,16 +21,17 @@
<inherits name="com.google.gwt.dev.jjs.intrinsic.Intrinsic" />
<inherits name="com.google.gwt.emul.Emulation" />
<inherits name="com.google.gwt.xhr.XMLHttpRequest" />
+ <inherits name="com.google.gwt.core.CompilerParameters" />
<define-linker name="sso" class="com.google.gwt.core.linker.SingleScriptLinker" />
<define-linker name="std" class="com.google.gwt.core.linker.IFrameLinker" />
- <define-linker name="xs" class="com.google.gwt.core.linker.XSLinker" />
-
- <define-linker name="soycReport" class="com.google.gwt.core.linker.SoycReportLinker" />
- <define-linker name="symbolMaps" class="com.google.gwt.core.linker.SymbolMapsLinker" />
+ <define-linker name="xs" class="com.google.gwt.core.linker.XSLinker" />
+
+ <define-linker name="soycReport" class="com.google.gwt.core.linker.SoycReportLinker" />
+ <define-linker name="symbolMaps" class="com.google.gwt.core.linker.SymbolMapsLinker" />
<add-linker name="std" />
-
- <add-linker name="soycReport" />
- <add-linker name="symbolMaps" />
+
+ <add-linker name="soycReport" />
+ <add-linker name="symbolMaps" />
</module>
diff --git a/user/test/com/google/gwt/emultest/EmulSuite.gwt.xml b/user/test/com/google/gwt/emultest/EmulSuite.gwt.xml
index 2de2c30..e1de729 100644
--- a/user/test/com/google/gwt/emultest/EmulSuite.gwt.xml
+++ b/user/test/com/google/gwt/emultest/EmulSuite.gwt.xml
@@ -13,7 +13,13 @@
<!-- limitations under the License. -->
<module>
- <inherits name='com.google.gwt.junit.JUnit'/>
- <inherits name='org.apache.commons.Collections'/>
- <source path='java'/>
+ <inherits name='com.google.gwt.junit.JUnit' />
+ <inherits name='org.apache.commons.Collections' />
+ <source path='java' />
+
+ <!--
+ Specify some tighter compiler settings so that those compiler paths
+ are tested by the normal GWT regression suite
+ -->
+ <set-configuration-property name='compiler.max.vars.per.var' value='10' />
</module>