Bug 505418 - [GTK3][webkit] Support Javascript 'evalute()' in Webkit2 

Support for javascript to return arrays to Java

Change notes:
- This uses existing Java code to create Java objects instead
  of doing it in custom code.
  The reason is existing code already sucessfully deals with
  arrays. Also creating java objects in C is prone to errors/crashes.

Change-Id: I8eb6823f5694037da4073ba15988c6325f1fb7f8
Signed-off-by: Leo Ufimtsev <lufimtse@redhat.com>
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c
index 8cc8f9c..0d724f9 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c
@@ -1754,6 +1754,24 @@
 }
 #endif
 
+#ifndef NO__1webkit_1javascript_1result_1unref
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1webkit_1javascript_1result_1unref)
+	(JNIEnv *env, jclass that, jintLong arg0)
+{
+	WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1javascript_1result_1unref_FUNC);
+/*
+	webkit_javascript_result_unref(arg0);
+*/
+	{
+		WebKitGTK_LOAD_FUNCTION(fp, webkit_javascript_result_unref)
+		if (fp) {
+			((void (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+		}
+	}
+	WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1javascript_1result_1unref_FUNC);
+}
+#endif
+
 #ifndef NO__1webkit_1major_1version
 JNIEXPORT jint JNICALL WebKitGTK_NATIVE(_1webkit_1major_1version)
 	(JNIEnv *env, jclass that)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.h b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.h
index 1830cbe..4719786 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.h
@@ -155,10 +155,11 @@
  * webkigtk_struct.c/h should be updated by auto-tools to add setters/getters.
  */
 typedef struct {
-	jintLong 	returnPointer;
+	jintLong 	errorMsg;
 	int 		returnType;
-	jboolean 	returnBoolean;
-	double 		returnDouble;
+	jintLong	context;
+	jintLong	value;
+	jintLong 	jsResultPointer;
 
 	jboolean 	JsCallFinished; // Custom field only used on C side. Not mirrored by Java.
 } SWTJSreturnVal;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_custom.c b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_custom.c
index 1fcb78b..4bfe48b 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_custom.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_custom.c
@@ -39,19 +39,6 @@
 dyn_JSGlobalContextRef 		(*fp_webkit_javascript_result_get_global_context)(dyn_WebKitJavascriptResult);
 void 			(*fp_webkit_web_view_run_javascript) 	(dyn_WebKitWebView, const gchar * /*script*/, GCancellable*, GAsyncReadyCallback, gpointer /*user_data*/);
 dyn_JSValueRef  (*fp_webkit_javascript_result_get_value)(dyn_WebKitJavascriptResult);
-bool 			(*fp_JSValueIsString)					(dyn_JSContextRef, dyn_JSValueRef);
-dyn_JSStringRef (*fp_JSValueToStringCopy) 				(dyn_JSContextRef, dyn_JSValueRef, dyn_JSValueRef* /*exception*/);
-size_t 			(*fp_JSStringGetMaximumUTF8CStringSize) (dyn_JSStringRef);
-size_t			(*fp_JSStringGetUTF8CString)(dyn_JSStringRef, char*, size_t);
-void 			(*fp_JSStringRelease)(dyn_JSStringRef);
-void 			(*fp_webkit_javascript_result_unref)(dyn_WebKitJavascriptResult);
-bool			(*fp_JSValueIsNumber)(dyn_JSContextRef, dyn_JSValueRef);
-double 			(*fp_JSValueToNumber)(dyn_JSContextRef, dyn_JSValueRef, dyn_JSValueRef*);
-bool 			(*fp_JSValueIsBoolean)(dyn_JSContextRef, dyn_JSValueRef);
-bool 			(*fp_JSValueToBoolean)(dyn_JSContextRef, dyn_JSValueRef);
-bool 			(*fp_JSValueIsNull)(dyn_JSContextRef, dyn_JSValueRef);
-bool 			(*fp_JSValueIsUndefined)(dyn_JSContextRef, dyn_JSValueRef);
-bool 			(*fp_JSValueIsArray)(dyn_JSContextRef, dyn_JSValueRef);
 
 #define INIT_WEBKIT_FP(function) \
 		{ \
@@ -63,23 +50,11 @@
 		}
 
 void initFPs() {
-	INIT_WEBKIT_FP(webkit_web_view_run_javascript); // At compile time, these args are turned into strings by a macro.
 	INIT_WEBKIT_FP(webkit_web_view_run_javascript_finish);
 	INIT_WEBKIT_FP(webkit_javascript_result_get_global_context);
+	INIT_WEBKIT_FP(webkit_web_view_run_javascript);
 	INIT_WEBKIT_FP(webkit_javascript_result_get_value);
-	INIT_WEBKIT_FP(JSValueIsString);
-	INIT_WEBKIT_FP(JSValueToStringCopy);
-	INIT_WEBKIT_FP(JSStringGetMaximumUTF8CStringSize);
-	INIT_WEBKIT_FP(JSStringGetUTF8CString);
-	INIT_WEBKIT_FP(JSStringRelease);
-	INIT_WEBKIT_FP(webkit_javascript_result_unref);
-	INIT_WEBKIT_FP(JSValueIsNumber);
-	INIT_WEBKIT_FP(JSValueToNumber);
-	INIT_WEBKIT_FP(JSValueIsBoolean);
-	INIT_WEBKIT_FP(JSValueToBoolean);
-	INIT_WEBKIT_FP(JSValueIsNull);
-	INIT_WEBKIT_FP(JSValueIsUndefined);
-	INIT_WEBKIT_FP(JSValueIsArray);
+
 	fps_cached = 1;
 	return;
 
@@ -91,6 +66,7 @@
 /*
  Calling JS script and getting return value example copied and adapted to be dynamic from:
  https://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebView.html#webkit-web-view-run-javascript-finish
+ Type conversion occurs on Java side.
 */
 static void
 web_view_javascript_finished_callback (GObject      *object,
@@ -103,10 +79,7 @@
     GError                 *error = NULL;
 
 	SWTJSreturnVal * swtjsreturnvalSTRUCT = (SWTJSreturnVal*) user_data;
-
-//  js_result = webkit_web_view_run_javascript_finish (WEBKIT_WEB_VIEW (object), result, &error); // Static.
-    js_result = fp_webkit_web_view_run_javascript_finish ((jintLong) object, result, &error); // Dynamic
-
+    js_result = fp_webkit_web_view_run_javascript_finish ((jintLong) object, result, &error);
     if (!js_result) {
     	WEBKIT_DBG_MSG ("DEBUG: webkitgtk_custom.c: webkitgtk_custom.c: Error running javascript(1): %s", error->message);
         swtjsreturnvalSTRUCT->returnType = 50; //SWT.java:ERROR_FAILED_EVALUATE
@@ -114,51 +87,17 @@
         gsize err_msg_len = strlen(error->message);
         err_msg = malloc(err_msg_len + 1);
         strcpy(err_msg, error->message);
-        swtjsreturnvalSTRUCT->returnPointer = (jintLong) err_msg;
-
+        swtjsreturnvalSTRUCT->errorMsg = (jintLong) err_msg;
         g_error_free (error);
     } else {
+    	WEBKIT_DBG_MSG ("DEBUG: webkitgtk_custom.c: webkitgtk_custom.c: Javascript execution yielded a value");
 		context = fp_webkit_javascript_result_get_global_context (js_result);
 		value = fp_webkit_javascript_result_get_value (js_result);
-		if (fp_JSValueIsString (context, value)) {
-			dyn_JSStringRef js_str_value;
-			gchar      *str_value;  // Note: Freeing up of string *has* to be done on Java side
-			gsize       str_length;
-
-			js_str_value = fp_JSValueToStringCopy (context, value, NULL);
-			str_length = fp_JSStringGetMaximumUTF8CStringSize (js_str_value);
-			str_value = (gchar *)g_malloc (str_length);
-			fp_JSStringGetUTF8CString (js_str_value, str_value, str_length);
-			fp_JSStringRelease (js_str_value);
-			WEBKIT_DBG_MSG ("DEBUG: webkitgtk_custom.c: JS script result: %s\n", str_value);
-			swtjsreturnvalSTRUCT->returnPointer = (jintLong) str_value;
-			swtjsreturnvalSTRUCT->returnType = 4;
-		} else if (fp_JSValueIsNumber(context, value)){
-			double num = fp_JSValueToNumber(context, value, NULL);
-			WEBKIT_DBG_MSG("DEBUG: webkitgtk_custom.c: JS returned a number: %f", num);
-			swtjsreturnvalSTRUCT->returnDouble =  num;
-			swtjsreturnvalSTRUCT->returnType = 3;
-		} else if (fp_JSValueIsBoolean(context, value)) {
-			bool retBool = fp_JSValueToBoolean(context, value);
-			WEBKIT_DBG_MSG("DEBUG: webkitgtk_custom.c: JS returned a boolean: %d", retBool); // 1 = true. 0 = false.
-			swtjsreturnvalSTRUCT->returnBoolean = retBool;
-			swtjsreturnvalSTRUCT->returnType = 2;
-		} else if (fp_JSValueIsNull(context, value) || fp_JSValueIsUndefined(context, value)){
-			WEBKIT_DBG_MSG("DEBUG: webkitgtk_custom.c: Return value is null or undefined");
-			swtjsreturnvalSTRUCT->returnType = 5;
-		} else if (fp_JSValueIsArray(context, value)) {
-			WEBKIT_DBG_MSG("DEBUG: webkitgtk_custom.c: Return type is an array");
-			swtjsreturnvalSTRUCT->returnType = 6;
-			// TODO - TO BE IMPLEMENTED.
-			// -- SEE JSTypedArray.cpp
-			// -- int, bool, string array,
-			// -- returned array may contain arrays (nested arrays).
-			// -- Idea: use WebKit.java:convertToJava(..)
-		} else {
-			swtjsreturnvalSTRUCT->returnType = 51; // SWT.java:ERROR_INVALID_RETURN_VALUE
-			WEBKIT_DBG_MSG ("webkitgtk_custom.c: Error running javascript(2): unexpected return value");
-		}
-		fp_webkit_javascript_result_unref (js_result);
+		swtjsreturnvalSTRUCT->context = (jintLong) context;
+		swtjsreturnvalSTRUCT->value = (jintLong) value;
+		swtjsreturnvalSTRUCT->returnType = 1; // Return is a value to be converted.
+		swtjsreturnvalSTRUCT->jsResultPointer = (jintLong) js_result;
+		// Note: js_result is free up in WebKit.java:evalute().
     }
 
     // Note about exit points: this function must unlock the spinlock prior to returning.
@@ -189,9 +128,9 @@
 	SWTJSreturnVal swtjsreturnvalSTRUCT;
 	swtjsreturnvalSTRUCT.JsCallFinished = false;
 	swtjsreturnvalSTRUCT.returnType = 0;
-	swtjsreturnvalSTRUCT.returnPointer = 0;
-	swtjsreturnvalSTRUCT.returnBoolean = 0;
-	swtjsreturnvalSTRUCT.returnDouble = 0;
+	swtjsreturnvalSTRUCT.errorMsg = 0;
+	swtjsreturnvalSTRUCT.context = 0;
+	swtjsreturnvalSTRUCT.value = 0;
 
 	fp_webkit_web_view_run_javascript(webkit_handle,(const gchar *) cString, NULL, web_view_javascript_finished_callback, &swtjsreturnvalSTRUCT);
 
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c
index b0dd35a..0ec4066 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c
@@ -110,6 +110,7 @@
 	"_1webkit_1hit_1test_1result_1context_1is_1link",
 	"_1webkit_1hit_1test_1result_1get_1link_1title",
 	"_1webkit_1hit_1test_1result_1get_1link_1uri",
+	"_1webkit_1javascript_1result_1unref",
 	"_1webkit_1major_1version",
 	"_1webkit_1micro_1version",
 	"_1webkit_1minor_1version",
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h
index 2795d42..6b1491d 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h
@@ -120,6 +120,7 @@
 	_1webkit_1hit_1test_1result_1context_1is_1link_FUNC,
 	_1webkit_1hit_1test_1result_1get_1link_1title_FUNC,
 	_1webkit_1hit_1test_1result_1get_1link_1uri_FUNC,
+	_1webkit_1javascript_1result_1unref_FUNC,
 	_1webkit_1major_1version_FUNC,
 	_1webkit_1micro_1version_FUNC,
 	_1webkit_1minor_1version_FUNC,
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_structs.c b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_structs.c
index 10420dd..d2b861f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_structs.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_structs.c
@@ -102,7 +102,7 @@
 typedef struct SWTJSreturnVal_FID_CACHE {
 	int cached;
 	jclass clazz;
-	jfieldID returnPointer, returnDouble, returnBoolean, returnType;
+	jfieldID returnType, errorMsg, jsResultPointer, context, value;
 } SWTJSreturnVal_FID_CACHE;
 
 SWTJSreturnVal_FID_CACHE SWTJSreturnValFc;
@@ -111,30 +111,33 @@
 {
 	if (SWTJSreturnValFc.cached) return;
 	SWTJSreturnValFc.clazz = (*env)->GetObjectClass(env, lpObject);
-	SWTJSreturnValFc.returnPointer = (*env)->GetFieldID(env, SWTJSreturnValFc.clazz, "returnPointer", I_J);
-	SWTJSreturnValFc.returnDouble = (*env)->GetFieldID(env, SWTJSreturnValFc.clazz, "returnDouble", "D");
-	SWTJSreturnValFc.returnBoolean = (*env)->GetFieldID(env, SWTJSreturnValFc.clazz, "returnBoolean", "Z");
 	SWTJSreturnValFc.returnType = (*env)->GetFieldID(env, SWTJSreturnValFc.clazz, "returnType", "I");
+	SWTJSreturnValFc.errorMsg = (*env)->GetFieldID(env, SWTJSreturnValFc.clazz, "errorMsg", I_J);
+	SWTJSreturnValFc.jsResultPointer = (*env)->GetFieldID(env, SWTJSreturnValFc.clazz, "jsResultPointer", I_J);
+	SWTJSreturnValFc.context = (*env)->GetFieldID(env, SWTJSreturnValFc.clazz, "context", I_J);
+	SWTJSreturnValFc.value = (*env)->GetFieldID(env, SWTJSreturnValFc.clazz, "value", I_J);
 	SWTJSreturnValFc.cached = 1;
 }
 
 SWTJSreturnVal *getSWTJSreturnValFields(JNIEnv *env, jobject lpObject, SWTJSreturnVal *lpStruct)
 {
 	if (!SWTJSreturnValFc.cached) cacheSWTJSreturnValFields(env, lpObject);
-	lpStruct->returnPointer = (jintLong)(*env)->GetIntLongField(env, lpObject, SWTJSreturnValFc.returnPointer);
-	lpStruct->returnDouble = (*env)->GetDoubleField(env, lpObject, SWTJSreturnValFc.returnDouble);
-	lpStruct->returnBoolean = (*env)->GetBooleanField(env, lpObject, SWTJSreturnValFc.returnBoolean);
 	lpStruct->returnType = (int)(*env)->GetIntField(env, lpObject, SWTJSreturnValFc.returnType);
+	lpStruct->errorMsg = (jintLong)(*env)->GetIntLongField(env, lpObject, SWTJSreturnValFc.errorMsg);
+	lpStruct->jsResultPointer = (jintLong)(*env)->GetIntLongField(env, lpObject, SWTJSreturnValFc.jsResultPointer);
+	lpStruct->context = (jintLong)(*env)->GetIntLongField(env, lpObject, SWTJSreturnValFc.context);
+	lpStruct->value = (jintLong)(*env)->GetIntLongField(env, lpObject, SWTJSreturnValFc.value);
 	return lpStruct;
 }
 
 void setSWTJSreturnValFields(JNIEnv *env, jobject lpObject, SWTJSreturnVal *lpStruct)
 {
 	if (!SWTJSreturnValFc.cached) cacheSWTJSreturnValFields(env, lpObject);
-	(*env)->SetIntLongField(env, lpObject, SWTJSreturnValFc.returnPointer, (jintLong)lpStruct->returnPointer);
-	(*env)->SetDoubleField(env, lpObject, SWTJSreturnValFc.returnDouble, (jdouble)lpStruct->returnDouble);
-	(*env)->SetBooleanField(env, lpObject, SWTJSreturnValFc.returnBoolean, (jboolean)lpStruct->returnBoolean);
 	(*env)->SetIntField(env, lpObject, SWTJSreturnValFc.returnType, (jint)lpStruct->returnType);
+	(*env)->SetIntLongField(env, lpObject, SWTJSreturnValFc.errorMsg, (jintLong)lpStruct->errorMsg);
+	(*env)->SetIntLongField(env, lpObject, SWTJSreturnValFc.jsResultPointer, (jintLong)lpStruct->jsResultPointer);
+	(*env)->SetIntLongField(env, lpObject, SWTJSreturnValFc.context, (jintLong)lpStruct->context);
+	(*env)->SetIntLongField(env, lpObject, SWTJSreturnValFc.value, (jintLong)lpStruct->value);
 }
 #endif
 
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java
index ea42b77..ac8c8d0 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java
@@ -947,35 +947,30 @@
 		} else {
 			fixedScript = script;
 		}
-		SWTJSreturnVal jsRetVal = new SWTJSreturnVal();
-		WebKitGTK.swtWebkitEvaluateJavascript(webView, Converter.wcsToMbcs(fixedScript, true), jsRetVal);
+		SWTJSreturnVal jsReturnVal = new SWTJSreturnVal();
+		WebKitGTK.swtWebkitEvaluateJavascript(webView, Converter.wcsToMbcs(fixedScript, true), jsReturnVal);
 
-		switch (jsRetVal.returnType) {
-		case SWTJSreturnVal.STRING: {
-			return Converter.cCharPtrToJavaString(jsRetVal.returnPointer);
-		}
-		case SWTJSreturnVal.NUMBER:
-			return new Double((double) jsRetVal.returnDouble);
-		case SWTJSreturnVal.BOOLEAN:
-			return new Boolean(jsRetVal.returnBoolean);
-		case SWTJSreturnVal.NULL:
-			return null;
-		case SWTJSreturnVal.ARRAY:
-			// TODO - implement support for retunrning arrays.
-			System.err.println("Webkit2: Support for returning arrays not yet implemented. Returning null instead");
-			return null;
-		case SWT.ERROR_FAILED_EVALUATE: {
-			String err_msg = Converter.cCharPtrToJavaString(jsRetVal.returnPointer);
-			if (err_msg.length() > 0) {
-				throw new SWTException (SWT.ERROR_FAILED_EVALUATE, err_msg);
-			} else {
-				// With no error message, "Failed to evaluate javascript expression" is printed, which is better than "".
-				throw new SWTException (SWT.ERROR_FAILED_EVALUATE);
+		switch (jsReturnVal.returnType) {
+			case SWTJSreturnVal.VALUE:
+				Object retObj = null;
+				try {
+					retObj = convertToJava(jsReturnVal.context, jsReturnVal.value);
+				} catch (IllegalArgumentException invalid_arg) {
+					SWT.error (SWT.ERROR_INVALID_RETURN_VALUE);
+				} finally {
+					WebKitGTK.webkit_javascript_result_unref (jsReturnVal.jsResultPointer);
+				}
+				return retObj;
+			case SWT.ERROR_FAILED_EVALUATE: {
+				String err_msg = Converter.cCharPtrToJavaString(jsReturnVal.errorMsg);
+				if (err_msg.length() > 0) {
+					throw new SWTException (SWT.ERROR_FAILED_EVALUATE, err_msg);
+				} else {
+					// With no error message, "Failed to evaluate javascript expression" is printed, which is better than "".
+					throw new SWTException (SWT.ERROR_FAILED_EVALUATE);
+				}
+				}
 			}
-		}
-		case SWT.ERROR_INVALID_RETURN_VALUE:
-			throw new SWTException(SWT.ERROR_INVALID_RETURN_VALUE);
-		}
 		return null;
 	} else {
 		return super.evaluate(script);
@@ -2322,6 +2317,8 @@
 long /*int*/ callJava (long /*int*/ ctx, long /*int*/ func, long /*int*/ thisObject, long /*int*/ argumentCount, long /*int*/ arguments, long /*int*/ exception) {
 	Object returnValue = null;
 	if (argumentCount == 3) {
+		// Javastring array: <int: function index>, <string: token>, <array: javascript args>
+		// 1st arg: Function index
 		long /*int*/[] result = new long /*int*/[1];
 		C.memmove (result, arguments, C.PTR_SIZEOF);
 		int type = WebKitGTK.JSValueGetType (ctx, result[0]);
@@ -2329,6 +2326,7 @@
 			int index = ((Double)convertToJava (ctx, result[0])).intValue ();
 			result[0] = 0;
 			Integer key = new Integer (index);
+			// 2nd arg: function token
 			C.memmove (result, arguments + C.PTR_SIZEOF, C.PTR_SIZEOF);
 			type = WebKitGTK.JSValueGetType (ctx, result[0]);
 			if (type == WebKitGTK.kJSTypeString) {
@@ -2336,6 +2334,7 @@
 				BrowserFunction function = functions.get (key);
 				if (function != null && token.equals (function.token)) {
 					try {
+						// 3rd Arg: paramaters given from Javascript
 						C.memmove (result, arguments + 2 * C.PTR_SIZEOF, C.PTR_SIZEOF);
 						Object temp = convertToJava (ctx, result[0]);
 						if (temp instanceof Object[]) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/SWTJSreturnVal.java b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/SWTJSreturnVal.java
index 3791427..679733d 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/SWTJSreturnVal.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/SWTJSreturnVal.java
@@ -26,27 +26,24 @@
 	 * Fields used to determine type of return value. These are like enums.
 	 * Note. SWT Tools doesn't auto generate setters/getters for static fields.
 	 */
-	public static final int BOOLEAN = 2;
-	public static final int NUMBER = 3;
-	public static final int STRING = 4;  // Value in returnPointer. Needs to be freed on Java side
-	public static final int NULL = 5;
-	public static final int ARRAY = 6;
-
-	// Note, the following are used but are defined in SWT.java:
+	public static final int VALUE = 1;    // as in return type is a value
+	// Note, the following two types are used but are defined in SWT.java:
 	// ERROR_FAILED_EVALUATE = 50;
 	// ERROR_INVALID_RETURN_VALUE = 51;
-
-	/** @field cast=(jintLong) */
-	public long /*int*/ returnPointer;
-
-	/** @field cast(double) */
-	public double returnDouble;
-
-	/** @field cast(jboolean) */
-	public boolean returnBoolean;
-
 	/** @field cast=(int) */
 	public int returnType;  //Uses types defined above.
 
+	/** @field cast=(jintLong) */
+	public long /*int*/ errorMsg;
+
+	/** @field cast=(jintLong) */
+	public long /*int*/ jsResultPointer;
+
+	/** @field cast=(jintLong) */
+	public long /*int*/ context;
+
+	/** @field cast=(jintLong) */
+	public long /*int*/ value;
+
 	public static final int sizeof = WebKitGTK.SWTJSreturnVal_sizeof();
 }
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java
index 69c0ca9..1cbb2ed 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java
@@ -290,6 +290,19 @@
 	}
 }
 
+// Signature: 	   void webkit_javascript_result_unref (WebKitJavascriptResult *js_result);
+// Type Note:      WebKitJavascriptResult -> gpointer -> jintLong
+/** @method flags=dynamic */
+public static final native void _webkit_javascript_result_unref(long /*int*/ js_result);
+public static final void webkit_javascript_result_unref(long /*int*/ js_result) {
+	lock.lock();
+	try {
+		_webkit_javascript_result_unref (js_result);
+	} finally {
+		lock.unlock();
+	}
+}
+
 /** @method flags=dynamic */
 public static final native int _JSValueGetType (long /*int*/ ctx, long /*int*/ value);
 public static final int JSValueGetType (long /*int*/ ctx, long /*int*/ value) {