Initial subversion import.

The following lines are to recognize contributions made before the switch
to Subversion.

Patch by: bruce, jgw, scottb, mmendez, ecc, hcc, knorton, haeberling, samgross, mat.gessel


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/jni/mac/DispWrapper.cpp b/jni/mac/DispWrapper.cpp
new file mode 100644
index 0000000..68eb09f
--- /dev/null
+++ b/jni/mac/DispWrapper.cpp
@@ -0,0 +1,89 @@
+// Copyright 2005 Google Inc.
+// All Rights Reserved.
+
+#include "DispWrapper.h"
+#include "FunctionObject.h"
+
+using namespace KJS;
+
+const ClassInfo DispWrapper::info = {"DispWrapper", 0, 0, 0};
+
+JSValue *DispWrapper::getter(ExecState* exec, JSObject* thisObj, const Identifier& propertyName, const PropertySlot& slot) {
+	TRACE("ENTER DispWrapper::getter");
+	if (propertyName.ustring() == "toString") {
+		return new ToStringFunction();
+	}
+	if (thisObj->classInfo() == &DispWrapper::info) {
+		DispWrapper* dispWrap = static_cast<DispWrapper*>(thisObj);
+		jobject dispObj = dispWrap->dispObj;
+		jstring jpropName = gEnv->NewString((const jchar*)propertyName.data(), propertyName.size());
+		if (!jpropName || gEnv->ExceptionCheck()) {
+			gEnv->ExceptionClear();
+			return jsUndefined();
+		}
+		jint result = gEnv->CallIntMethod(dispObj, gGetFieldMeth, jpropName);
+		if (!result || gEnv->ExceptionCheck()) {
+			gEnv->ExceptionClear();
+			return jsUndefined();
+		}
+		TRACE("SUCCESS DispWrapper::getter");
+		return (JSValue*)result;
+	}
+	return jsUndefined();
+}
+
+DispWrapper::DispWrapper(jobject dispObj): dispObj(dispObj) {
+}
+
+DispWrapper::~DispWrapper() {
+	gEnv->DeleteGlobalRef(dispObj);
+}
+
+bool DispWrapper::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) {
+	slot.setCustom(this, getter);
+	return true;
+}
+
+bool DispWrapper::canPut(ExecState *exec, const Identifier &propertyName) const {
+	return true;
+}
+
+void DispWrapper::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr) {
+	TRACE("ENTER DispWrapper::put");
+	jstring jpropName = gEnv->NewString((const jchar*)propertyName.data(), propertyName.size());
+	if (!jpropName || gEnv->ExceptionCheck()) {
+		gEnv->ExceptionClear();
+		return;
+	}
+
+	gEnv->CallVoidMethod(dispObj, gSetFieldMeth, jpropName, (jint)value);
+	if (gEnv->ExceptionCheck()) {
+		gEnv->ExceptionClear();
+		return;
+	}
+	TRACE("SUCCESS DispWrapper::put");
+}
+
+bool DispWrapper::deleteProperty(ExecState *exec, const Identifier &propertyName) {
+	return false;
+}
+
+JSValue *DispWrapper::defaultValue(ExecState *exec, JSType hint) const {
+	jstring result = (jstring)gEnv->CallObjectMethod(dispObj, gToStringMeth);
+	if (gEnv->ExceptionCheck()) {
+		return jsUndefined();
+	} else if (!result) {
+		return jsNull();
+	} else {
+		JStringWrap jresult(gEnv, result);
+		return jsString(UString((const UChar*)jresult.jstr(), jresult.length()));
+	}
+}
+
+bool DispWrapper::implementsCall() const {
+	return false;
+}
+
+JSValue *DispWrapper::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) {
+	return jsUndefined();
+}
diff --git a/jni/mac/DispWrapper.h b/jni/mac/DispWrapper.h
new file mode 100644
index 0000000..4eed813
--- /dev/null
+++ b/jni/mac/DispWrapper.h
@@ -0,0 +1,43 @@
+// Copyright 2005 Google Inc.
+// All Rights Reserved.
+
+#ifndef DISP_WRAPPER_H
+#define DISP_WRAPPER_H
+
+#include "gwt-webkit.h"
+#include <kjs/object.h>
+
+// This class actually wraps Java objects
+class DispWrapper : public KJS::JSObject {
+public:
+	// dispObj MUST be a global ref
+    DispWrapper(jobject dispObj);
+	virtual ~DispWrapper();
+	jobject getDispObj();
+
+public:
+	// implementations of JSObject methods
+    const KJS::ClassInfo *classInfo() const { return &info; }
+
+    virtual bool getOwnPropertySlot(KJS::ExecState*, const KJS::Identifier&, KJS::PropertySlot&);
+    virtual bool canPut(KJS::ExecState*, const KJS::Identifier&) const;
+    virtual void put(KJS::ExecState*, const KJS::Identifier&, KJS::JSValue*, int);
+    virtual bool deleteProperty(KJS::ExecState*, const KJS::Identifier&);
+    virtual KJS::JSValue *defaultValue(KJS::ExecState*, KJS::JSType) const;
+    virtual bool implementsCall() const;
+    virtual KJS::JSValue *callAsFunction(KJS::ExecState*, KJS::JSObject*, const KJS::List&);
+    
+    static const KJS::ClassInfo info;
+
+private:
+	static KJS::JSValue* getter(KJS::ExecState*, KJS::JSObject*, const KJS::Identifier&, const KJS::PropertySlot&);
+
+private:
+	jobject dispObj;
+};
+
+inline jobject DispWrapper::getDispObj() {
+	return dispObj;
+}
+
+#endif
diff --git a/jni/mac/FuncWrapper.cpp b/jni/mac/FuncWrapper.cpp
new file mode 100644
index 0000000..e44ca03
--- /dev/null
+++ b/jni/mac/FuncWrapper.cpp
@@ -0,0 +1,42 @@
+// Copyright 2005 Google Inc.
+// All Rights Reserved.
+
+#include "FuncWrapper.h"
+#include <kjs/array_object.h>
+
+using namespace KJS;
+
+// FuncWrapper
+FuncWrapper::FuncWrapper(const UString& name, jobject funcObj): FunctionObject(name)
+, funcObj(funcObj) {
+}
+
+FuncWrapper::~FuncWrapper() {
+	gEnv->DeleteGlobalRef(funcObj);
+}
+
+JSValue *FuncWrapper::callAsFunction(ExecState* execState, JSObject* thisObj, const List& args) {
+    TRACE("ENTER FuncWrapper::callAsFunction");
+
+	int argc = args.size();
+    jintArray jsargs = gEnv->NewIntArray(argc);
+    if (!jsargs || gEnv->ExceptionCheck())
+        return TRACE("FAIL FuncWrapper::callAsFunction: NewIntArray"), jsUndefined();
+
+	for (int i = 0; i < argc; ++i) {
+		JSValue* arg = args[i];
+		gEnv->SetIntArrayRegion(jsargs, i, 1, (jint*)&arg);
+		if (gEnv->ExceptionCheck())
+			return TRACE("FAIL FuncWrapper::callAsFunction: SetIntArrayRegion"), jsUndefined();
+	}
+
+    jint result = gEnv->CallIntMethod(funcObj, gInvokeMeth, execState, thisObj, jsargs);
+    if (gEnv->ExceptionCheck())
+        return TRACE("FAIL FuncWrapper::callAsFunction: java exception is active"), jsUndefined();
+
+    if (execState->hadException())
+        return TRACE("FAIL FuncWrapper::callAsFunction: js exception is active"), jsUndefined();
+
+    TRACE("SUCCESS FuncWrapper::callAsFunction");
+    return (JSValue*)result;
+}
diff --git a/jni/mac/FuncWrapper.h b/jni/mac/FuncWrapper.h
new file mode 100644
index 0000000..8019754
--- /dev/null
+++ b/jni/mac/FuncWrapper.h
@@ -0,0 +1,29 @@
+// Copyright 2005 Google Inc.
+// All Rights Reserved.
+
+#ifndef FUNC_WRAPPER_H
+#define FUNC_WRAPPER_H
+
+#include "FunctionObject.h"
+#include <jni.h>
+
+// This class actually wraps Java method objects
+class FuncWrapper : public FunctionObject {
+public:
+	// funcObj MUST be a global ref
+	FuncWrapper(const KJS::UString& name, jobject funcObj);
+	virtual ~FuncWrapper();
+	jobject getFuncObj();
+
+public:
+    virtual KJS::JSValue *callAsFunction(KJS::ExecState*, KJS::JSObject*, const KJS::List&);
+
+private:
+	jobject funcObj;
+};
+
+inline jobject FuncWrapper::getFuncObj() {
+	return funcObj;
+}
+
+#endif
diff --git a/jni/mac/FunctionObject.cpp b/jni/mac/FunctionObject.cpp
new file mode 100644
index 0000000..8e013cd
--- /dev/null
+++ b/jni/mac/FunctionObject.cpp
@@ -0,0 +1,132 @@
+// Copyright 2005 Google Inc.
+// All Rights Reserved.
+
+#include "FunctionObject.h"
+#include <kjs/array_object.h>
+
+using namespace KJS;
+
+const ClassInfo FunctionObject::info = {"Function", 0, 0, 0};
+
+class CallFunction : public FunctionObject {
+public:
+	CallFunction(): FunctionObject("call") {
+	}
+
+    virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) {
+		// Copied from FunctionProtoFunc::callAsFunction()
+		JSValue *thisArg = args[0];
+		JSObject *func = thisObj;
+
+		if (!func->implementsCall())
+			return throwError(exec, TypeError);
+
+		JSObject *callThis;
+		if (thisArg->isUndefinedOrNull())
+			callThis = exec->dynamicInterpreter()->globalObject();
+		else
+			callThis = thisArg->toObject(exec);
+
+		return func->call(exec, callThis, args.copyTail());
+	}
+};
+
+class ApplyFunction  : public FunctionObject {
+public:
+	ApplyFunction(): FunctionObject("apply") {
+	}
+
+    virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) {
+		// Copied from FunctionProtoFunc::callAsFunction()
+		JSObject *func = thisObj;
+		if (!func->implementsCall())
+			return throwError(exec, TypeError);
+
+		JSValue *thisArg = args[0];
+		JSObject *applyThis;
+		if (thisArg->isUndefinedOrNull())
+			applyThis = exec->dynamicInterpreter()->globalObject();
+		else
+			applyThis = thisArg->toObject(exec);
+
+		JSValue *argArray = args[1];
+		List applyArgs;
+		if (!argArray->isUndefinedOrNull()) {
+			if (!argArray->isObject(&ArrayInstance::info))
+				return throwError(exec, TypeError);
+
+			JSObject *argArrayObj = static_cast<JSObject *>(argArray);
+			unsigned int length = argArrayObj->get(exec, lengthPropertyName)->toUInt32(exec);
+			for (unsigned int i = 0; i < length; ++i) {
+				applyArgs.append(argArrayObj->get(exec,i));
+			}
+		}
+		return func->call(exec, applyThis, applyArgs);
+	}
+};
+
+
+static UString makeFunctionString(const UString& name) {
+	return "\nfunction " + name + "() {\n    [native code]\n}\n";
+}
+
+JSValue *FunctionObject::getter(ExecState* exec, JSObject* obj, const Identifier& propertyName, const PropertySlot& slot) {
+	if (propertyName.ustring() == "toString") {
+		return new ToStringFunction();
+	} else if (propertyName.ustring() == "call") {
+		return new CallFunction();
+	} else if (propertyName.ustring() == "apply") {
+		return new ApplyFunction();
+	}
+	return jsUndefined();
+}
+
+FunctionObject::FunctionObject(const UString& name): name(name) {
+}
+
+bool FunctionObject::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) {
+	if (propertyName.ustring() == "toString") {
+		slot.setCustom(this, getter);
+		return true;
+	}
+	if (propertyName.ustring() == "call") {
+		slot.setCustom(this, getter);
+		return true;
+	}
+	if (propertyName.ustring() == "apply") {
+		slot.setCustom(this, getter);
+		return true;
+	}
+	return false;
+}
+
+bool FunctionObject::canPut(ExecState *exec, const Identifier &propertyName) const {
+	return false;
+}
+
+void FunctionObject::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr) {
+}
+
+bool FunctionObject::deleteProperty(ExecState *exec, const Identifier &propertyName) {
+	return false;
+}
+
+JSValue *FunctionObject::defaultValue(ExecState *exec, JSType hint) const {
+	return jsString(makeFunctionString(name));
+}
+
+bool FunctionObject::implementsCall() const {
+	return true;
+}
+
+// ToStringFunction
+
+ToStringFunction::ToStringFunction(): FunctionObject("toString") {
+}
+
+JSValue *ToStringFunction::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) {
+	if (!thisObj) {
+		return throwError(exec, TypeError);
+	}
+	return jsString(thisObj->toString(exec));
+}
diff --git a/jni/mac/FunctionObject.h b/jni/mac/FunctionObject.h
new file mode 100644
index 0000000..0860f5b
--- /dev/null
+++ b/jni/mac/FunctionObject.h
@@ -0,0 +1,43 @@
+// Copyright 2005 Google Inc.
+// All Rights Reserved.
+
+#ifndef FUNCTION_OBJECT_H
+#define FUNCTION_OBJECT_H
+
+#include "gwt-webkit.h"
+#include <kjs/object.h>
+
+class FunctionObject : public KJS::JSObject {
+protected:
+    FunctionObject(const KJS::UString& name);
+
+public:
+    const KJS::ClassInfo *classInfo() const { return &info; }
+
+	// shared implementations of JSObject methods
+    virtual bool getOwnPropertySlot(KJS::ExecState*, const KJS::Identifier&, KJS::PropertySlot&);
+    virtual bool canPut(KJS::ExecState*, const KJS::Identifier&) const;
+    virtual void put(KJS::ExecState*, const KJS::Identifier&, KJS::JSValue*, int);
+    virtual bool deleteProperty(KJS::ExecState*, const KJS::Identifier&);
+    virtual KJS::JSValue *defaultValue(KJS::ExecState*, KJS::JSType) const;
+    virtual bool implementsCall() const;
+	
+	// subclasses must implement
+    virtual KJS::JSValue *callAsFunction(KJS::ExecState*, KJS::JSObject*, const KJS::List&) = 0;
+    
+    static const KJS::ClassInfo info;
+
+private:
+	static KJS::JSValue* getter(KJS::ExecState*, KJS::JSObject*, const KJS::Identifier&, const KJS::PropertySlot&);
+
+private:
+	KJS::UString name;
+};
+
+class ToStringFunction : public FunctionObject {
+public:
+	ToStringFunction();
+    virtual KJS::JSValue *callAsFunction(KJS::ExecState*, KJS::JSObject*, const KJS::List&);
+};
+
+#endif
diff --git a/jni/mac/JStringWrap.h b/jni/mac/JStringWrap.h
new file mode 100644
index 0000000..2bb5c35
--- /dev/null
+++ b/jni/mac/JStringWrap.h
@@ -0,0 +1,23 @@
+// Copyright 2005 Google Inc.
+// All Rights Reserved.
+
+#ifndef JSTRINGWRAP_H
+#define JSTRINGWRAP_H
+
+#include <jni.h>
+
+struct JStringWrap
+{
+    JStringWrap(JNIEnv* env, jstring str): env(env), s(str), p(0), jp(0) { }
+    ~JStringWrap() { if (p) env->ReleaseStringUTFChars(s, p); if (jp) env->ReleaseStringChars(s, jp); }
+    const char* str() { if (!p) p = env->GetStringUTFChars(s, 0); return p; }
+    const jchar* jstr() { if (!jp) jp = env->GetStringChars(s, 0); return jp; }
+	jsize length() { return env->GetStringLength(s); }
+private:
+    JNIEnv* env;
+    jstring s;
+    const char* p;
+    const jchar* jp;
+};
+
+#endif
diff --git a/jni/mac/Makefile b/jni/mac/Makefile
new file mode 100644
index 0000000..ea0cf31
--- /dev/null
+++ b/jni/mac/Makefile
@@ -0,0 +1,31 @@
+# NOTE: THIS MAKEFILE DOES NOT WORK IN OUR BUILD SYSTEM. IT IS USED
+# TO DO THE ISOLATED BUILD OF THE MAC LIBS AND DEPENDS ON A DIFFERENT
+# DIRECTORY STRUCTURE. IT IS PUT HERE FOR ARCHIVE ONLY.
+
+GWT_LIB=../dist/libgwt-ll.jnilib
+
+CC = g++
+ARCHS = -arch i386 -arch ppc
+CFLAGS = -Wall -c $(ARCHS) -DCARBON -I /System/Library/Frameworks/JavaVM.framework/Headers -fno-exceptions -fno-rtti
+LFLAGS = -bundle $(ARCHS) -isysroot /Developer/SDKs/MacOSX10.4u.sdk
+WEBKITCFLAGS = $(CFLAGS)  -I../WebKit-15921/JavaScriptCore
+WEBKITLFLAGS = $(LFLAGS) -framework JavaScriptCore -F../dist/Frameworks
+GWT_OBJECTS = gwt-ll.o
+WEBKIT_OBJECTS = gwt-webkit.o DispWrapper.o FuncWrapper.o FunctionObject.o
+
+all: $(GWT_LIB)
+
+%.o: %.cpp
+	$(CC) -c -o $@ $< $(WEBKITCFLAGS)
+
+gwt-ll.o: ../gwt-ll-core/gwt-ll.cpp
+	$(CC) $(CFLAGS) gwt-ll.cpp
+
+$(GWT_LIB): $(GWT_OBJECTS) $(WEBKIT_OBJECTS)
+	$(CC) -o $(WEBKIT_LIB) $(WEBKITLFLAGS) $(WEBKIT_OBJECTS)
+
+install: all
+	cp *.jnilib $(OUTPUT_DIR)
+
+clean:
+	rm -f $(GWT_LIB) $(WEBKIT_LIB) *.o
diff --git a/jni/mac/build.xml b/jni/mac/build.xml
new file mode 100755
index 0000000..37146d8
--- /dev/null
+++ b/jni/mac/build.xml
@@ -0,0 +1,20 @@
+<project name="jni-mac" default="all" basedir=".">

+	<property name="gwt.root" location="../.." />

+	<property name="project.tail" value="jni/mac" />

+	<import file="${gwt.root}/common.ant.xml" />

+

+	<target name="build" description="Builds a JNI lib">

+		<mkdir dir="${project.jni}" />

+		<!-- TODO: Actually build this from source! -->

+		<copy todir="${project.jni}">

+			<fileset dir="prebuilt" />

+		</copy>

+	</target>

+

+	<target name="clean" description="Cleans this project's intermediate and output files">

+		<delete dir="${project.build}" failonerror="false" />

+		<delete dir="${project.jni}" failonerror="false" />

+	</target>

+

+	<target name="all" depends="build" description="Builds and packages this project" />

+</project>

diff --git a/jni/mac/gwt-ll.h b/jni/mac/gwt-ll.h
new file mode 100644
index 0000000..a2df826
--- /dev/null
+++ b/jni/mac/gwt-ll.h
@@ -0,0 +1,237 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_google_gwt_dev_shell_mac_LowLevelSaf */
+
+#ifndef _Included_com_google_gwt_dev_shell_mac_LowLevelSaf
+#define _Included_com_google_gwt_dev_shell_mac_LowLevelSaf
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    isNull
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isNull
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    isUndefined
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isUndefined
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    jsNull
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_jsNull
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    jsUndefined
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_jsUndefined
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _coerceToBoolean
+ * Signature: (II[Z)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1coerceToBoolean
+  (JNIEnv *, jclass, jint, jint, jbooleanArray);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _coerceToDouble
+ * Signature: (II[D)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1coerceToDouble
+  (JNIEnv *, jclass, jint, jint, jdoubleArray);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _coerceToString
+ * Signature: (II[Ljava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1coerceToString
+  (JNIEnv *, jclass, jint, jint, jobjectArray);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _convertBoolean
+ * Signature: (Z[I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1convertBoolean
+  (JNIEnv *, jclass,  jboolean, jintArray);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _convertDouble
+ * Signature: (D[I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1convertDouble
+  (JNIEnv *, jclass,  jdouble, jintArray);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _convertString
+ * Signature: (Ljava/lang/String;[I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1convertString
+  (JNIEnv *, jclass,  jstring, jintArray);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _executeScript
+ * Signature: (ILjava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1executeScript
+  (JNIEnv *, jclass, jint, jstring);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _executeScriptWithInfo
+ * Signature: (ILjava/lang/String;Ljava/lang/String;I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1executeScriptWithInfo
+  (JNIEnv *, jclass, jint, jstring, jstring, jint);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _gcLock
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1gcLock
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _gcUnlock
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1gcUnlock
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _getArgc
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1getArgc
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _getArgv
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1getArgv
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _getGlobalExecState
+ * Signature: (I[I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1getGlobalExecState
+  (JNIEnv *, jclass, jint, jintArray);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _initNative
+ * Signature: (Ljava/lang/Class;Ljava/lang/Class;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1initNative
+  (JNIEnv *, jclass, jclass, jclass);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _invoke
+ * Signature: (IILjava/lang/String;II[I[I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1invoke
+  (JNIEnv *, jclass, jint, jint, jstring, jint, jint, jintArray, jintArray);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _isObject
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1isObject
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _isString
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1isString
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _isWrappedDispatch
+ * Signature: (I[Z)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1isWrappedDispatch
+  (JNIEnv *, jclass, jint, jbooleanArray);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _jsLock
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1jsLock
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _jsUnlock
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1jsUnlock
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _raiseJavaScriptException
+ * Signature: (II)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1raiseJavaScriptException
+  (JNIEnv *, jclass, jint, jint);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _unwrapDispatch
+ * Signature: (I[Lcom/google/gwt/dev/shell/mac/LowLevelSaf/DispatchObject;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1unwrapDispatch
+  (JNIEnv *, jclass, jint, jobjectArray);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _wrapDispatch
+ * Signature: (Lcom/google/gwt/dev/shell/mac/LowLevelSaf/DispatchObject;[I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1wrapDispatch
+  (JNIEnv *, jclass, jobject, jintArray);
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _wrapFunction
+ * Signature: (Ljava/lang/String;Lcom/google/gwt/dev/shell/mac/LowLevelSaf/DispatchMethod;[I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1wrapFunction
+  (JNIEnv *, jclass, jstring, jobject, jintArray);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/jni/mac/gwt-webkit.cpp b/jni/mac/gwt-webkit.cpp
new file mode 100644
index 0000000..ec2dfaf
--- /dev/null
+++ b/jni/mac/gwt-webkit.cpp
@@ -0,0 +1,609 @@
+// Copyright 2005 Google Inc.
+// All Rights Reserved.
+
+#include "gwt-ll.h"
+#include "DispWrapper.h"
+#include "FuncWrapper.h"
+
+JNIEnv* gEnv;
+jclass gClass;
+jclass gDispObjCls;
+jclass gDispMethCls;
+jmethodID gGetFieldMeth;
+jmethodID gSetFieldMeth;
+jmethodID gInvokeMeth;
+jmethodID gToStringMeth;
+
+using namespace KJS;
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    isNull
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isNull
+  (JNIEnv *env, jclass, jint jsval) {
+    TRACE("ENTER Java_com_google_gwt_dev_shell_mac_LowLevelSaf__isNull");
+
+  JSValue* val = (JSValue*)jsval;
+  if (!val)
+    return JNI_FALSE;
+
+    TRACE("SUCESS Java_com_google_gwt_dev_shell_mac_LowLevelSaf__isNull");
+  return val->isNull();
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    isUndefined
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isUndefined
+  (JNIEnv *env, jclass, jint jsval) {
+    TRACE("ENTER Java_com_google_gwt_dev_shell_mac_LowLevelSaf__isUndefined");
+  JSValue* val = (JSValue*)jsval;
+  if (!val)
+    return JNI_FALSE;
+
+    TRACE("SUCCESS Java_com_google_gwt_dev_shell_mac_LowLevelSaf__isUndefined");
+  return val->isUndefined();
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    jsNull
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_jsNull
+  (JNIEnv *, jclass) {
+  return (jint)jsNull();
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    jsUndefined
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_jsUndefined
+  (JNIEnv *env, jclass) {
+    return (jint)jsUndefined();
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _coerceToBoolean
+ * Signature: (II[Z)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1coerceToBoolean
+  (JNIEnv * env, jclass, jint execState, jint jsval, jbooleanArray rval) {
+    TRACE("ENTER Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1coerceToBoolean");
+
+  if (!execState || !jsval)
+    return JNI_FALSE;
+
+  jboolean result = ((JSValue*)jsval)->toBoolean((ExecState*)execState);
+  env->SetBooleanArrayRegion(rval, 0, 1, &result);
+  if (env->ExceptionCheck())
+      return JNI_FALSE;
+
+    TRACE("SUCCESS Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1coerceToBoolean");
+  return JNI_TRUE;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _coerceToDouble
+ * Signature: (II[D)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1coerceToDouble
+  (JNIEnv *env, jclass, jint execState, jint jsval, jdoubleArray rval) {
+    TRACE("ENTER Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1coerceToDouble");
+
+  if (!execState || !jsval)
+    return JNI_FALSE;
+
+  jdouble result = ((JSValue*)jsval)->toNumber((ExecState*)execState);
+  env->SetDoubleArrayRegion(rval, 0, 1, &result);
+  if (env->ExceptionCheck())
+      return JNI_FALSE;
+
+    TRACE("SUCCESS Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1coerceToDouble");
+  return JNI_TRUE;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _coerceToString
+ * Signature: (II[Ljava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1coerceToString
+  (JNIEnv *env, jclass, jint execState, jint jsval, jobjectArray rval) {
+    TRACE("ENTER Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1coerceToString");
+
+  JSValue *val = (JSValue*)jsval;
+  if (!execState || !val)
+    return JNI_FALSE;
+
+  /* 
+   * Convert all objects to their string representation, EXCEPT
+   * null and undefined which will be returned as a true NULL.
+   */
+  jstring result = NULL;
+  if (!val->isNull() && !val->isUndefined()) {
+    UString str = val->toString((ExecState*)execState);
+    result = env->NewString((const jchar*)str.data(), str.size());
+    if (env->ExceptionCheck())
+      return JNI_FALSE;
+  }
+
+  env->SetObjectArrayElement(rval,0,result);
+  if (env->ExceptionCheck())
+    return JNI_FALSE;
+
+  TRACE("SUCCESS Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1coerceToString");
+  return JNI_TRUE;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _convertBoolean
+ * Signature: (IZ[I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1convertBoolean
+  (JNIEnv *env, jclass, jboolean jval, jintArray rval) {
+    TRACE("ENTER Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1convertBoolean");
+
+  JSValue *jsval = (jval == JNI_FALSE) ? jsBoolean(false) : jsBoolean(true);
+  if (!jsval)
+    return JNI_FALSE;
+
+  env->SetIntArrayRegion(rval,0,1,(const jint*)&jsval);
+  if (env->ExceptionCheck())
+    return JNI_FALSE;
+  
+    TRACE("SUCCESS Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1convertBoolean");
+  return JNI_TRUE;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _convertDouble
+ * Signature: (ID[I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1convertDouble
+  (JNIEnv *env, jclass, jdouble jval, jintArray rval) {
+    TRACE("ENTER Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1convertDouble");
+
+  JSValue *jsval = jsNumber(jval);
+  if (!jsval)
+    return JNI_FALSE;
+
+  env->SetIntArrayRegion(rval,0,1,(const jint*)&jsval);
+  if (env->ExceptionCheck())
+    return JNI_FALSE;
+
+    TRACE("SUCCESS Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1convertDouble");
+  return JNI_TRUE;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _convertString
+ * Signature: (ILjava/lang/String;[I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1convertString
+  (JNIEnv *env, jclass, jstring jval, jintArray rval) {
+    TRACE("ENTER Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1convertString");
+
+  JStringWrap jstr(env, jval);
+  if (!jstr.jstr())
+    return JNI_FALSE;
+  
+  JSValue *jsval = jsString(UString((const UChar*)jstr.jstr(), jstr.length()));
+  /*
+   * TODO / LEAK / HACK: We will be persisting these objects on the java side,
+   * so in order to keep the JS GC from collecting our objects when they are
+   * away, we need to add them to the protect list. This should be refactored
+   * out in favor of better memory mgmt scheme.
+   */
+  gcProtectNullTolerant(jsval);
+  if (!jsval)
+    return JNI_FALSE;
+
+  env->SetIntArrayRegion(rval,0,1,(const jint*)&jsval);
+  if (env->ExceptionCheck())
+    return JNI_FALSE;
+
+  TRACE("SUCCESS Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1convertString");
+  return JNI_TRUE;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _executeScript
+ * Signature: (ILjava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1executeScript
+  (JNIEnv* env, jclass, jint execState, jstring code) {
+    TRACE("ENTER Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1executeScript"); 
+  if (!execState || !code)
+    return JNI_FALSE;
+
+  JStringWrap jcode(env, code);
+  if (!jcode.jstr())
+    return JNI_FALSE;
+
+  Interpreter* interp = ((ExecState*)execState)->dynamicInterpreter();
+  if (!interp)
+    return JNI_FALSE;
+
+  interp->evaluate(UString(), 0, (const UChar*)jcode.jstr(), jcode.length());
+    TRACE("SUCCESS Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1executeScript");
+  return JNI_TRUE;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _executeScriptWithInfo
+ * Signature: (ILjava/lang/String;Ljava/lang/String;I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1executeScriptWithInfo
+  (JNIEnv* env, jclass, jint execState, jstring code, jstring file, jint line) {
+    TRACE("ENTER Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1executeScriptWithInfo");
+  if (!execState || !code || !file)
+    return JNI_FALSE;
+
+  JStringWrap jcode(env, code);
+  if (!jcode.jstr())
+    return JNI_FALSE;
+
+  JStringWrap jfile(env, file);
+  if (!jcode.jstr())
+    return JNI_FALSE;
+
+  Interpreter* interp = ((ExecState*)execState)->dynamicInterpreter();
+  if (!interp)
+    return JNI_FALSE;
+
+  interp->evaluate(UString((const UChar*)jfile.jstr(), jfile.length()), line, (const UChar*)jcode.jstr(), jcode.length());
+    TRACE("SUCCESS Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1executeScriptWithInfo");
+  return JNI_TRUE;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _gcLock
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1gcLock
+  (JNIEnv *, jclass, jint jsval) {
+  gcProtectNullTolerant((JSValue*)jsval);
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _gcUnlock
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1gcUnlock
+  (JNIEnv *, jclass, jint jsval) {
+  gcUnprotectNullTolerant((JSValue*)jsval);
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _getGlobalExecState
+ * Signature: (I[I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1getGlobalExecState
+  (JNIEnv *env, jclass, jint scriptObject, jintArray rval) {
+    TRACE("ENTER Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1getGlobalExecState");
+
+  if (!scriptObject || !((JSValue*)scriptObject)->isObject())
+    return JNI_FALSE;
+
+  Interpreter* interp = Interpreter::interpreterWithGlobalObject((JSObject*)scriptObject);
+  if (!interp)
+    return JNI_FALSE;
+
+  ExecState* execState = interp->globalExec();
+    env->SetIntArrayRegion(rval, 0, 1, (jint*)&execState);
+    if (env->ExceptionCheck())
+        return JNI_FALSE;
+    TRACE("SUCCESS Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1getGlobalExecState");
+  return JNI_TRUE;
+
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _initNative
+ * Signature: (Ljava/lang/Class;Ljava/lang/Class;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1initNative
+  (JNIEnv* env, jclass llClass, jclass dispObjCls, jclass dispMethCls) {
+  Interpreter::setShouldPrintExceptions(true);
+  gEnv = env;
+  gClass =  static_cast<jclass>(env->NewGlobalRef(llClass));
+  gDispObjCls = static_cast<jclass>(env->NewGlobalRef(dispObjCls));
+  gDispMethCls = static_cast<jclass>(env->NewGlobalRef(dispMethCls));
+  if (!gClass || !gDispObjCls || !gDispMethCls || env->ExceptionCheck()) {
+    return false;
+  }
+
+  gGetFieldMeth = env->GetMethodID(gDispObjCls, "getField", "(Ljava/lang/String;)I");
+  gSetFieldMeth = env->GetMethodID(gDispObjCls, "setField", "(Ljava/lang/String;I)V");
+  gInvokeMeth = env->GetMethodID(gDispMethCls, "invoke", "(II[I)I");
+  gToStringMeth = env->GetMethodID(gDispObjCls, "toString", "()Ljava/lang/String;");
+  if (!gGetFieldMeth || !gSetFieldMeth || !gInvokeMeth || !gToStringMeth || env->ExceptionCheck()) {
+    return false;
+  }
+
+#ifdef FILETRACE
+    gout = fopen("gwt-ll.log", "w");
+    filetrace("LOG STARTED");
+#endif // FILETRACE
+
+#ifdef JAVATRACE
+    gTraceMethod = env->GetStaticMethodID(gClass, "trace", "(Ljava/lang/String;)V");
+    if (!gTraceMethod || env->ExceptionCheck())
+        return false;
+#endif // JAVATRACE
+
+  return true;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _invoke
+ * Signature: (IILjava/lang/String;II[I[I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1invoke
+  (JNIEnv* env, jclass, jint jsexecState, jint jsScriptObject, jstring method, jint jsthis, jint argc, jintArray argv, jintArray rval) {
+    TRACE("ENTER Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1invoke");
+
+  if (!jsexecState || !jsScriptObject || !method || !rval)
+    return JNI_FALSE;
+  
+  ExecState* execState = (ExecState*)jsexecState;
+
+  JSObject* scriptObj = (JSObject*)jsScriptObject;
+  if (!scriptObj->isObject())
+    return JNI_FALSE;
+
+  JStringWrap jmethod(env, method);
+  if (!jmethod.jstr())
+    return JNI_FALSE;
+
+  JSObject* thisObj = (JSObject*)jsthis;
+  if (!thisObj || thisObj->isNull() || thisObj->isUndefined()) {
+    thisObj = scriptObj;
+  }
+  if (!thisObj->isObject())
+    return JNI_FALSE;
+
+  JSValue* maybeFunc = scriptObj->get(execState, Identifier((const UChar*)jmethod.jstr(), jmethod.length()));
+  if (!maybeFunc || !maybeFunc->isObject())
+    return JNI_FALSE;
+  
+  JSObject* func = (JSObject*)maybeFunc;
+  if (!func->implementsCall())
+    return JNI_FALSE;
+
+  List args;
+  for (int i = 0; i < argc; ++i) {
+    jint argi;
+    env->GetIntArrayRegion(argv, i, 1, &argi);
+    if (env->ExceptionCheck())
+      return JNI_FALSE;
+
+    if (argi) {
+      args.append((JSValue*)argi);
+    } else {
+      args.append(jsNull());
+    }
+  }
+
+  JSValue* result = func->call(execState, thisObj, args);
+    env->SetIntArrayRegion(rval, 0, 1, (jint*)&result);
+    if (env->ExceptionCheck())
+        return JNI_FALSE;
+
+    TRACE("SUCCESS Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1invoke");
+  return JNI_TRUE;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _isObject
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1isObject
+  (JNIEnv *, jclass, jint jsval) {
+  if (!jsval)
+    return JNI_FALSE;
+  return ((JSValue*)jsval)->isObject() ? JNI_TRUE : JNI_FALSE;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _isString
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1isString
+  (JNIEnv *, jclass, jint jsval) {
+  if (!jsval)
+    return JNI_FALSE;
+  return ((JSValue*)jsval)->isString() ? JNI_TRUE : JNI_FALSE;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _isWrappedDispatch
+ * Signature: (I[Z)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1isWrappedDispatch
+  (JNIEnv* env, jclass, jint jsval, jbooleanArray rval) {
+    TRACE("ENTER Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1isWrappedDispatch");
+  if (!jsval)
+    return JNI_FALSE;
+
+  JSValue* val = (JSValue*)jsval;
+  jboolean result = val->isObject(&DispWrapper::info) ? JNI_TRUE : JNI_FALSE;
+
+    env->SetBooleanArrayRegion(rval, 0, 1, &result);
+    if (env->ExceptionCheck())
+        return JNI_FALSE;
+
+    TRACE("SUCCESS Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1isWrappedDispatch");
+    return JNI_TRUE;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _jsLock
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1jsLock
+  (JNIEnv *, jclass) {
+  JSLock::lock();
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _jsUnlock
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1jsUnlock
+  (JNIEnv *, jclass) {
+  JSLock::unlock();
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _raiseJavaScriptException
+ * Signature: (II)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1raiseJavaScriptException
+  (JNIEnv *env, jclass, jint execState, jint jsval) {
+    TRACE("ENTER Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1raiseJavaScriptException");
+
+  if (!execState || !jsval)
+    return JNI_FALSE;
+
+  ((ExecState*)execState)->setException((JSValue*)jsval);
+    TRACE("SUCCESS Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1raiseJavaScriptException");
+  return JNI_TRUE;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _unwrapDispatch
+ * Signature: (I[Lcom/google/gwt/dev/shell/mac/LowLevelSaf/DispatchObject;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1unwrapDispatch
+  (JNIEnv* env, jclass, jint jsval, jobjectArray rval) {
+    TRACE("ENTER Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1unwrapDispatch");
+  if (!jsval)
+    return JNI_FALSE;
+
+  JSValue* val = (JSValue*)jsval;
+  if (!val->isObject(&DispWrapper::info))
+    return JNI_FALSE;
+
+  DispWrapper* wrapper = static_cast<DispWrapper*>(val);
+    env->SetObjectArrayElement(rval, 0, wrapper->getDispObj());
+    if (env->ExceptionCheck())
+        return JNI_FALSE;
+
+    TRACE("SUCCESS Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1unwrapDispatch");
+    return JNI_TRUE;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _wrapDispatch
+ * Signature: (Lcom/google/gwt/dev/shell/mac/LowLevelSaf/DispatchObject;[I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1wrapDispatch
+  (JNIEnv* env, jclass, jobject dispObj, jintArray rval) {
+    TRACE("ENTER Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1wrapDispatch");
+
+    jobject dispObjRef = env->NewGlobalRef(dispObj);
+    if (!dispObjRef || env->ExceptionCheck())
+        return JNI_FALSE;
+  
+  DispWrapper* wrapper = new DispWrapper(dispObjRef);
+  /*
+   * TODO / LEAK / HACK: We will be persisting these objects on the java side,
+   * so in order to keep the JS GC from collecting our objects when they are
+   * away, we need to add them to the protect list. This should be refactored
+   * out in favor of better memory mgmt scheme.
+   */
+  gcProtectNullTolerant(wrapper);
+    env->SetIntArrayRegion(rval, 0, 1, (jint*)&wrapper);
+    if (env->ExceptionCheck())
+        return JNI_FALSE;
+
+    TRACE("SUCCESS Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1wrapDispatch");
+    return JNI_TRUE;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_mac_LowLevelSaf
+ * Method:    _wrapFunction
+ * Signature: (Ljava/lang/String;Lcom/google/gwt/dev/shell/mac/LowLevelSaf/DispatchMethod;[I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1wrapFunction
+  (JNIEnv* env, jclass, jstring name, jobject dispMeth, jintArray rval) {
+    TRACE("ENTER Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1wrapFunction");
+
+    jobject dispMethRef = env->NewGlobalRef(dispMeth);
+    if (!dispMethRef || env->ExceptionCheck())
+        return JNI_FALSE;
+  
+  JStringWrap jname(env, name);
+  if (!jname.jstr())
+    return JNI_FALSE;
+  
+  FuncWrapper* wrapper = new FuncWrapper(UString((const UChar*)jname.jstr(), jname.length()), dispMethRef);
+  /*
+   * TODO / LEAK / HACK: We will be persisting these objects on the java side,
+   * so in order to keep the JS GC from collecting our objects when they are
+   * away, we need to add them to the protect list. This should be refactored
+   * out in favor of better memory mgmt scheme.
+   */
+  gcProtectNullTolerant(wrapper);
+    env->SetIntArrayRegion(rval, 0, 1, (jint*)&wrapper);
+    if (env->ExceptionCheck())
+        return JNI_FALSE;
+
+    TRACE("SUCCESS Java_com_google_gwt_dev_shell_mac_LowLevelSaf__1wrapFunction");
+    return JNI_TRUE;
+}
+
+#ifdef FILETRACE
+FILE* gout = 0;
+void filetrace(const char* s)
+{
+    fprintf(gout, s);
+    fprintf(gout, "\n");
+    fflush(gout);
+}
+#endif // FILETRACE
+
+#ifdef JAVATRACE
+jmethodID gTraceMethod = 0;
+void javatrace(const char* s)
+{
+    if (!gEnv->ExceptionCheck())
+    {
+        jstring out = gEnv->NewStringUTF(s);
+        if (!gEnv->ExceptionCheck())
+            gEnv->CallStaticVoidMethod(gClass, gTraceMethod, out);
+        else
+            gEnv->ExceptionClear();
+    }
+}
+#endif // JAVATRACE
+
diff --git a/jni/mac/gwt-webkit.h b/jni/mac/gwt-webkit.h
new file mode 100644
index 0000000..88db9f7
--- /dev/null
+++ b/jni/mac/gwt-webkit.h
@@ -0,0 +1,41 @@
+// Copyright 2005 Google Inc.
+// All Rights Reserved.
+
+#ifndef GWT_WEBKIT_H
+#define GWT_WEBKIT_H
+
+#include <jni.h>
+#include "JStringWrap.h"
+
+extern JNIEnv* gEnv;
+extern jclass gClass;
+extern jclass gDispObjCls;
+extern jclass gDispMethCls;
+extern jmethodID gSetFieldMeth;
+extern jmethodID gGetFieldMeth;
+extern jmethodID gInvokeMeth;
+extern jmethodID gToStringMeth;
+
+//#define FILETRACE
+//#define JAVATRACE
+#if defined(FILETRACE) && defined(JAVATRACE)
+#define TRACE(s) filetrace(s),javatrace(s)
+#elif defined(FILETRACE)
+#define TRACE(s) filetrace(s)
+#elif defined(JAVATRACE)
+#define TRACE(s) javatrace(s)
+#else
+#define TRACE(s) ((void)0)
+#endif
+
+#ifdef FILETRACE
+extern FILE* gout;
+void filetrace(const char* s);
+#endif // FILETRACE
+
+#ifdef JAVATRACE
+extern jmethodID gTraceMethod;
+void javatrace(const char* s);
+#endif // JAVATRACE
+
+#endif
diff --git a/jni/mac/prebuilt/libgwt-ll.jnilib b/jni/mac/prebuilt/libgwt-ll.jnilib
new file mode 100755
index 0000000..2d036c6
--- /dev/null
+++ b/jni/mac/prebuilt/libgwt-ll.jnilib
Binary files differ
diff --git a/jni/mac/prebuilt/libgwt-webkit.jnilib b/jni/mac/prebuilt/libgwt-webkit.jnilib
new file mode 100755
index 0000000..0fdd5b4
--- /dev/null
+++ b/jni/mac/prebuilt/libgwt-webkit.jnilib
Binary files differ