Guard against invalid dispIds in JavaDispatchImpl
Also, rather than write an invalid dispId and wait for things to blow up, throw
a HostedModeException if we hit a JSNI ref that shouldn't be there
Review at http://gwt-code-reviews.appspot.com/1172801
Review by: scottb@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9390 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/shell/JavaDispatchImpl.java b/dev/core/src/com/google/gwt/dev/shell/JavaDispatchImpl.java
index 2323597..9338a85 100644
--- a/dev/core/src/com/google/gwt/dev/shell/JavaDispatchImpl.java
+++ b/dev/core/src/com/google/gwt/dev/shell/JavaDispatchImpl.java
@@ -61,6 +61,9 @@
* @return the field
*/
public Field getField(int dispId) {
+ if (dispId < 0) {
+ throw new RuntimeException("Field does not exist.");
+ }
Member member = getMember(dispId);
if (member instanceof SyntheticClassMember) {
@@ -82,6 +85,10 @@
* @throws IllegalArgumentException
*/
public Object getFieldValue(int dispId) {
+ if (dispId < 0) {
+ throw new RuntimeException("Field does not exist.");
+ }
+
Member member = getMember(dispId);
if (member instanceof SyntheticClassMember) {
@@ -103,6 +110,10 @@
* @return the method
*/
public MethodAdaptor getMethod(int dispId) {
+ if (dispId < 0) {
+ throw new RuntimeException("Method does not exist.");
+ }
+
Member m = getMember(dispId);
if (m instanceof Method) {
return new MethodAdaptor((Method) m);
diff --git a/dev/core/src/com/google/gwt/dev/shell/Jsni.java b/dev/core/src/com/google/gwt/dev/shell/Jsni.java
index 2533cd7..19bd33d 100644
--- a/dev/core/src/com/google/gwt/dev/shell/Jsni.java
+++ b/dev/core/src/com/google/gwt/dev/shell/Jsni.java
@@ -106,13 +106,18 @@
Member member;
if (dispId < 0) {
- // We've already emitted a warning from getDispId; just fake the jsni
member = null;
} else {
member = dispatchInfo.getClassInfoByDispId(dispId).getMember(dispId);
}
+
+ if (member == null) {
+ throw new HostedModeException(
+ "JSNI rewriter found reference to non-existent field in a field reference or java method tear-off: "
+ + ident + " at " + x.getSourceInfo());
+ }
- if (member == null || member instanceof Field
+ if (member instanceof Field
|| member instanceof SyntheticClassMember) {
if (q != null) {
accept(q);
@@ -176,18 +181,21 @@
member = dispatchInfo.getClassInfoByDispId(dispId).getMember(dispId);
}
+ if (member == null) {
+ throw new HostedModeException(
+ "JSNI rewriter found reference to non-existent field in a method invocation: "
+ + ref.getIdent() + " at " + ref.getSourceInfo());
+ }
+
/*
* Make sure the ident is a reference to a method or constructor and
* not a reference to a field whose contents (e.g. a Function) we
* intend to immediately invoke.
*
* p.C::method()(); versus p.C::field();
- *
- * Also, if the reference was to a non-existent field, we'll go ahead
- * and rewrite the call site as though -1 is a valid dispid.
+ *
*/
- if (member == null || member instanceof Method
- || member instanceof Constructor<?>) {
+ if (member instanceof Method || member instanceof Constructor<?>) {
// Use a clone instead of modifying the original JSNI
// __gwt_makeJavaInvoke(paramCount)(obj, dispId, args)
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/util/Arrays.java b/user/src/com/google/gwt/user/client/rpc/core/java/util/Arrays.java
index a3336ef..121ab51 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/util/Arrays.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/util/Arrays.java
@@ -60,16 +60,12 @@
Object[] array;
if (GWT.isScript()) {
// Violator pattern.
- array = getArray0(instance);
+ array = ArraysViolator.getArray0(instance);
} else {
// Clone the underlying array.
array = instance.toArray();
}
streamWriter.writeObject(array);
}
-
- private static native Object[] getArray0(List<?> instance) /*-{
- return instance.@java.util.Arrays$ArrayList::array;
- }-*/;
}
}
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/util/ArraysViolator.java b/user/src/com/google/gwt/user/client/rpc/core/java/util/ArraysViolator.java
new file mode 100644
index 0000000..350bd57
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/util/ArraysViolator.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2010 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.user.client.rpc.core.java.util;
+
+import java.util.List;
+
+/**
+ * Used to delay referencing methods only present in the emulated JRE until they
+ * are actually used.
+ */
+public class ArraysViolator {
+ public static native Object[] getArray0(List<?> instance) /*-{
+ return instance.@java.util.Arrays$ArrayList::array;
+ }-*/;
+}
diff --git a/user/super/com/google/gwt/emul/java/util/Random.java b/user/super/com/google/gwt/emul/java/util/Random.java
index 0ded4c2..3605535 100644
--- a/user/super/com/google/gwt/emul/java/util/Random.java
+++ b/user/super/com/google/gwt/emul/java/util/Random.java
@@ -34,14 +34,14 @@
*/
package java.util;
-import java.io.Serializable;
-
/**
* This class provides methods that generates pseudo-random numbers of different
* types, such as {@code int}, {@code long}, {@code double}, and {@code float}.
* It follows the algorithms specified in the JRE javadoc.
+ *
+ * This emulated version of Random is not serializable.
*/
-public class Random implements Serializable {
+public class Random {
private static final double multiplierHi = 0x5de;
private static final double multiplierLo = 0xece66d;
@@ -90,29 +90,21 @@
/**
* The boolean value indicating if the second Gaussian number is available.
- *
- * @serial
*/
private boolean haveNextNextGaussian = false;
/**
* The second Gaussian generated number.
- *
- * @serial
*/
private double nextNextGaussian;
/**
* The high 24 bits of the 48=bit seed value.
- *
- * @serial It is associated with the internal state of this generator.
*/
private double seedhi;
/**
* The low 24 bits of the 48=bit seed value.
- *
- * @serial It is associated with the internal state of this generator.
*/
private double seedlo;
diff --git a/user/test/com/google/gwt/emultest/java/math/BigIntegerConstructorsTest.java b/user/test/com/google/gwt/emultest/java/math/BigIntegerConstructorsTest.java
index 6909741..a3f77aa 100644
--- a/user/test/com/google/gwt/emultest/java/math/BigIntegerConstructorsTest.java
+++ b/user/test/com/google/gwt/emultest/java/math/BigIntegerConstructorsTest.java
@@ -786,29 +786,25 @@
// JRE implementation doesn't have the method tested here
return;
}
- BigInteger val = fromDouble(1.0);
+ BigInteger val = BigIntegerViolator.fromDouble(1.0);
assertEquals("1", val.toString());
- val = fromDouble(100.0);
+ val = BigIntegerViolator.fromDouble(100.0);
assertEquals("100", val.toString());
- val = fromDouble(2147483647.0);
+ val = BigIntegerViolator.fromDouble(2147483647.0);
assertEquals("2147483647", val.toString());
- val = fromDouble(-2147483647.0);
+ val = BigIntegerViolator.fromDouble(-2147483647.0);
assertEquals("-2147483647", val.toString());
- val = fromDouble(2147483648.0);
+ val = BigIntegerViolator.fromDouble(2147483648.0);
assertEquals("2147483648", val.toString());
- val = fromDouble(-2147483648.0);
+ val = BigIntegerViolator.fromDouble(-2147483648.0);
assertEquals("-2147483648", val.toString());
- val = fromDouble(4294967295.0);
+ val = BigIntegerViolator.fromDouble(4294967295.0);
assertEquals("4294967295", val.toString());
- val = fromDouble(-4294967295.0);
+ val = BigIntegerViolator.fromDouble(-4294967295.0);
assertEquals("-4294967295", val.toString());
- val = fromDouble(4294967296.0);
+ val = BigIntegerViolator.fromDouble(4294967296.0);
assertEquals("4294967296", val.toString());
- val = fromDouble(-4294967296.0);
+ val = BigIntegerViolator.fromDouble(-4294967296.0);
assertEquals("-4294967296", val.toString());
}
-
- private native BigInteger fromDouble(double v) /*-{
- return @java.math.BigInteger::valueOf(D)(v);
- }-*/;
}
diff --git a/user/test/com/google/gwt/emultest/java/math/BigIntegerViolator.java b/user/test/com/google/gwt/emultest/java/math/BigIntegerViolator.java
new file mode 100644
index 0000000..81edf89
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java/math/BigIntegerViolator.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2010 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.emultest.java.math;
+
+import java.math.BigInteger;
+
+/**
+ * Used to delay referencing methods only present in the emulated JRE until they
+ * are actually used.
+ */
+public class BigIntegerViolator {
+
+ public static native BigInteger fromDouble(double v) /*-{
+ return @java.math.BigInteger::valueOf(D)(v);
+ }-*/;
+}
\ No newline at end of file
diff --git a/user/test/com/google/gwt/emultest/java/util/TreeMapTest.java b/user/test/com/google/gwt/emultest/java/util/TreeMapTest.java
index 07251c9..37cd46d 100644
--- a/user/test/com/google/gwt/emultest/java/util/TreeMapTest.java
+++ b/user/test/com/google/gwt/emultest/java/util/TreeMapTest.java
@@ -136,12 +136,6 @@
assertEquals(expected.values().toArray(), actual.values().toArray());
}
- // Use JSNI to call a special method on our implementation of TreeMap.
- @SuppressWarnings("unchecked") // raw Map
- private static native void callAssertCorrectness(Map map) /*-{
- map.@java.util.TreeMap::assertCorrectness()();
- }-*/;
-
/**
* Create the expected return of toString for a Map containing only the passed
* key and value.
@@ -1868,7 +1862,7 @@
protected void verifyMap() {
if (GWT.isScript()) {
// Verify red-black correctness in our implementation
- callAssertCorrectness(map);
+ TreeMapViolator.callAssertCorrectness(map);
}
super.verifyMap();
}
diff --git a/user/test/com/google/gwt/emultest/java/util/TreeMapViolator.java b/user/test/com/google/gwt/emultest/java/util/TreeMapViolator.java
new file mode 100644
index 0000000..d2de931
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java/util/TreeMapViolator.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010 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.emultest.java.util;
+
+import java.util.Map;
+
+/**
+ * Used to delay referencing methods only present in the emulated JRE until they
+ * are actually used.
+ */
+public class TreeMapViolator {
+ // Use JSNI to call a special method on our implementation of TreeMap.
+ @SuppressWarnings("unchecked") // raw Map
+ public static native void callAssertCorrectness(Map map) /*-{
+ map.@java.util.TreeMap::assertCorrectness()();
+ }-*/;
+}