Fix for issue #1062; allows checked exceptions declared a JSNI method signature to actually be thrown in hosted mode as the correct type.
Review by: jat
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1054 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/shell/JavaScriptHost.java b/dev/core/src/com/google/gwt/dev/shell/JavaScriptHost.java
index 76c2ba4..272974e 100644
--- a/dev/core/src/com/google/gwt/dev/shell/JavaScriptHost.java
+++ b/dev/core/src/com/google/gwt/dev/shell/JavaScriptHost.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * Copyright 2007 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
@@ -45,7 +45,7 @@
* Invoke a native JavaScript function that returns a boolean value.
*/
public static boolean invokeNativeBoolean(String name, Object jthis,
- Class[] types, Object[] args) {
+ Class[] types, Object[] args) throws Throwable {
return sHost.invokeNativeBoolean(name, jthis, types, args);
}
@@ -53,7 +53,7 @@
* Invoke a native JavaScript function that returns a byte value.
*/
public static byte invokeNativeByte(String name, Object jthis, Class[] types,
- Object[] args) {
+ Object[] args) throws Throwable {
return sHost.invokeNativeByte(name, jthis, types, args);
}
@@ -61,7 +61,7 @@
* Invoke a native JavaScript function that returns a character value.
*/
public static char invokeNativeChar(String name, Object jthis, Class[] types,
- Object[] args) {
+ Object[] args) throws Throwable {
return sHost.invokeNativeChar(name, jthis, types, args);
}
@@ -69,7 +69,7 @@
* Invoke a native JavaScript function that returns a double value.
*/
public static double invokeNativeDouble(String name, Object jthis,
- Class[] types, Object[] args) {
+ Class[] types, Object[] args) throws Throwable {
return sHost.invokeNativeDouble(name, jthis, types, args);
}
@@ -77,7 +77,7 @@
* Invoke a native JavaScript function that returns a float value.
*/
public static float invokeNativeFloat(String name, Object jthis,
- Class[] types, Object[] args) {
+ Class[] types, Object[] args) throws Throwable {
return sHost.invokeNativeFloat(name, jthis, types, args);
}
@@ -85,7 +85,7 @@
* Invoke a native JavaScript function that returns a handle value.
*/
public static Object invokeNativeHandle(String name, Object jthis,
- Class returnType, Class[] types, Object[] args) {
+ Class returnType, Class[] types, Object[] args) throws Throwable {
return sHost.invokeNativeHandle(name, jthis, returnType, types, args);
}
@@ -93,7 +93,7 @@
* Invoke a native JavaScript function that returns an integer value.
*/
public static int invokeNativeInt(String name, Object jthis, Class[] types,
- Object[] args) {
+ Object[] args) throws Throwable {
return sHost.invokeNativeInt(name, jthis, types, args);
}
@@ -101,7 +101,7 @@
* Invoke a native JavaScript function that returns a long value.
*/
public static long invokeNativeLong(String name, Object jthis, Class[] types,
- Object[] args) {
+ Object[] args) throws Throwable {
return sHost.invokeNativeLong(name, jthis, types, args);
}
@@ -109,7 +109,7 @@
* Invoke a native JavaScript function that returns an object value.
*/
public static Object invokeNativeObject(String name, Object jthis,
- Class[] types, Object[] args) {
+ Class[] types, Object[] args) throws Throwable {
return sHost.invokeNativeObject(name, jthis, types, args);
}
@@ -117,7 +117,7 @@
* Invoke a native JavaScript function that returns a short value.
*/
public static short invokeNativeShort(String name, Object jthis,
- Class[] types, Object[] args) {
+ Class[] types, Object[] args) throws Throwable {
return sHost.invokeNativeShort(name, jthis, types, args);
}
@@ -125,7 +125,7 @@
* Invoke a native JavaScript function that returns a string value.
*/
public static String invokeNativeString(String name, Object jthis,
- Class[] types, Object[] args) {
+ Class[] types, Object[] args) throws Throwable {
return sHost.invokeNativeString(name, jthis, types, args);
}
@@ -133,7 +133,7 @@
* Invoke a native JavaScript function that returns no value.
*/
public static void invokeNativeVoid(String name, Object jthis, Class[] types,
- Object[] args) {
+ Object[] args) throws Throwable {
sHost.invokeNativeVoid(name, jthis, types, args);
}
@@ -153,7 +153,7 @@
return sHost.rebindAndCreate(className);
} catch (Throwable e) {
String msg = "Deferred binding failed for '" + className
- + "' (did you forget to inherit a required module?)";
+ + "' (did you forget to inherit a required module?)";
throw new RuntimeException(msg, e);
}
}
diff --git a/dev/core/src/com/google/gwt/dev/shell/JsniInjector.java b/dev/core/src/com/google/gwt/dev/shell/JsniInjector.java
index 1774936..a9c43e7 100644
--- a/dev/core/src/com/google/gwt/dev/shell/JsniInjector.java
+++ b/dev/core/src/com/google/gwt/dev/shell/JsniInjector.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * Copyright 2007 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
@@ -233,6 +233,8 @@
false, false);
sb.append(methodDecl + " {");
+ // wrap the call in a try-catch block
+ sb.append("try {");
// Write the Java call to the property invoke method, adding
// downcasts where necessary.
@@ -303,7 +305,21 @@
// parameters.
//
sb.append(Jsni.buildArgList(method));
- sb.append(");}");
+ sb.append(");");
+
+ // Catch exceptions; rethrow if the exception is RTE or declared.
+ sb.append("} catch (java.lang.Throwable __gwt_exception) {");
+ sb.append("if (__gwt_exception instanceof java.lang.RuntimeException) throw (java.lang.RuntimeException) __gwt_exception;");
+ JType[] throwTypes = method.getThrows();
+ for (int i = 0; i < throwTypes.length; ++i) {
+ String typeName = throwTypes[i].getQualifiedSourceName();
+ sb.append("if (__gwt_exception instanceof " + typeName + ") throw (" + typeName
+ + ") __gwt_exception;");
+ }
+ sb.append("throw new java.lang.RuntimeException(\"Undeclared checked exception thrown out of JavaScript; web mode behavior may differ.\", __gwt_exception);");
+ sb.append("}");
+
+ sb.append("}");
// Add extra lines at the end to match JSNI body.
//
diff --git a/dev/core/src/com/google/gwt/dev/shell/ModuleSpace.java b/dev/core/src/com/google/gwt/dev/shell/ModuleSpace.java
index bd991a1..c987314 100644
--- a/dev/core/src/com/google/gwt/dev/shell/ModuleSpace.java
+++ b/dev/core/src/com/google/gwt/dev/shell/ModuleSpace.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * Copyright 2007 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
@@ -30,25 +30,25 @@
*/
public abstract class ModuleSpace implements ShellJavaScriptHost {
- protected static ThreadLocal sCaughtJavaExceptionObject = new ThreadLocal();
+ private static ThreadLocal sCaughtJavaExceptionObject = new ThreadLocal();
- protected static ThreadLocal sLastThrownJavaException = new ThreadLocal();
+ private static ThreadLocal sLastThrownJavaException = new ThreadLocal();
- protected static ThreadLocal sThrownJavaExceptionObject = new ThreadLocal();
+ private static ThreadLocal sThrownJavaExceptionObject = new ThreadLocal();
/**
* Logger is thread local.
*/
private static ThreadLocal threadLocalLogger = new ThreadLocal();
- public static void setThrownJavaException(RuntimeException re) {
- RuntimeException was = (RuntimeException) sLastThrownJavaException.get();
- if (was != re) {
+ public static void setThrownJavaException(Throwable t) {
+ Throwable was = (Throwable) sLastThrownJavaException.get();
+ if (was != t) {
// avoid logging the same exception twice
- getLogger().log(TreeLogger.WARN, "Exception thrown into JavaScript", re);
- sLastThrownJavaException.set(re);
+ getLogger().log(TreeLogger.WARN, "Exception thrown into JavaScript", t);
+ sLastThrownJavaException.set(t);
}
- sThrownJavaExceptionObject.set(re);
+ sThrownJavaExceptionObject.set(t);
}
protected static RuntimeException createJavaScriptException(ClassLoader cl,
@@ -145,6 +145,22 @@
host.getClassLoader().clear();
}
+ public void exceptionCaught(int number, String name, String message) {
+ Throwable thrown = (Throwable) sThrownJavaExceptionObject.get();
+
+ if (thrown != null) {
+ // See if the caught exception was thrown by us
+ if (isExceptionSame(thrown, number, name, message)) {
+ sCaughtJavaExceptionObject.set(thrown);
+ sThrownJavaExceptionObject.set(null);
+ return;
+ }
+ }
+
+ sCaughtJavaExceptionObject.set(createJavaScriptException(
+ getIsolatedClassLoader(), name, message));
+ }
+
/**
* Get the unique key for this module.
*
@@ -164,7 +180,7 @@
}
public boolean invokeNativeBoolean(String name, Object jthis, Class[] types,
- Object[] args) {
+ Object[] args) throws Throwable {
JsValue result = invokeNative(name, jthis, types, args);
Boolean value = (Boolean) JsValueGlue.get(result, Boolean.class,
"invokeNativeBoolean(" + name + ")");
@@ -172,7 +188,7 @@
}
public byte invokeNativeByte(String name, Object jthis, Class[] types,
- Object[] args) {
+ Object[] args) throws Throwable {
JsValue result = invokeNative(name, jthis, types, args);
Byte value = (Byte) JsValueGlue.get(result, Byte.class, "invokeNativeByte("
+ name + ")");
@@ -180,7 +196,7 @@
}
public char invokeNativeChar(String name, Object jthis, Class[] types,
- Object[] args) {
+ Object[] args) throws Throwable {
JsValue result = invokeNative(name, jthis, types, args);
Character value = (Character) JsValueGlue.get(result, Character.class,
"invokeNativeCharacter(" + name + ")");
@@ -188,7 +204,7 @@
}
public double invokeNativeDouble(String name, Object jthis, Class[] types,
- Object[] args) {
+ Object[] args) throws Throwable {
JsValue result = invokeNative(name, jthis, types, args);
Double value = (Double) JsValueGlue.get(result, Double.class,
"invokeNativeDouble(" + name + ")");
@@ -196,7 +212,7 @@
}
public float invokeNativeFloat(String name, Object jthis, Class[] types,
- Object[] args) {
+ Object[] args) throws Throwable {
JsValue result = invokeNative(name, jthis, types, args);
Float value = (Float) JsValueGlue.get(result, Float.class,
"invokeNativeFloat(" + name + ")");
@@ -204,7 +220,7 @@
}
public Object invokeNativeHandle(String name, Object jthis, Class returnType,
- Class[] types, Object[] args) {
+ Class[] types, Object[] args) throws Throwable {
JsValue result = invokeNative(name, jthis, types, args);
return JsValueGlue.get(result, returnType, "invokeNativeHandle(" + name
@@ -212,7 +228,7 @@
}
public int invokeNativeInt(String name, Object jthis, Class[] types,
- Object[] args) {
+ Object[] args) throws Throwable {
JsValue result = invokeNative(name, jthis, types, args);
Integer value = (Integer) JsValueGlue.get(result, Integer.class,
"invokeNativeInteger(" + name + ")");
@@ -220,7 +236,7 @@
}
public long invokeNativeLong(String name, Object jthis, Class[] types,
- Object[] args) {
+ Object[] args) throws Throwable {
JsValue result = invokeNative(name, jthis, types, args);
Long value = (Long) JsValueGlue.get(result, Long.class, "invokeNativeLong("
+ name + ")");
@@ -228,14 +244,14 @@
}
public Object invokeNativeObject(String name, Object jthis, Class[] types,
- Object[] args) {
+ Object[] args) throws Throwable {
JsValue result = invokeNative(name, jthis, types, args);
return JsValueGlue.get(result, Object.class, "invokeNativeObject(" + name
+ ")");
}
public short invokeNativeShort(String name, Object jthis, Class[] types,
- Object[] args) {
+ Object[] args) throws Throwable {
JsValue result = invokeNative(name, jthis, types, args);
Short value = (Short) JsValueGlue.get(result, Short.class,
"invokeNativeShort(" + name + ")");
@@ -243,14 +259,14 @@
}
public String invokeNativeString(String name, Object jthis, Class[] types,
- Object[] args) {
+ Object[] args) throws Throwable {
JsValue result = invokeNative(name, jthis, types, args);
return (String) JsValueGlue.get(result, String.class, "invokeNativeString("
+ name + ")");
}
public void invokeNativeVoid(String name, Object jthis, Class[] types,
- Object[] args) {
+ Object[] args) throws Throwable {
JsValue result = invokeNative(name, jthis, types, args);
if (!result.isUndefined()) {
getLogger().log(
@@ -287,7 +303,16 @@
// Make sure we can resolve JSNI references to static Java names.
//
- initializeStaticDispatcher();
+ try {
+ Object staticDispatch = getStaticDispatcher();
+ createNative("initializeStaticDispatcher", 0, "__defineStatic",
+ new String[] {"__arg0"}, "window.__static = __arg0;");
+ invokeNativeVoid("__defineStatic", null, new Class[] {Object.class},
+ new Object[] {staticDispatch});
+ } catch (Throwable e) {
+ logger.log(TreeLogger.ERROR, "Unable to initialize static dispatcher", e);
+ throw new UnableToCompleteException();
+ }
// Actually run user code.
//
@@ -416,7 +441,7 @@
* @return the return value as a Variant.
*/
protected abstract JsValue doInvoke(String name, Object jthis, Class[] types,
- Object[] args);
+ Object[] args) throws Throwable;
protected CompilingClassLoader getIsolatedClassLoader() {
return host.getClassLoader();
@@ -425,7 +450,7 @@
/**
* Injects the magic needed to resolve JSNI references from module-space.
*/
- protected abstract void initializeStaticDispatcher();
+ protected abstract Object getStaticDispatcher();
/**
* Invokes a native JavaScript function.
@@ -437,14 +462,31 @@
* @return the return value as a Variant.
*/
protected final JsValue invokeNative(String name, Object jthis,
- Class[] types, Object[] args) {
+ Class[] types, Object[] args) throws Throwable {
// Whenever a native method is invoked, release any enqueued cleanup objects
JsValue.mainThreadCleanup();
- return doInvoke(name, jthis, types, args);
+ JsValue result = doInvoke(name, jthis, types, args);
+ // Is an exception active?
+ Throwable thrown = (Throwable) sCaughtJavaExceptionObject.get();
+ if (thrown == null) {
+ return result;
+ }
+ sCaughtJavaExceptionObject.set(null);
+
+ /*
+ * The stack trace on the stored exception will not be very useful due to
+ * how it was created. Using fillInStackTrace() resets the stack trace to
+ * this moment in time, which is usually far more useful.
+ */
+ thrown.fillInStackTrace();
+ throw thrown;
}
- protected boolean isExceptionActive() {
- return sCaughtJavaExceptionObject.get() != null;
+ protected boolean isExceptionSame(Throwable original, int number,
+ String name, String message) {
+ // For most platforms, the null exception means we threw it.
+ // IE overrides this.
+ return (name == null && message == null);
}
protected String rebind(String sourceName) throws UnableToCompleteException {
@@ -463,12 +505,6 @@
}
}
- protected RuntimeException takeJavaException() {
- RuntimeException re = (RuntimeException) sCaughtJavaExceptionObject.get();
- sCaughtJavaExceptionObject.set(null);
- return re;
- }
-
/**
* Clear the module's JavaScriptHost 'host' field.
*/
diff --git a/dev/core/src/com/google/gwt/dev/shell/ModuleSpacePropertyOracle.java b/dev/core/src/com/google/gwt/dev/shell/ModuleSpacePropertyOracle.java
index 459b5f7..ce466d2 100644
--- a/dev/core/src/com/google/gwt/dev/shell/ModuleSpacePropertyOracle.java
+++ b/dev/core/src/com/google/gwt/dev/shell/ModuleSpacePropertyOracle.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * Copyright 2007 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
@@ -94,7 +94,7 @@
//
value = space.invokeNativeString("__gwt_getProperty", null,
new Class[] {String.class}, new Object[] {prop.getName()});
- } catch (RuntimeException e) {
+ } catch (Throwable e) {
// Treat as an unknown value.
//
String msg = "Error while executing the JavaScript provider for property '"
diff --git a/dev/core/src/com/google/gwt/dev/shell/ShellJavaScriptHost.java b/dev/core/src/com/google/gwt/dev/shell/ShellJavaScriptHost.java
index 858a1dc..3f049a6 100644
--- a/dev/core/src/com/google/gwt/dev/shell/ShellJavaScriptHost.java
+++ b/dev/core/src/com/google/gwt/dev/shell/ShellJavaScriptHost.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * Copyright 2007 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
@@ -48,73 +48,73 @@
* Invoke a native JavaScript function that returns a boolean value.
*/
abstract boolean invokeNativeBoolean(String name, Object jthis,
- Class[] types, Object[] args);
+ Class[] types, Object[] args) throws Throwable;
/**
* Invoke a native JavaScript function that returns a byte value.
*/
abstract byte invokeNativeByte(String name, Object jthis, Class[] types,
- Object[] args);
+ Object[] args) throws Throwable;
/**
* Invoke a native JavaScript function that returns a character value.
*/
abstract char invokeNativeChar(String name, Object jthis, Class[] types,
- Object[] args);
+ Object[] args) throws Throwable;
/**
* Invoke a native JavaScript function that returns a double value.
*/
abstract double invokeNativeDouble(String name, Object jthis, Class[] types,
- Object[] args);
+ Object[] args) throws Throwable;
/**
* Invoke a native JavaScript function that returns a float value.
*/
abstract float invokeNativeFloat(String name, Object jthis, Class[] types,
- Object[] args);
+ Object[] args) throws Throwable;
/**
* Invoke a native JavaScript function that returns a handle value.
*/
abstract Object invokeNativeHandle(String name, Object jthis,
- Class returnType, Class[] types, Object[] args);
+ Class returnType, Class[] types, Object[] args) throws Throwable;
/**
* Invoke a native JavaScript function that returns an integer value.
*/
abstract int invokeNativeInt(String name, Object jthis, Class[] types,
- Object[] args);
+ Object[] args) throws Throwable;
/**
* Invoke a native JavaScript function that returns a long value.
*/
abstract long invokeNativeLong(String name, Object jthis, Class[] types,
- Object[] args);
+ Object[] args) throws Throwable;
/**
* Invoke a native JavaScript function that returns an object value.
*/
abstract Object invokeNativeObject(String name, Object jthis, Class[] types,
- Object[] args);
+ Object[] args) throws Throwable;
/**
* Invoke a native JavaScript function that returns a short value.
*/
abstract short invokeNativeShort(String name, Object jthis, Class[] types,
- Object[] args);
+ Object[] args) throws Throwable;
/**
* Invoke a native JavaScript function that returns a string value.
*/
abstract String invokeNativeString(String name, Object jthis, Class[] types,
- Object[] args);
+ Object[] args) throws Throwable;
/**
* Invoke a native JavaScript function that returns no value.
*/
abstract void invokeNativeVoid(String name, Object jthis, Class[] types,
- Object[] args);
+ Object[] args) throws Throwable;
/**
* Logs to the dev shell logger.
diff --git a/dev/linux/src/com/google/gwt/dev/shell/moz/MethodDispatch.java b/dev/linux/src/com/google/gwt/dev/shell/moz/MethodDispatch.java
index 9ac0296..2297ee4 100644
--- a/dev/linux/src/com/google/gwt/dev/shell/moz/MethodDispatch.java
+++ b/dev/linux/src/com/google/gwt/dev/shell/moz/MethodDispatch.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * Copyright 2007 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
@@ -88,16 +88,9 @@
// If we get here, it means an exception is being thrown from
// Java back into JavaScript
Throwable t = e.getTargetException();
- RuntimeException re;
- if (t instanceof RuntimeException) {
- re = (RuntimeException) t;
- } else {
- re = new RuntimeException("Checked exception thrown into JavaScript"
- + " (Web Mode behavior may differ)", t);
- }
// TODO(jat): if this was originally JavaScript exception, re-throw the
// original exception rather than just a null.
- ModuleSpaceMoz.setThrownJavaException(re);
+ ModuleSpaceMoz.setThrownJavaException(t);
LowLevelMoz.raiseJavaScriptException(jscontext);
} catch (IllegalArgumentException e) {
// TODO(jat): log to treelogger instead? If so, how do I get to it?
@@ -111,4 +104,4 @@
throw e;
}
}
-}
\ No newline at end of file
+}
diff --git a/dev/linux/src/com/google/gwt/dev/shell/moz/ModuleSpaceMoz.java b/dev/linux/src/com/google/gwt/dev/shell/moz/ModuleSpaceMoz.java
index e326fb5..2b1fa7d 100644
--- a/dev/linux/src/com/google/gwt/dev/shell/moz/ModuleSpaceMoz.java
+++ b/dev/linux/src/com/google/gwt/dev/shell/moz/ModuleSpaceMoz.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * Copyright 2007 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
@@ -20,7 +20,6 @@
import com.google.gwt.dev.shell.JsValueGlue;
import com.google.gwt.dev.shell.ModuleSpace;
import com.google.gwt.dev.shell.ModuleSpaceHost;
-import com.google.gwt.dev.shell.moz.LowLevelMoz.DispatchObject;
/**
* An implementation of {@link com.google.gwt.dev.shell.ModuleSpace} for
@@ -28,8 +27,6 @@
*/
public class ModuleSpaceMoz extends ModuleSpace {
- private DispatchObject staticDispatch;
-
private final int window;
/**
@@ -45,8 +42,11 @@
SwtGeckoGlue.addRefInt(window);
}
- /* (non-Javadoc)
- * @see com.google.gwt.dev.shell.ShellJavaScriptHost#createNative(java.lang.String, int, java.lang.String, java.lang.String[], java.lang.String)
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.google.gwt.dev.shell.ShellJavaScriptHost#createNative(java.lang.String,
+ * int, java.lang.String, java.lang.String[], java.lang.String)
*/
public void createNative(String file, int line, String jsniSignature,
String[] paramNames, String js) {
@@ -57,7 +57,9 @@
LowLevelMoz.executeScriptWithInfo(window, newScript, file, line);
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see com.google.gwt.dev.shell.ModuleSpace#dispose()
*/
public void dispose() {
@@ -65,25 +67,6 @@
super.dispose();
}
- /* (non-Javadoc)
- * @see com.google.gwt.dev.shell.ShellJavaScriptHost#exceptionCaught(int, java.lang.String, java.lang.String)
- */
- public void exceptionCaught(int number, String name, String message) {
- RuntimeException thrown = (RuntimeException) sThrownJavaExceptionObject.get();
-
- // See if the caught exception is null (thus thrown by us)
- if (thrown != null) {
- if (name == null && message == null) {
- sCaughtJavaExceptionObject.set(thrown);
- sThrownJavaExceptionObject.set(null);
- return;
- }
- }
-
- sCaughtJavaExceptionObject.set(createJavaScriptException(
- getIsolatedClassLoader(), name, message));
- }
-
/**
* Invokes a native JavaScript function.
*
@@ -109,31 +92,12 @@
jsArgsInt[i] = argv[i].getJsRootedValue();
}
JsValueMoz returnVal = JsValueMoz.createUndefinedValue(window);
- LowLevelMoz.invoke(window, name, jsthis.getJsRootedValue(),
- jsArgsInt, returnVal.getJsRootedValue());
-
- if (!isExceptionActive()) {
- return returnVal;
- }
-
- /*
- * The stack trace on the stored exception will not be very useful due to
- * how it was created. Using fillInStackTrace() resets the stack trace to
- * this moment in time, which is usually far more useful.
- */
- RuntimeException thrown = takeJavaException();
- thrown.fillInStackTrace();
- throw thrown;
+ LowLevelMoz.invoke(window, name, jsthis.getJsRootedValue(), jsArgsInt,
+ returnVal.getJsRootedValue());
+ return returnVal;
}
- protected void initializeStaticDispatcher() {
- staticDispatch = new GeckoDispatchAdapter(getIsolatedClassLoader());
-
- // Define the static dispatcher for use by JavaScript.
- //
- createNative("initializeStaticDispatcher", 0, "__defineStatic",
- new String[] {"__arg0"}, "window.__static = __arg0;");
- invokeNativeVoid("__defineStatic", null, new Class[] {Object.class},
- new Object[] {staticDispatch});
+ protected Object getStaticDispatcher() {
+ return new GeckoDispatchAdapter(getIsolatedClassLoader());
}
}
diff --git a/dev/mac/src/com/google/gwt/dev/shell/mac/MethodDispatch.java b/dev/mac/src/com/google/gwt/dev/shell/mac/MethodDispatch.java
index 38106dd..87cf270 100644
--- a/dev/mac/src/com/google/gwt/dev/shell/mac/MethodDispatch.java
+++ b/dev/mac/src/com/google/gwt/dev/shell/mac/MethodDispatch.java
@@ -84,14 +84,7 @@
// If we get here, it means an exception is being thrown from
// Java back into JavaScript
Throwable t = e.getTargetException();
- RuntimeException re;
- if (t instanceof RuntimeException) {
- re = (RuntimeException) t;
- } else {
- re = new RuntimeException("Checked exception thrown into JavaScript"
- + " (Web Mode behavior may differ)", t);
- }
- ModuleSpaceSaf.setThrownJavaException(re);
+ ModuleSpaceSaf.setThrownJavaException(t);
LowLevelSaf.raiseJavaScriptException(execState, LowLevelSaf.jsNull());
return LowLevelSaf.jsUndefined();
}
@@ -99,4 +92,4 @@
LowLevelSaf.popExecState(execState);
}
}
-}
\ No newline at end of file
+}
diff --git a/dev/mac/src/com/google/gwt/dev/shell/mac/ModuleSpaceSaf.java b/dev/mac/src/com/google/gwt/dev/shell/mac/ModuleSpaceSaf.java
index 02371e6..70b4533 100644
--- a/dev/mac/src/com/google/gwt/dev/shell/mac/ModuleSpaceSaf.java
+++ b/dev/mac/src/com/google/gwt/dev/shell/mac/ModuleSpaceSaf.java
@@ -26,14 +26,12 @@
*/
public class ModuleSpaceSaf extends ModuleSpace {
- private DispatchObject staticDispatch;
-
private final int window;
/**
* Constructs a browser interface for use with a global window object.
*
- * @param moduleName name of the module
+ * @param moduleName name of the module
* @param key unique key for this instance of the module
*/
public ModuleSpaceSaf(ModuleSpaceHost host, int scriptGlobalObject,
@@ -61,22 +59,6 @@
super.dispose();
}
- public void exceptionCaught(int number, String name, String message) {
- RuntimeException thrown = (RuntimeException) sThrownJavaExceptionObject.get();
-
- // See if the caught exception is null (thus thrown by us)
- if (thrown != null) {
- if (name == null && message == null) {
- sCaughtJavaExceptionObject.set(thrown);
- sThrownJavaExceptionObject.set(null);
- return;
- }
- }
-
- sCaughtJavaExceptionObject.set(createJavaScriptException(
- getIsolatedClassLoader(), name, message));
- }
-
/**
* Invokes a native JavaScript function.
*
@@ -99,36 +81,18 @@
}
int result = LowLevelSaf.invoke(curExecState, window, name, jsthis, argv);
- if (!isExceptionActive()) {
- return new JsValueSaf(result);
- }
+ return new JsValueSaf(result);
+}
- /*
- * The stack trace on the stored exception will not be very useful due to
- * how it was created. Using fillInStackTrace() resets the stack trace to
- * this moment in time, which is usually far more useful.
- */
- RuntimeException thrown = takeJavaException();
- thrown.fillInStackTrace();
- throw thrown;
- }
-
- protected void initializeStaticDispatcher() {
- staticDispatch = new WebKitDispatchAdapter(getIsolatedClassLoader());
-
- // Define the static dispatcher for use by JavaScript.
- //
- createNative("initializeStaticDispatcher", 0, "__defineStatic",
- new String[] {"__arg0"}, "window.__static = __arg0;");
- invokeNativeVoid("__defineStatic", null, new Class[] {Object.class},
- new Object[] {staticDispatch});
+ protected Object getStaticDispatcher() {
+ return new WebKitDispatchAdapter(getIsolatedClassLoader());
}
protected int wrapObjectAsJSObject(Object o) {
if (o == null) {
return LowLevelSaf.jsNull();
}
-
+
DispatchObject dispObj;
if (o instanceof DispatchObject) {
dispObj = (DispatchObject) o;
diff --git a/dev/windows/src/com/google/gwt/dev/shell/ie/IDispatchImpl.java b/dev/windows/src/com/google/gwt/dev/shell/ie/IDispatchImpl.java
index 38c8220..b66e86e 100644
--- a/dev/windows/src/com/google/gwt/dev/shell/ie/IDispatchImpl.java
+++ b/dev/windows/src/com/google/gwt/dev/shell/ie/IDispatchImpl.java
@@ -305,15 +305,8 @@
// Java back into JavaScript
Throwable t = e.getTargetException();
- RuntimeException re;
- if (t instanceof RuntimeException) {
- re = (RuntimeException) t;
- } else {
- re = new RuntimeException("Checked exception thrown into JavaScript"
- + " (web mode behavior may differ)", t);
- }
- ex = new HResultException(re);
- ModuleSpace.setThrownJavaException(re);
+ ex = new HResultException(t);
+ ModuleSpace.setThrownJavaException(t);
} catch (Exception e) {
// Log to the console for detailed examination.
//
diff --git a/dev/windows/src/com/google/gwt/dev/shell/ie/JsValueIE6.java b/dev/windows/src/com/google/gwt/dev/shell/ie/JsValueIE6.java
index 404fb2a..f287bf5 100644
--- a/dev/windows/src/com/google/gwt/dev/shell/ie/JsValueIE6.java
+++ b/dev/windows/src/com/google/gwt/dev/shell/ie/JsValueIE6.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * Copyright 2007 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
@@ -404,12 +404,17 @@
* @see com.google.gwt.dev.shell.JsValue#setWrappedJavaObject(com.google.gwt.dev.shell.CompilingClassLoader,
* java.lang.Object)
*/
- public void setWrappedJavaObject(CompilingClassLoader cl, Object obj) {
- if (obj == null) {
+ public void setWrappedJavaObject(CompilingClassLoader cl, Object val) {
+ IDispatchImpl dispObj;
+ if (val == null) {
setNull();
return;
+ } else if (val instanceof IDispatchImpl) {
+ dispObj = (IDispatchImpl)val;
+ } else {
+ dispObj = new IDispatchProxy(cl, val);
}
- IDispatch disp = new IDispatch(new IDispatchProxy(cl, obj).getAddress());
+ IDispatch disp = new IDispatch(dispObj.getAddress());
disp.AddRef();
setVariant(new Variant(disp));
}
diff --git a/dev/windows/src/com/google/gwt/dev/shell/ie/MethodDispatch.java b/dev/windows/src/com/google/gwt/dev/shell/ie/MethodDispatch.java
index 84cc999..9b47ce4 100644
--- a/dev/windows/src/com/google/gwt/dev/shell/ie/MethodDispatch.java
+++ b/dev/windows/src/com/google/gwt/dev/shell/ie/MethodDispatch.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * Copyright 2007 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
@@ -121,4 +121,4 @@
}
throw new HResultException(COM.E_NOTSUPPORTED);
}
-}
\ No newline at end of file
+}
diff --git a/dev/windows/src/com/google/gwt/dev/shell/ie/ModuleSpaceIE6.java b/dev/windows/src/com/google/gwt/dev/shell/ie/ModuleSpaceIE6.java
index b24cf05..681d4f3 100644
--- a/dev/windows/src/com/google/gwt/dev/shell/ie/ModuleSpaceIE6.java
+++ b/dev/windows/src/com/google/gwt/dev/shell/ie/ModuleSpaceIE6.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * Copyright 2007 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
@@ -23,7 +23,6 @@
import org.eclipse.swt.internal.ole.win32.IDispatch;
import org.eclipse.swt.ole.win32.OleAutomation;
import org.eclipse.swt.ole.win32.Variant;
-import org.eclipse.swt.widgets.Display;
/**
* An implementation of {@link com.google.gwt.dev.shell.ModuleSpace} for
@@ -31,14 +30,14 @@
*/
public class ModuleSpaceIE6 extends ModuleSpace {
/**
- * Invoke a JavaScript function. The static function exists to allow
+ * Invoke a JavaScript function. The static function exists to allow
* platform-dependent code to make JavaScript calls without having a
* ModuleSpaceIE6 (and all that entails) if it is not required.
*
* @param window the window containing the function
* @param name the name of the function
- * @param vArgs the array of arguments. vArgs[0] is the this parameter
- * supplied to the function, which must be null if it is static.
+ * @param vArgs the array of arguments. vArgs[0] is the this parameter
+ * supplied to the function, which must be null if it is static.
* @return the return value of the JavaScript function
*/
protected static Variant doInvokeOnWindow(OleAutomation window, String name,
@@ -78,19 +77,15 @@
private static int CODE(int hresult) {
return hresult & 0xFFFF;
}
-
// CHECKSTYLE_ON
- private Variant staticDispatch;
-
- private IDispatchProxy staticDispatchProxy;
-
private final OleAutomation window;
/**
* Constructs a browser interface for use with an IE6 'window' automation
* object.
- * @param moduleName
+ *
+ * @param moduleName
*/
public ModuleSpaceIE6(ModuleSpaceHost host, IDispatch scriptFrameWindow,
String moduleName, Object key) {
@@ -119,30 +114,6 @@
}
public void dispose() {
- /*
- * Dispose the static dispatcher. This should be simple and straightforward,
- * but isn't, because IE (especially 7) appears to over-Release() the static
- * dispatcher on unload (less often when shutting down, but occasionally
- * then as well). Because this occurs *after* the window unload event, we
- * intentionally use Display.asyncExec() to defer it until after the browser
- * is done cleaning up. We then dispose() the static dispatcher only if it
- * has not already been disposed().
- */
- if (staticDispatch != null) {
- final Variant staticDispatchToDispose = staticDispatch;
- staticDispatch = null;
-
- Display.getCurrent().asyncExec(new Runnable() {
- public void run() {
- // If the proxy has already been disposed, don't try to do so again,
- // as this will attempt to call through a null vtable.
- if (!staticDispatchProxy.isDisposed()) {
- staticDispatchToDispose.dispose();
- }
- }
- });
- }
-
// Dispose everything else.
if (window != null) {
window.dispose();
@@ -150,24 +121,6 @@
super.dispose();
}
- public void exceptionCaught(int number, String name, String message) {
- RuntimeException thrown = (RuntimeException) sThrownJavaExceptionObject.get();
-
- // See if the caught exception matches the thrown exception
- if (thrown != null) {
- HResultException hre = new HResultException(thrown);
- if (CODE(hre.getHResult()) == CODE(number)
- && hre.getMessage().equals(message)) {
- sCaughtJavaExceptionObject.set(thrown);
- sThrownJavaExceptionObject.set(null);
- return;
- }
- }
-
- sCaughtJavaExceptionObject.set(createJavaScriptException(
- getIsolatedClassLoader(), name, message));
- }
-
/**
* Invokes a native javascript function.
*
@@ -178,7 +131,7 @@
* @return the return value as a Variant.
*/
protected JsValue doInvoke(String name, Object jthis, Class[] types,
- Object[] args) {
+ Object[] args) throws Throwable {
Variant[] vArgs = null;
try {
// Build the argument list, including 'jthis'.
@@ -196,23 +149,12 @@
Variant result = doInvokeOnWindow(window, name, vArgs);
try {
- if (!isExceptionActive()) {
- return new JsValueIE6(result);
- }
+ return new JsValueIE6(result);
} finally {
if (result != null) {
result.dispose();
}
}
-
- /*
- * The stack trace on the stored exception will not be very useful due to
- * how it was created. Using fillInStackTrace() resets the stack trace to
- * this moment in time, which is usually far more useful.
- */
- RuntimeException thrown = takeJavaException();
- thrown.fillInStackTrace();
- throw thrown;
} finally {
// We allocated variants for all arguments, so we must dispose them all.
//
@@ -223,19 +165,14 @@
}
}
}
+
+ protected Object getStaticDispatcher() {
+ return new IDispatchProxy(getIsolatedClassLoader());
+ }
- protected void initializeStaticDispatcher() {
- staticDispatchProxy = new IDispatchProxy(getIsolatedClassLoader());
- IDispatch staticDisp = new IDispatch(staticDispatchProxy.getAddress());
- staticDisp.AddRef();
- this.staticDispatch = new Variant(staticDisp);
-
- // Define the static dispatcher for use by JavaScript.
- //
- createNative("initializeStaticDispatcher", 0, "__defineStatic",
- new String[] {"__arg0"}, "window.__static = __arg0;");
- invokeNativeVoid("__defineStatic", null, new Class[] {Variant.class},
- new Object[] {this.staticDispatch});
+ protected boolean isExceptionSame(Throwable original, int number, String name, String message) {
+ HResultException hre = new HResultException(original);
+ return CODE(hre.getHResult()) == CODE(number) && hre.getMessage().equals(message);
}
private Variant execute(String code) {