update per review comments.
authorDan Witte <dwitte@mozilla.com>
Wed, 23 Sep 2009 10:57:22 -0700
changeset 33000 62d7498066ea59ae74c4f4fee0a59333d79a817a
parent 32999 2a88b4c3eb911db69f2043cfdaf04c60ae5b22b1
child 33001 eb4e7e25a9884510d8eeb01d55d04ced1f754208
child 33003 5cdeb73fdcca7b7dd3136f658e963c2dbc29bb8b
push idunknown
push userunknown
push dateunknown
milestone1.9.3a1pre
update per review comments.
js/ctypes/Function.cpp
js/ctypes/Function.h
js/ctypes/Library.cpp
js/ctypes/Library.h
js/ctypes/Makefile.in
js/ctypes/Module.cpp
js/ctypes/ctypes.jsm
js/ctypes/nsIForeignLibrary.idl
js/ctypes/nsINativeTypes.idl
js/ctypes/nsNativeMethod.cpp
js/ctypes/nsNativeMethod.h
js/ctypes/nsNativeModule.cpp
js/ctypes/nsNativeTypes.cpp
js/ctypes/nsNativeTypes.h
js/ctypes/tests/jsctypes-test.cpp
js/ctypes/tests/jsctypes-test.h
js/ctypes/tests/unit/test_jsctypes.js.in
new file mode 100644
--- /dev/null
+++ b/js/ctypes/Function.cpp
@@ -0,0 +1,593 @@
+/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is js-ctypes.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation <http://www.mozilla.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
+ *  Fredrik Larsson <nossralf@gmail.com>
+ *  Dan Witte <dwitte@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "Function.h"
+#include "nsComponentManagerUtils.h"
+#include "nsServiceManagerUtils.h"
+#include "nsIXPConnect.h"
+#include "nsCRT.h"
+
+namespace mozilla {
+namespace ctypes {
+
+/*******************************************************************************
+** Static helpers
+*******************************************************************************/
+
+template<class IntegerType>
+static bool
+jsvalToIntStrict(jsval aValue, IntegerType *aResult)
+{
+  if (JSVAL_IS_INT(aValue)) {
+    jsint i = JSVAL_TO_INT(aValue);
+    *aResult = IntegerType(i);
+
+    // Make sure the integer fits in the alotted precision, and has the right sign.
+    return jsint(*aResult) == i &&
+           (i < 0) == (*aResult < 0);
+  }
+  if (JSVAL_IS_DOUBLE(aValue)) {
+    jsdouble d = *JSVAL_TO_DOUBLE(aValue);
+    *aResult = IntegerType(d);
+
+    // Don't silently lose bits here -- check that aValue really is an
+    // integer value, and has the right sign.
+    return jsdouble(*aResult) == d &&
+           (d < 0) == (*aResult < 0);
+  }
+  if (JSVAL_IS_BOOLEAN(aValue)) {
+    // Implicitly promote boolean values to 0 or 1, like C.
+    *aResult = JSVAL_TO_BOOLEAN(aValue);
+    NS_ASSERTION(*aResult == 0 || *aResult == 1, "invalid boolean");
+    return true;
+  }
+  // Don't silently convert null to an integer. It's probably a mistake.
+  return false;
+}
+
+static bool
+jsvalToDoubleStrict(jsval aValue, jsdouble *dp)
+{
+  // Don't silently convert true to 1.0 or false to 0.0, even though C/C++
+  // does it. It's likely to be a mistake.
+  if (JSVAL_IS_INT(aValue)) {
+    *dp = JSVAL_TO_INT(aValue);
+    return true;
+  }
+  if (JSVAL_IS_DOUBLE(aValue)) {
+    *dp = *JSVAL_TO_DOUBLE(aValue);
+    return true;
+  }
+  return false;
+}
+
+static nsresult
+TypeError(JSContext *cx, const char *message)
+{
+  JS_ReportError(cx, "%s", message);
+  return NS_ERROR_FAILURE;
+}
+
+static nsresult
+GetABI(PRUint16 aCallType, ffi_abi& aResult)
+{
+  // determine the ABI from the subset of those available on the
+  // given platform. nsIForeignLibrary::DEFAULT specifies the default
+  // C calling convention (cdecl) on each platform.
+  switch (aCallType) {
+  case nsIForeignLibrary::DEFAULT:
+    aResult = FFI_DEFAULT_ABI;
+    return NS_OK;
+#if defined(XP_WIN32)
+  case nsIForeignLibrary::STDCALL:
+    aResult = FFI_STDCALL;
+    return NS_OK;
+#endif
+  default:
+    return NS_ERROR_INVALID_ARG;
+  }
+}
+
+static nsresult
+PrepareType(JSContext* aContext, jsval aType, Type& aResult)
+{
+  // for now, the only types we accept are integer values.
+  if (!JSVAL_IS_INT(aType)) {
+    JS_ReportError(aContext, "Invalid type specification");
+    return NS_ERROR_FAILURE;
+  }
+
+  PRInt32 type = JSVAL_TO_INT(aType);
+
+  switch (type) {
+  case nsIForeignLibrary::VOID:
+    aResult.mFFIType = ffi_type_void;
+    break;
+  case nsIForeignLibrary::INT8:
+    aResult.mFFIType = ffi_type_sint8;
+    break;
+  case nsIForeignLibrary::INT16:
+    aResult.mFFIType = ffi_type_sint16;
+    break;
+  case nsIForeignLibrary::INT32:
+    aResult.mFFIType = ffi_type_sint32;
+    break;
+  case nsIForeignLibrary::INT64:
+    aResult.mFFIType = ffi_type_sint64;
+    break;
+  case nsIForeignLibrary::BOOL:
+  case nsIForeignLibrary::UINT8:
+    aResult.mFFIType = ffi_type_uint8;
+    break;
+  case nsIForeignLibrary::UINT16:
+    aResult.mFFIType = ffi_type_uint16;
+    break;
+  case nsIForeignLibrary::UINT32:
+    aResult.mFFIType = ffi_type_uint32;
+    break;
+  case nsIForeignLibrary::UINT64:
+    aResult.mFFIType = ffi_type_uint64;
+    break;
+  case nsIForeignLibrary::FLOAT:
+    aResult.mFFIType = ffi_type_float;
+    break;
+  case nsIForeignLibrary::DOUBLE:
+    aResult.mFFIType = ffi_type_double;
+    break;
+  case nsIForeignLibrary::STRING:
+  case nsIForeignLibrary::USTRING:
+    aResult.mFFIType = ffi_type_pointer;
+    break;
+  default:
+    JS_ReportError(aContext, "Invalid type specification");
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+
+  aResult.mType = type;
+
+  return NS_OK;
+}
+
+static nsresult
+PrepareValue(JSContext* aContext, const Type& aType, jsval aValue, Value& aResult)
+{
+  jsdouble d;
+
+  switch (aType.mType) {
+  case nsIForeignLibrary::BOOL:
+    // Do not implicitly lose bits, but allow the values 0, 1, and -0.
+    // Programs can convert explicitly, if needed, using `Boolean(v)` or `!!v`.
+    if (!jsvalToIntStrict(aValue, &aResult.mValue.mUint8) ||
+        aResult.mValue.mUint8 > 1)
+      return TypeError(aContext, "Expected boolean value");
+
+    aResult.mData = &aResult.mValue.mUint8;
+    break;
+  case nsIForeignLibrary::INT8:
+    // Do not implicitly lose bits.
+    if (!jsvalToIntStrict(aValue, &aResult.mValue.mInt8))
+      return TypeError(aContext, "Expected int8 value");
+
+    aResult.mData = &aResult.mValue.mInt8;
+    break;
+  case nsIForeignLibrary::INT16:
+    // Do not implicitly lose bits.
+    if (!jsvalToIntStrict(aValue, &aResult.mValue.mInt16))
+      return TypeError(aContext, "Expected int16 value");
+
+    aResult.mData = &aResult.mValue.mInt16;
+    break;
+  case nsIForeignLibrary::INT32:
+    // Do not implicitly lose bits.
+    if (!jsvalToIntStrict(aValue, &aResult.mValue.mInt32))
+      return TypeError(aContext, "Expected int32 value");
+
+    aResult.mData = &aResult.mValue.mInt32;
+  case nsIForeignLibrary::INT64:
+    // Do not implicitly lose bits.
+    if (!jsvalToIntStrict(aValue, &aResult.mValue.mInt64))
+      return TypeError(aContext, "Expected int64 value");
+
+    aResult.mData = &aResult.mValue.mInt64;
+    break;
+  case nsIForeignLibrary::UINT8:
+    // Do not implicitly lose bits.
+    if (!jsvalToIntStrict(aValue, &aResult.mValue.mUint8))
+      return TypeError(aContext, "Expected uint8 value");
+
+    aResult.mData = &aResult.mValue.mUint8;
+    break;
+  case nsIForeignLibrary::UINT16:
+    // Do not implicitly lose bits.
+    if (!jsvalToIntStrict(aValue, &aResult.mValue.mUint16))
+      return TypeError(aContext, "Expected uint16 value");
+
+    aResult.mData = &aResult.mValue.mUint16;
+    break;
+  case nsIForeignLibrary::UINT32:
+    // Do not implicitly lose bits.
+    if (!jsvalToIntStrict(aValue, &aResult.mValue.mUint32))
+      return TypeError(aContext, "Expected uint32 value");
+
+    aResult.mData = &aResult.mValue.mUint32;
+  case nsIForeignLibrary::UINT64:
+    // Do not implicitly lose bits.
+    if (!jsvalToIntStrict(aValue, &aResult.mValue.mUint64))
+      return TypeError(aContext, "Expected uint64 value");
+
+    aResult.mData = &aResult.mValue.mUint64;
+    break;
+  case nsIForeignLibrary::FLOAT:
+    if (!jsvalToDoubleStrict(aValue, &d))
+      return TypeError(aContext, "Expected number");
+
+    // The following cast silently throws away some bits, but there's
+    // no good way around it. Sternly requiring that the 64-bit double
+    // argument be exactly representable as a 32-bit float is
+    // unrealistic: it would allow 1/2 to pass but not 1/3.
+    aResult.mValue.mFloat = float(d);
+    aResult.mData = &aResult.mValue.mFloat;
+    break;
+  case nsIForeignLibrary::DOUBLE:
+    if (!jsvalToDoubleStrict(aValue, &d))
+      return TypeError(aContext, "Expected number");
+
+    aResult.mValue.mDouble = d;
+    aResult.mData = &aResult.mValue.mDouble;
+    break;
+  case nsIForeignLibrary::STRING:
+    if (JSVAL_IS_NULL(aValue)) {
+      // Allow passing a null pointer.
+      aResult.mValue.mPointer = nsnull;
+    } else if (JSVAL_IS_STRING(aValue)) {
+      aResult.mValue.mPointer = JS_GetStringBytes(JSVAL_TO_STRING(aValue));
+    } else {
+      // Don't implicitly convert to string. Users can implicitly convert
+      // with `String(x)` or `""+x`.
+      return TypeError(aContext, "Expected string");
+    }
+
+    aResult.mData = &aResult.mValue.mPointer;
+    break;
+  case nsIForeignLibrary::USTRING:
+    if (JSVAL_IS_NULL(aValue)) {
+      // Allow passing a null pointer.
+      aResult.mValue.mPointer = nsnull;
+    } else if (JSVAL_IS_STRING(aValue)) {
+      aResult.mValue.mPointer = JS_GetStringChars(JSVAL_TO_STRING(aValue));
+    } else {
+      // Don't implicitly convert to string. Users can implicitly convert
+      // with `String(x)` or `""+x`.
+      return TypeError(aContext, "Expected string");
+    }
+
+    aResult.mData = &aResult.mValue.mPointer;
+    break;
+  default:
+    NS_NOTREACHED("invalid type");
+    return NS_ERROR_FAILURE;
+  }
+
+  return NS_OK;
+}
+
+static void
+PrepareReturnValue(const Type& aType, Value& aResult)
+{
+  switch (aType.mType) {
+  case nsIForeignLibrary::VOID:
+    aResult.mData = nsnull;
+    break;
+  case nsIForeignLibrary::INT8:
+    aResult.mData = &aResult.mValue.mInt8;
+    break;
+  case nsIForeignLibrary::INT16:
+    aResult.mData = &aResult.mValue.mInt16;
+    break;
+  case nsIForeignLibrary::INT32:
+    aResult.mData = &aResult.mValue.mInt32;
+    break;
+  case nsIForeignLibrary::INT64:
+    aResult.mData = &aResult.mValue.mInt64;
+    break;
+  case nsIForeignLibrary::BOOL:
+  case nsIForeignLibrary::UINT8:
+    aResult.mData = &aResult.mValue.mUint8;
+    break;
+  case nsIForeignLibrary::UINT16:
+    aResult.mData = &aResult.mValue.mUint16;
+    break;
+  case nsIForeignLibrary::UINT32:
+    aResult.mData = &aResult.mValue.mUint32;
+    break;
+  case nsIForeignLibrary::UINT64:
+    aResult.mData = &aResult.mValue.mUint64;
+    break;
+  case nsIForeignLibrary::FLOAT:
+    aResult.mData = &aResult.mValue.mFloat;
+    break;
+  case nsIForeignLibrary::DOUBLE:
+    aResult.mData = &aResult.mValue.mDouble;
+    break;
+  case nsIForeignLibrary::STRING:
+  case nsIForeignLibrary::USTRING:
+    aResult.mData = &aResult.mValue.mPointer;
+    break;
+  default:
+    NS_NOTREACHED("invalid type");
+    break;
+  }
+}
+
+static nsresult
+ConvertReturnValue(JSContext* aContext,
+                   const Type& aResultType,
+                   const Value& aResultValue,
+                   jsval* aValue)
+{
+  switch (aResultType.mType) {
+  case nsIForeignLibrary::VOID:
+    *aValue = JSVAL_VOID;
+    break;
+  case nsIForeignLibrary::BOOL:
+    *aValue = aResultValue.mValue.mUint8 ? JSVAL_TRUE : JSVAL_FALSE;
+    break;
+  case nsIForeignLibrary::INT8:
+    *aValue = INT_TO_JSVAL(aResultValue.mValue.mInt8);
+    break;
+  case nsIForeignLibrary::INT16:
+    *aValue = INT_TO_JSVAL(aResultValue.mValue.mInt16);
+    break;
+  case nsIForeignLibrary::INT32:
+    if (!JS_NewNumberValue(aContext, jsdouble(aResultValue.mValue.mInt32), aValue))
+      return NS_ERROR_OUT_OF_MEMORY;
+    break;
+  case nsIForeignLibrary::INT64:
+    // Implicit conversion with loss of bits.  :-[
+    if (!JS_NewNumberValue(aContext, jsdouble(aResultValue.mValue.mInt64), aValue))
+      return NS_ERROR_OUT_OF_MEMORY;
+    break;
+  case nsIForeignLibrary::UINT8:
+    *aValue = INT_TO_JSVAL(aResultValue.mValue.mUint8);
+    break;
+  case nsIForeignLibrary::UINT16:
+    *aValue = INT_TO_JSVAL(aResultValue.mValue.mUint16);
+    break;
+  case nsIForeignLibrary::UINT32:
+    if (!JS_NewNumberValue(aContext, jsdouble(aResultValue.mValue.mUint32), aValue))
+      return NS_ERROR_OUT_OF_MEMORY;
+    break;
+  case nsIForeignLibrary::UINT64:
+    // Implicit conversion with loss of bits.  :-[
+    if (!JS_NewNumberValue(aContext, jsdouble(aResultValue.mValue.mUint64), aValue))
+      return NS_ERROR_OUT_OF_MEMORY;
+    break;
+  case nsIForeignLibrary::FLOAT:
+    if (!JS_NewNumberValue(aContext, jsdouble(aResultValue.mValue.mFloat), aValue))
+      return NS_ERROR_OUT_OF_MEMORY;
+    break;
+  case nsIForeignLibrary::DOUBLE:
+    if (!JS_NewNumberValue(aContext, jsdouble(aResultValue.mValue.mDouble), aValue))
+      return NS_ERROR_OUT_OF_MEMORY;
+    break;
+  case nsIForeignLibrary::STRING: {
+    if (!aResultValue.mValue.mPointer) {
+      // Allow returning a null pointer.
+      *aValue = JSVAL_NULL;
+    } else {
+      JSString *jsstring = JS_NewStringCopyZ(aContext,
+                             reinterpret_cast<const char*>(aResultValue.mValue.mPointer));
+      if (!jsstring)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+      *aValue = STRING_TO_JSVAL(jsstring);
+    }
+    break;
+  }
+  case nsIForeignLibrary::USTRING: {
+    if (!aResultValue.mValue.mPointer) {
+      // Allow returning a null pointer.
+      *aValue = JSVAL_NULL;
+    } else {
+      JSString *jsstring = JS_NewUCStringCopyZ(aContext,
+                             reinterpret_cast<const jschar*>(aResultValue.mValue.mPointer));
+      if (!jsstring)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+      *aValue = STRING_TO_JSVAL(jsstring);
+    }
+    break;
+  }
+  default:
+    NS_NOTREACHED("invalid type");
+    return NS_ERROR_FAILURE;
+  }
+
+  return NS_OK;
+}
+
+/*******************************************************************************
+** Function
+*******************************************************************************/
+
+NS_IMPL_ISUPPORTS1(Function, nsIXPCScriptable)
+
+Function::Function()
+  : mFunc(nsnull)
+{
+}
+
+Function::~Function()
+{
+}
+
+nsresult
+Function::Init(JSContext* aContext,
+               Library* aLibrary,
+               PRFuncPtr aFunc,
+               PRUint16 aCallType,
+               jsval aResultType,
+               const nsTArray<jsval>& aArgTypes)
+{
+  nsresult rv;
+
+  mLibrary = aLibrary;
+  mFunc = aFunc;
+
+  // determine the ABI
+  rv = GetABI(aCallType, mCallType);
+  if (NS_FAILED(rv)) {
+    JS_ReportError(aContext, "Invalid ABI specification");
+    return rv;
+  }
+
+  // prepare the result type
+  rv = PrepareType(aContext, aResultType, mResultType);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // prepare the argument types
+  for (PRUint32 i = 0; i < aArgTypes.Length(); ++i) {
+    rv = PrepareType(aContext, aArgTypes[i], *mArgTypes.AppendElement());
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    // disallow void argument types
+    if (mArgTypes[i].mType == nsIForeignLibrary::VOID)
+      return TypeError(aContext, "Cannot have void argument type");
+
+    // ffi_prep_cif requires an array of ffi_types; prepare it separately.
+    mFFITypes.AppendElement(&mArgTypes[i].mFFIType);
+  }
+
+  ffi_status status = ffi_prep_cif(&mCIF, mCallType, mFFITypes.Length(),
+                                   &mResultType.mFFIType, mFFITypes.Elements());
+  switch (status) {
+  case FFI_OK:
+    return NS_OK;
+  case FFI_BAD_ABI:
+    JS_ReportError(aContext, "Invalid ABI specification");
+    return NS_ERROR_INVALID_ARG;
+  case FFI_BAD_TYPEDEF:
+    JS_ReportError(aContext, "Invalid type specification");
+    return NS_ERROR_INVALID_ARG;
+  default:
+    JS_ReportError(aContext, "Unknown libffi error");
+    return NS_ERROR_FAILURE;
+  }
+}
+
+PRBool
+Function::Execute(JSContext* aContext, PRUint32 aArgc, jsval* aArgv, jsval* aValue)
+{
+  nsresult rv;
+
+  // prepare the values for each argument
+  nsAutoTArray<Value, 16> values;
+  for (PRUint32 i = 0; i < mArgTypes.Length(); ++i) {
+    rv = PrepareValue(aContext, mArgTypes[i], aArgv[i], *values.AppendElement());
+    if (NS_FAILED(rv)) return PR_FALSE;
+  }
+
+  // create an array of pointers to each value, for passing to ffi_call
+  nsAutoTArray<void*, 16> ffiValues;
+  for (PRUint32 i = 0; i < mArgTypes.Length(); ++i) {
+    ffiValues.AppendElement(values[i].mData);
+  }
+
+  // initialize a pointer to an appropriate location, for storing the result
+  Value resultValue;
+  PrepareReturnValue(mResultType, resultValue);
+
+  // suspend the request before we call into the function, since the call
+  // may block or otherwise take a long time to return.
+  jsrefcount rc = JS_SuspendRequest(aContext);
+
+  ffi_call(&mCIF, mFunc, resultValue.mData, ffiValues.Elements());
+
+  JS_ResumeRequest(aContext, rc);
+
+  // prepare a JS object from the result
+  rv = ConvertReturnValue(aContext, mResultType, resultValue, aValue);
+  if (NS_FAILED(rv)) return PR_FALSE;
+
+  return PR_TRUE;
+}
+
+/*******************************************************************************
+** nsIXPCScriptable implementation
+*******************************************************************************/
+
+#define XPC_MAP_CLASSNAME Function
+#define XPC_MAP_QUOTED_CLASSNAME "Function"
+#define XPC_MAP_WANT_CALL
+#define XPC_MAP_FLAGS nsIXPCScriptable::WANT_CALL
+
+#include "xpc_map_end.h"
+
+NS_IMETHODIMP
+Function::Call(nsIXPConnectWrappedNative* wrapper,
+               JSContext* cx,
+               JSObject* obj, 
+               PRUint32 argc, 
+               jsval* argv, 
+               jsval* vp, 
+               PRBool* _retval)
+{
+  if (!mLibrary->IsOpen()) {
+    JS_ReportError(cx, "Library is not open");
+    *_retval = PR_FALSE;
+    return NS_ERROR_FAILURE;
+  }
+
+  if (argc != mArgTypes.Length()) {
+    JS_ReportError(cx, "Number of arguments does not match declaration");
+    *_retval = PR_FALSE;
+    return NS_ERROR_FAILURE;
+  }
+
+  *_retval = Execute(cx, argc, argv, vp);
+  if (!*_retval)
+    return NS_ERROR_FAILURE;
+
+  return NS_OK;
+}
+
+}
+}
+
new file mode 100644
--- /dev/null
+++ b/js/ctypes/Function.h
@@ -0,0 +1,111 @@
+/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is js-ctypes.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation <http://www.mozilla.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
+ *  Dan Witte <dwitte@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef FUNCTION_H
+#define FUNCTION_H
+
+#include "Library.h"
+#include "nsIXPCScriptable.h"
+#include "nsString.h"
+#include "nsTArray.h"
+#include "nsAutoPtr.h"
+#include "prlink.h"
+#include "jsapi.h"
+#include "ffi.h"
+
+namespace mozilla {
+namespace ctypes {
+
+struct Type
+{
+  ffi_type mFFIType;
+  PRUint16 mType;
+};
+
+struct Value
+{
+  void* mData;
+  union {
+    int8_t   mInt8;
+    int16_t  mInt16;
+    int32_t  mInt32;
+    int64_t  mInt64;
+    uint8_t  mUint8;
+    uint16_t mUint16;
+    uint32_t mUint32;
+    uint64_t mUint64;
+    float    mFloat;
+    double   mDouble;
+    void*    mPointer;
+  } mValue;
+};
+
+class Function : public nsIXPCScriptable
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIXPCSCRIPTABLE
+
+  Function();
+
+  nsresult Init(JSContext* aContext, Library* aLibrary, PRFuncPtr aFunc, PRUint16 aCallType, jsval aResultType, const nsTArray<jsval>& aArgTypes);
+
+private:
+  ~Function();
+
+  PRBool Execute(JSContext* aContext, PRUint32 aArgc, jsval* aArgv, jsval* aValue);
+
+protected:
+  // reference to the library our function is in
+  nsRefPtr<Library> mLibrary;
+
+  PRFuncPtr mFunc;
+
+  ffi_abi mCallType;
+  Type mResultType;
+  nsAutoTArray<Type, 16> mArgTypes;
+  nsAutoTArray<ffi_type*, 16> mFFITypes;
+
+  ffi_cif mCIF;
+};
+
+}
+}
+
+#endif
new file mode 100644
--- /dev/null
+++ b/js/ctypes/Library.cpp
@@ -0,0 +1,171 @@
+/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is js-ctypes.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation <http://www.mozilla.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
+ *  Fredrik Larsson <nossralf@gmail.com>
+ *  Dan Witte <dwitte@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "Library.h"
+#include "Function.h"
+#include "nsServiceManagerUtils.h"
+#include "nsAutoPtr.h"
+#include "nsILocalFile.h"
+#include "prlink.h"
+#include "jsapi.h"
+
+namespace mozilla {
+namespace ctypes {
+
+static inline nsresult
+jsvalToUint16(JSContext* aContext, jsval aVal, PRUint16& aResult)
+{
+  if (JSVAL_IS_INT(aVal)) {
+    PRUint32 i = JSVAL_TO_INT(aVal);
+    if (i <= PR_UINT16_MAX) {
+      aResult = i;
+      return NS_OK;
+    }
+  }
+
+  JS_ReportError(aContext, "Parameter must be an integer");
+  return NS_ERROR_INVALID_ARG;
+}
+
+static inline nsresult
+jsvalToCString(JSContext* aContext, jsval aVal, const char*& aResult)
+{
+  if (JSVAL_IS_STRING(aVal)) {
+    aResult = JS_GetStringBytes(JSVAL_TO_STRING(aVal));
+    return NS_OK;
+  }
+
+  JS_ReportError(aContext, "Parameter must be a string");
+  return NS_ERROR_INVALID_ARG;
+}
+
+NS_IMPL_ISUPPORTS1(Library, nsIForeignLibrary)
+
+Library::Library()
+  : mLibrary(nsnull)
+{
+}
+
+Library::~Library()
+{
+  Close();
+}
+
+NS_IMETHODIMP
+Library::Open(nsILocalFile* aFile)
+{
+  NS_ENSURE_ARG(aFile);
+  NS_ENSURE_TRUE(!mLibrary, NS_ERROR_ALREADY_INITIALIZED);
+
+  return aFile->Load(&mLibrary);
+}
+
+NS_IMETHODIMP
+Library::Close()
+{
+  if (mLibrary) {
+    PR_UnloadLibrary(mLibrary);
+    mLibrary = nsnull;
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+Library::Declare(nsISupports** aResult)
+{
+  NS_ENSURE_ARG_POINTER(aResult);
+  NS_ENSURE_TRUE(mLibrary, NS_ERROR_NOT_INITIALIZED);
+
+  nsresult rv;
+
+  nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
+
+  nsAXPCNativeCallContext* ncc;
+  rv = xpc->GetCurrentNativeCallContext(&ncc);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  JSContext *ctx;
+  rv = ncc->GetJSContext(&ctx);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  JSAutoRequest ar(ctx);
+
+  PRUint32 argc;
+  jsval *argv;
+  ncc->GetArgc(&argc);
+  ncc->GetArgvPtr(&argv);
+
+  // we always need at least a method name, a call type and a return type
+  if (argc < 3) {
+    JS_ReportError(ctx, "Insufficient number of arguments");
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  const char* name;
+  rv = jsvalToCString(ctx, argv[0], name);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRUint16 callType;
+  rv = jsvalToUint16(ctx, argv[1], callType);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsAutoTArray<jsval, 16> argTypes;
+  for (PRUint32 i = 3; i < argc; ++i) {
+    argTypes.AppendElement(argv[i]);
+  }
+
+  PRFuncPtr func = PR_FindFunctionSymbol(mLibrary, name);
+  if (!func) {
+    JS_ReportError(ctx, "Couldn't find function symbol in library");
+    return NS_ERROR_FAILURE;
+  }
+
+  nsRefPtr<Function> call = new Function;
+  rv = call->Init(ctx, this, func, callType, argv[2], argTypes);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  call.forget(aResult);
+  return rv;
+}
+
+}
+}
+
new file mode 100644
--- /dev/null
+++ b/js/ctypes/Library.h
@@ -0,0 +1,75 @@
+/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is js-ctypes.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation <http://www.mozilla.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
+ *  Dan Witte <dwitte@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef LIBRARY_H
+#define LIBRARY_H
+
+#include "nsIForeignLibrary.h"
+
+#define FOREIGNLIBRARY_CONTRACTID \
+  "@mozilla.org/jsctypes;1"
+
+#define FOREIGNLIBRARY_CID \
+{ 0xc797702, 0x1c60, 0x4051, { 0x9d, 0xd7, 0x4d, 0x74, 0x5, 0x60, 0x56, 0x42 } }
+
+struct PRLibrary;
+
+namespace mozilla {
+namespace ctypes {
+
+class Library : public nsIForeignLibrary
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIFOREIGNLIBRARY
+
+  Library();
+
+  PRBool IsOpen() { return mLibrary != nsnull; }
+
+private:
+  ~Library();
+
+  PRLibrary* mLibrary;
+};
+
+}
+}
+
+#endif
--- a/js/ctypes/Makefile.in
+++ b/js/ctypes/Makefile.in
@@ -49,30 +49,30 @@ MODULE_NAME = jsctypes
 GRE_MODULE = 1
 
 # package the interface whether ctypes is enabled or not.
 EXTRA_JS_MODULES = \
     ctypes.jsm \
     $(NULL)
 
 XPIDLSRCS = \
-    nsINativeTypes.idl \
+    nsIForeignLibrary.idl \
     $(NULL)
 
 ifdef BUILD_CTYPES
 
 LIBRARY_NAME = jsctypes
 LIBXUL_LIBRARY = 1
 EXPORT_LIBRARY = 1
 IS_COMPONENT = 1
 
 CPPSRCS = \
-    nsNativeMethod.cpp \
-    nsNativeTypes.cpp \
-    nsNativeModule.cpp \
+    Function.cpp \
+    Library.cpp \
+    Module.cpp \
     $(NULL)
 
 ifdef _MSC_VER
 
 # build and link sources directly from libffi_msvc
 VPATH += \
     $(srcdir)/libffi_msvc \
     $(NULL)
new file mode 100644
--- /dev/null
+++ b/js/ctypes/Module.cpp
@@ -0,0 +1,62 @@
+/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is js-ctypes.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation <http://www.mozilla.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
+ *  Dan Witte <dwitte@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIGenericFactory.h"
+#include "Library.h"
+
+namespace mozilla {
+namespace ctypes {
+
+NS_GENERIC_FACTORY_CONSTRUCTOR(Library)
+
+}
+}
+
+static nsModuleComponentInfo components[] =
+{
+  {
+    "jsctypes",
+    FOREIGNLIBRARY_CID,
+    FOREIGNLIBRARY_CONTRACTID,
+    mozilla::ctypes::LibraryConstructor,
+  }
+};
+
+NS_IMPL_NSGETMODULE(jsctypes, components)
+
--- a/js/ctypes/ctypes.jsm
+++ b/js/ctypes/ctypes.jsm
@@ -37,21 +37,21 @@
  * ***** END LICENSE BLOCK ***** */
 
 let EXPORTED_SYMBOLS = [ "ctypes" ];
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 let ctypes = {
-  types: Ci.nsINativeTypes,
+  types: Ci.nsIForeignLibrary,
 
   open: function(name) {
     let library = Cc["@mozilla.org/jsctypes;1"]
-                  .createInstance(Ci.nsINativeTypes);
+                  .createInstance(Ci.nsIForeignLibrary);
 
     let file;
     if (name instanceof Ci.nsILocalFile) {
       file = name;
     } else {
       file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
       file.initWithPath(name);
     }
new file mode 100644
--- /dev/null
+++ b/js/ctypes/nsIForeignLibrary.idl
@@ -0,0 +1,108 @@
+/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is js-ctypes.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation <http://www.mozilla.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
+ *  Dan Witte <dwitte@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.idl"
+
+interface nsILocalFile;
+
+/**
+ * Interface that wraps a dynamic library and can create
+ * callable 'method' objects from exportable functions in the library
+ */
+[scriptable, uuid(352a72c1-5b99-451e-a330-c45079d8f087)]
+interface nsIForeignLibrary : nsISupports
+{
+  /**
+   * ABI constants that specify the calling convention to use.
+   * DEFAULT corresponds to the cdecl convention, and in almost all
+   * cases is the correct choice. STDCALL is provided for calling
+   * functions in the Microsoft Win32 API.
+   */
+  const PRUint16 DEFAULT    = 0;    // corresponds to cdecl
+  const PRUint16 STDCALL    = 1;    // for calling Win32 API functions
+
+  /**
+   * Types available for arguments and return values, representing
+   * their C counterparts.
+   */
+  const PRUint16 VOID       = 0;    // Only allowed for return types.
+  const PRUint16 BOOL       = 1;    // _Bool type (assumed 8 bits wide).
+  const PRUint16 INT8       = 2;    // int8_t (signed char) type.
+  const PRUint16 INT16      = 3;    // int16_t (short) type.
+  const PRUint16 INT32      = 4;    // int32_t (int) type.
+  const PRUint16 INT64      = 5;    // int64_t (long long) type.
+  const PRUint16 UINT8      = 6;    // uint8_t (unsigned char) type.
+  const PRUint16 UINT16     = 7;    // uint16_t (unsigned short) type.
+  const PRUint16 UINT32     = 8;    // uint32_t (unsigned int) type.
+  const PRUint16 UINT64     = 9;    // uint64_t (unsigned long long) type.
+  const PRUint16 FLOAT      = 10;   // float type.
+  const PRUint16 DOUBLE     = 11;   // double type.
+  const PRUint16 STRING     = 12;   // C string (char *).
+  const PRUint16 USTRING    = 13;   // 16-bit string (char16_t *).
+
+  /**
+   * Attempts to dynamically load the specified library
+   */
+  void open(in nsILocalFile aFile);
+
+  /**
+   * Unloads the currently loaded library. Any subsequent attempts to call
+   * functions on this interface will fail.
+   */
+  void close();
+
+  /**
+   * Used to specify an exported method from the currently loaded library. Even
+   * though the method appears to take no parameters, it does in fact require
+   * several. It uses some XPCOM/JSAPI magic to extract the parameters.
+   *
+   * declare(in AString aName, in int aABI, in int aReturnType, in int aArgType1, ...)
+   *
+   * The resulting object can then be used to call the underlying
+   * C function like so:
+   *
+   * var retval = nativeMethod(arg1, arg2, ...);
+   *
+   * Arguments will be checked against the types supplied at declaration, and
+   * some attempt to convert values (e.g. boolean true/false to integer 0/1)
+   * will be made. Otherwise, if types do not match, or conversion fails,
+   * an exception will be thrown.
+   */
+  nsISupports declare();
+};
deleted file mode 100644
--- a/js/ctypes/nsINativeTypes.idl
+++ /dev/null
@@ -1,108 +0,0 @@
-/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is js-ctypes.
- *
- * The Initial Developer of the Original Code is
- * The Mozilla Foundation <http://www.mozilla.org/>.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *  Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
- *  Dan Witte <dwitte@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "nsISupports.idl"
-
-interface nsILocalFile;
-
-/**
- * Interface that wraps a dynamic library and can create
- * callable 'method' objects from exportable functions in the library
- */
-[scriptable, uuid(352a72c1-5b99-451e-a330-c45079d8f087)]
-interface nsINativeTypes : nsISupports
-{
-  /**
-   * ABI constants that specify the calling convention to use.
-   * DEFAULT corresponds to the cdecl convention, and in almost all
-   * cases is the correct choice. STDCALL is provided for calling
-   * functions in the Microsoft Win32 API.
-   */
-  const PRUint16 DEFAULT    = 0;    // corresponds to cdecl
-  const PRUint16 STDCALL    = 1;    // for calling Win32 API functions
-
-  /**
-   * Types available for arguments and return values, representing
-   * their C counterparts.
-   */
-  const PRUint16 VOID       = 0;    // Only allowed for return types.
-  const PRUint16 BOOL       = 1;    // _Bool type (assumed 8 bits wide).
-  const PRUint16 INT8       = 2;    // int8_t (signed char) type.
-  const PRUint16 INT16      = 3;    // int16_t (short) type.
-  const PRUint16 INT32      = 4;    // int32_t (int) type.
-  const PRUint16 INT64      = 5;    // int64_t (long long) type.
-  const PRUint16 UINT8      = 6;    // uint8_t (unsigned char) type.
-  const PRUint16 UINT16     = 7;    // uint16_t (unsigned short) type.
-  const PRUint16 UINT32     = 8;    // uint32_t (unsigned int) type.
-  const PRUint16 UINT64     = 9;    // uint64_t (unsigned long long) type.
-  const PRUint16 FLOAT      = 10;   // float type.
-  const PRUint16 DOUBLE     = 11;   // double type.
-  const PRUint16 STRING     = 12;   // C string (char *).
-  const PRUint16 USTRING    = 13;   // 16-bit string (char16_t *).
-
-  /**
-   * Attempts to dynamically load the specified library
-   */
-  void open(in nsILocalFile aFile);
-
-  /**
-   * Unloads the currently loaded library. Any subsequent attempts to call
-   * nsINativeMethod functions will fail.
-   */
-  void close();
-
-  /**
-   * Used to specify an exported method from the currently loaded library. Even
-   * though the method appears to take no parameters, it does in fact require
-   * several. It uses some XPCOM/JSAPI magic to extract the parameters.
-   *
-   * declare(in AString aName, in int aABI, in int aReturnType, in int aArgType1, ...)
-   *
-   * The resulting object can then be used to call the underlying
-   * C function like so:
-   *
-   * var retval = nativeMethod(arg1, arg2, ...);
-   *
-   * Arguments will be checked against the types supplied at declaration, and
-   * some attempt to convert values (e.g. boolean true/false to integer 0/1)
-   * will be made. Otherwise, if types do not match, or conversion fails,
-   * an exception will be thrown.
-   */
-  nsISupports declare();
-};
deleted file mode 100644
--- a/js/ctypes/nsNativeMethod.cpp
+++ /dev/null
@@ -1,586 +0,0 @@
-/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is js-ctypes.
- *
- * The Initial Developer of the Original Code is
- * The Mozilla Foundation <http://www.mozilla.org/>.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *  Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
- *  Dan Witte <dwitte@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "nsNativeMethod.h"
-#include "nsComponentManagerUtils.h"
-#include "nsServiceManagerUtils.h"
-#include "nsIXPConnect.h"
-#include "nsCRT.h"
-
-/*******************************************************************************
-** Static helpers
-*******************************************************************************/
-
-template<class IntegerType>
-static bool
-jsvalToIntStrict(jsval aValue, IntegerType *aResult)
-{
-  if (JSVAL_IS_INT(aValue)) {
-    jsint i = JSVAL_TO_INT(aValue);
-    *aResult = IntegerType(i);
-
-    // Make sure the integer fits in the alotted precision.
-    return jsint(*aResult) == i;
-  }
-  if (JSVAL_IS_DOUBLE(aValue)) {
-    jsdouble d = *JSVAL_TO_DOUBLE(aValue);
-    *aResult = IntegerType(d);
-
-    // Don't silently lose bits here -- check that aValue really is an
-    // integer value.
-    return jsdouble(*aResult) == d;
-  }
-  if (JSVAL_IS_BOOLEAN(aValue)) {
-    // Implicitly promote boolean values to 0 or 1, like C.
-    *aResult = JSVAL_TO_BOOLEAN(aValue);
-    NS_ASSERTION(*aResult == 0 || *aResult == 1, "invalid boolean");
-    return true;
-  }
-  // Don't silently convert null to an integer. It's probably a mistake.
-  return false;
-}
-
-static bool
-jsvalToDoubleStrict(jsval aValue, jsdouble *dp)
-{
-  // Don't silently convert true to 1.0 or false to 0.0, even though C/C++
-  // does it. It's likely to be a mistake.
-  if (JSVAL_IS_INT(aValue)) {
-    *dp = JSVAL_TO_INT(aValue);
-    return true;
-  }
-  if (JSVAL_IS_DOUBLE(aValue)) {
-    *dp = *JSVAL_TO_DOUBLE(aValue);
-    return true;
-  }
-  return false;
-}
-
-static nsresult
-TypeError(JSContext *cx, const char *message)
-{
-  JS_ReportError(cx, message);
-  return NS_ERROR_FAILURE;
-}
-
-static nsresult
-GetABI(PRUint16 aCallType, ffi_abi& aResult)
-{
-  // determine the ABI from the subset of those available on the
-  // given platform. nsINativeTypes::DEFAULT specifies the default
-  // C calling convention (cdecl) on each platform.
-  switch (aCallType) {
-  case nsINativeTypes::DEFAULT:
-    aResult = FFI_DEFAULT_ABI;
-    return NS_OK;
-#if defined(XP_WIN32)
-  case nsINativeTypes::STDCALL:
-    aResult = FFI_STDCALL;
-    return NS_OK;
-#endif
-  default:
-    return NS_ERROR_INVALID_ARG;
-  }
-}
-
-static nsresult
-PrepareType(JSContext* aContext, jsval aType, nsNativeType& aResult)
-{
-  // for now, the only types we accept are integer values.
-  if (!JSVAL_IS_INT(aType)) {
-    JS_ReportError(aContext, "Invalid type specification");
-    return NS_ERROR_FAILURE;
-  }
-
-  PRInt32 type = JSVAL_TO_INT(aType);
-
-  switch (type) {
-  case nsINativeTypes::VOID:
-    aResult.mType = ffi_type_void;
-    break;
-  case nsINativeTypes::INT8:
-    aResult.mType = ffi_type_sint8;
-    break;
-  case nsINativeTypes::INT16:
-    aResult.mType = ffi_type_sint16;
-    break;
-  case nsINativeTypes::INT32:
-    aResult.mType = ffi_type_sint32;
-    break;
-  case nsINativeTypes::INT64:
-    aResult.mType = ffi_type_sint64;
-    break;
-  case nsINativeTypes::BOOL:
-  case nsINativeTypes::UINT8:
-    aResult.mType = ffi_type_uint8;
-    break;
-  case nsINativeTypes::UINT16:
-    aResult.mType = ffi_type_uint16;
-    break;
-  case nsINativeTypes::UINT32:
-    aResult.mType = ffi_type_uint32;
-    break;
-  case nsINativeTypes::UINT64:
-    aResult.mType = ffi_type_uint64;
-    break;
-  case nsINativeTypes::FLOAT:
-    aResult.mType = ffi_type_float;
-    break;
-  case nsINativeTypes::DOUBLE:
-    aResult.mType = ffi_type_double;
-    break;
-  case nsINativeTypes::STRING:
-  case nsINativeTypes::USTRING:
-    aResult.mType = ffi_type_pointer;
-    break;
-  default:
-    JS_ReportError(aContext, "Invalid type specification");
-    return NS_ERROR_NOT_IMPLEMENTED;
-  }
-
-  aResult.mNativeType = type;
-
-  return NS_OK;
-}
-
-static nsresult
-PrepareValue(JSContext* aContext, const nsNativeType& aType, jsval aValue, nsNativeValue& aResult)
-{
-  jsdouble d;
-
-  switch (aType.mNativeType) {
-  case nsINativeTypes::BOOL:
-    // Do not implicitly lose bits, but allow the values 0, 1, and -0.
-    // Programs can convert explicitly, if needed, using `Boolean(v)` or `!!v`.
-    if (!jsvalToIntStrict(aValue, &aResult.mValue.mUint8) ||
-        aResult.mValue.mUint8 > 1)
-      return TypeError(aContext, "Expected boolean value");
-
-    aResult.mData = &aResult.mValue.mUint8;
-    break;
-  case nsINativeTypes::INT8:
-    // Do not implicitly lose bits.
-    if (!jsvalToIntStrict(aValue, &aResult.mValue.mInt8))
-      return TypeError(aContext, "Expected int8 value");
-
-    aResult.mData = &aResult.mValue.mInt8;
-    break;
-  case nsINativeTypes::INT16:
-    // Do not implicitly lose bits.
-    if (!jsvalToIntStrict(aValue, &aResult.mValue.mInt16))
-      return TypeError(aContext, "Expected int16 value");
-
-    aResult.mData = &aResult.mValue.mInt16;
-    break;
-  case nsINativeTypes::INT32:
-    // Do not implicitly lose bits.
-    if (!jsvalToIntStrict(aValue, &aResult.mValue.mInt32))
-      return TypeError(aContext, "Expected int32 value");
-
-    aResult.mData = &aResult.mValue.mInt32;
-  case nsINativeTypes::INT64:
-    // Do not implicitly lose bits.
-    if (!jsvalToIntStrict(aValue, &aResult.mValue.mInt64))
-      return TypeError(aContext, "Expected int64 value");
-
-    aResult.mData = &aResult.mValue.mInt64;
-    break;
-  case nsINativeTypes::UINT8:
-    // Do not implicitly lose bits.
-    if (!jsvalToIntStrict(aValue, &aResult.mValue.mUint8))
-      return TypeError(aContext, "Expected uint8 value");
-
-    aResult.mData = &aResult.mValue.mUint8;
-    break;
-  case nsINativeTypes::UINT16:
-    // Do not implicitly lose bits.
-    if (!jsvalToIntStrict(aValue, &aResult.mValue.mUint16))
-      return TypeError(aContext, "Expected uint16 value");
-
-    aResult.mData = &aResult.mValue.mUint16;
-    break;
-  case nsINativeTypes::UINT32:
-    // Do not implicitly lose bits.
-    if (!jsvalToIntStrict(aValue, &aResult.mValue.mUint32))
-      return TypeError(aContext, "Expected uint32 value");
-
-    aResult.mData = &aResult.mValue.mUint32;
-  case nsINativeTypes::UINT64:
-    // Do not implicitly lose bits.
-    if (!jsvalToIntStrict(aValue, &aResult.mValue.mUint64))
-      return TypeError(aContext, "Expected uint64 value");
-
-    aResult.mData = &aResult.mValue.mUint64;
-    break;
-  case nsINativeTypes::FLOAT:
-    if (!jsvalToDoubleStrict(aValue, &d))
-      return TypeError(aContext, "Expected number");
-
-    // The following cast silently throws away some bits, but there's
-    // no good way around it. Sternly requiring that the 64-bit double
-    // argument be exactly representable as a 32-bit float is
-    // unrealistic: it would allow 1/2 to pass but not 1/3.
-    aResult.mValue.mFloat = float(d);
-    aResult.mData = &aResult.mValue.mFloat;
-    break;
-  case nsINativeTypes::DOUBLE:
-    if (!jsvalToDoubleStrict(aValue, &d))
-      return TypeError(aContext, "Expected number");
-
-    aResult.mValue.mDouble = d;
-    aResult.mData = &aResult.mValue.mDouble;
-    break;
-  case nsINativeTypes::STRING:
-    if (JSVAL_IS_NULL(aValue)) {
-      // Allow passing a null pointer.
-      aResult.mValue.mPointer = nsnull;
-    } else if (JSVAL_IS_STRING(aValue)) {
-      aResult.mValue.mPointer = JS_GetStringBytes(JSVAL_TO_STRING(aValue));
-    } else {
-      // Don't implicitly convert to string. Users can implicitly convert
-      // with `String(x)` or `""+x`.
-      return TypeError(aContext, "Expected string");
-    }
-
-    aResult.mData = &aResult.mValue.mPointer;
-    break;
-  case nsINativeTypes::USTRING:
-    if (JSVAL_IS_NULL(aValue)) {
-      // Allow passing a null pointer.
-      aResult.mValue.mPointer = nsnull;
-    } else if (JSVAL_IS_STRING(aValue)) {
-      aResult.mValue.mPointer = JS_GetStringChars(JSVAL_TO_STRING(aValue));
-    } else {
-      // Don't implicitly convert to string. Users can implicitly convert
-      // with `String(x)` or `""+x`.
-      return TypeError(aContext, "Expected string");
-    }
-
-    aResult.mData = &aResult.mValue.mPointer;
-    break;
-  default:
-    NS_NOTREACHED("invalid type");
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-static void
-PrepareReturnValue(const nsNativeType& aType, nsNativeValue& aResult)
-{
-  switch (aType.mNativeType) {
-  case nsINativeTypes::VOID:
-    aResult.mData = nsnull;
-    break;
-  case nsINativeTypes::INT8:
-    aResult.mData = &aResult.mValue.mInt8;
-    break;
-  case nsINativeTypes::INT16:
-    aResult.mData = &aResult.mValue.mInt16;
-    break;
-  case nsINativeTypes::INT32:
-    aResult.mData = &aResult.mValue.mInt32;
-    break;
-  case nsINativeTypes::INT64:
-    aResult.mData = &aResult.mValue.mInt64;
-    break;
-  case nsINativeTypes::BOOL:
-  case nsINativeTypes::UINT8:
-    aResult.mData = &aResult.mValue.mUint8;
-    break;
-  case nsINativeTypes::UINT16:
-    aResult.mData = &aResult.mValue.mUint16;
-    break;
-  case nsINativeTypes::UINT32:
-    aResult.mData = &aResult.mValue.mUint32;
-    break;
-  case nsINativeTypes::UINT64:
-    aResult.mData = &aResult.mValue.mUint64;
-    break;
-  case nsINativeTypes::FLOAT:
-    aResult.mData = &aResult.mValue.mFloat;
-    break;
-  case nsINativeTypes::DOUBLE:
-    aResult.mData = &aResult.mValue.mDouble;
-    break;
-  case nsINativeTypes::STRING:
-  case nsINativeTypes::USTRING:
-    aResult.mData = &aResult.mValue.mPointer;
-    break;
-  default:
-    NS_NOTREACHED("invalid type");
-    break;
-  }
-}
-
-static nsresult
-ConvertReturnValue(JSContext* aContext,
-                   const nsNativeType& aResultType,
-                   const nsNativeValue& aResultValue,
-                   jsval* aValue)
-{
-  switch (aResultType.mNativeType) {
-  case nsINativeTypes::VOID:
-    *aValue = JSVAL_VOID;
-    break;
-  case nsINativeTypes::BOOL:
-    *aValue = aResultValue.mValue.mUint8 ? JSVAL_TRUE : JSVAL_FALSE;
-    break;
-  case nsINativeTypes::INT8:
-    *aValue = INT_TO_JSVAL(aResultValue.mValue.mInt8);
-    break;
-  case nsINativeTypes::INT16:
-    *aValue = INT_TO_JSVAL(aResultValue.mValue.mInt16);
-    break;
-  case nsINativeTypes::INT32:
-    if (!JS_NewNumberValue(aContext, jsdouble(aResultValue.mValue.mInt32), aValue))
-      return NS_ERROR_OUT_OF_MEMORY;
-    break;
-  case nsINativeTypes::INT64:
-    // Implicit conversion with loss of bits.  :-[
-    if (!JS_NewNumberValue(aContext, jsdouble(aResultValue.mValue.mInt64), aValue))
-      return NS_ERROR_OUT_OF_MEMORY;
-    break;
-  case nsINativeTypes::UINT8:
-    *aValue = INT_TO_JSVAL(aResultValue.mValue.mUint8);
-    break;
-  case nsINativeTypes::UINT16:
-    *aValue = INT_TO_JSVAL(aResultValue.mValue.mUint16);
-    break;
-  case nsINativeTypes::UINT32:
-    if (!JS_NewNumberValue(aContext, jsdouble(aResultValue.mValue.mUint32), aValue))
-      return NS_ERROR_OUT_OF_MEMORY;
-    break;
-  case nsINativeTypes::UINT64:
-    // Implicit conversion with loss of bits.  :-[
-    if (!JS_NewNumberValue(aContext, jsdouble(aResultValue.mValue.mUint64), aValue))
-      return NS_ERROR_OUT_OF_MEMORY;
-    break;
-  case nsINativeTypes::FLOAT:
-    if (!JS_NewNumberValue(aContext, jsdouble(aResultValue.mValue.mFloat), aValue))
-      return NS_ERROR_OUT_OF_MEMORY;
-    break;
-  case nsINativeTypes::DOUBLE:
-    if (!JS_NewNumberValue(aContext, jsdouble(aResultValue.mValue.mDouble), aValue))
-      return NS_ERROR_OUT_OF_MEMORY;
-    break;
-  case nsINativeTypes::STRING: {
-    if (!aResultValue.mValue.mPointer) {
-      // Allow returning a null pointer.
-      *aValue = JSVAL_VOID;
-    } else {
-      JSString *jsstring = JS_NewStringCopyZ(aContext,
-                             reinterpret_cast<const char*>(aResultValue.mValue.mPointer));
-      if (!jsstring)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-      *aValue = STRING_TO_JSVAL(jsstring);
-    }
-    break;
-  }
-  case nsINativeTypes::USTRING: {
-    if (!aResultValue.mValue.mPointer) {
-      // Allow returning a null pointer.
-      *aValue = JSVAL_VOID;
-    } else {
-      JSString *jsstring = JS_NewUCStringCopyZ(aContext,
-                             reinterpret_cast<const jschar*>(aResultValue.mValue.mPointer));
-      if (!jsstring)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-      *aValue = STRING_TO_JSVAL(jsstring);
-    }
-    break;
-  }
-  default:
-    NS_NOTREACHED("invalid type");
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-/*******************************************************************************
-** nsNativeMethod
-*******************************************************************************/
-
-NS_IMPL_ISUPPORTS1(nsNativeMethod, nsIXPCScriptable)
-
-nsNativeMethod::nsNativeMethod()
-  : mFunc(nsnull)
-{
-}
-
-nsNativeMethod::~nsNativeMethod()
-{
-}
-
-nsresult
-nsNativeMethod::Init(JSContext* aContext,
-                     nsNativeTypes* aLibrary,
-                     PRFuncPtr aFunc,
-                     PRUint16 aCallType,
-                     jsval aResultType,
-                     const nsTArray<jsval>& aArgTypes)
-{
-  nsresult rv;
-
-  mLibrary = aLibrary;
-  mFunc = aFunc;
-
-  // determine the ABI
-  rv = GetABI(aCallType, mCallType);
-  if (NS_FAILED(rv)) {
-    JS_ReportError(aContext, "Invalid ABI specification");
-    return rv;
-  }
-
-  // prepare the result type
-  rv = PrepareType(aContext, aResultType, mResultType);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // prepare the argument types
-  for (PRUint32 i = 0; i < aArgTypes.Length(); ++i) {
-    rv = PrepareType(aContext, aArgTypes[i], *mArgTypes.AppendElement());
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // disallow void argument types
-    if (mArgTypes[i].mNativeType == nsINativeTypes::VOID)
-      return TypeError(aContext, "Cannot have void argument type");
-
-    // ffi_prep_cif requires an array of ffi_types; prepare it separately.
-    mFFITypes.AppendElement(&mArgTypes[i].mType);
-  }
-
-  ffi_status status = ffi_prep_cif(&mCIF, mCallType, mFFITypes.Length(),
-                                   &mResultType.mType, mFFITypes.Elements());
-  switch (status) {
-  case FFI_OK:
-    return NS_OK;
-  case FFI_BAD_ABI:
-    JS_ReportError(aContext, "Invalid ABI specification");
-    return NS_ERROR_INVALID_ARG;
-  case FFI_BAD_TYPEDEF:
-    JS_ReportError(aContext, "Invalid type specification");
-    return NS_ERROR_INVALID_ARG;
-  default:
-    JS_ReportError(aContext, "Unknown libffi error");
-    return NS_ERROR_FAILURE;
-  }
-}
-
-PRBool
-nsNativeMethod::Execute(JSContext* aContext, PRUint32 aArgc, jsval* aArgv, jsval* aValue)
-{
-  nsresult rv;
-
-  // prepare the values for each argument
-  nsAutoTArray<nsNativeValue, 16> nativeValues;
-  for (PRUint32 i = 0; i < mArgTypes.Length(); ++i) {
-    rv = PrepareValue(aContext, mArgTypes[i], aArgv[i], *nativeValues.AppendElement());
-    if (NS_FAILED(rv)) return PR_FALSE;
-  }
-
-  // create an array of pointers to each value, for passing to ffi_call
-  nsAutoTArray<void*, 16> values;
-  for (PRUint32 i = 0; i < mArgTypes.Length(); ++i) {
-    values.AppendElement(nativeValues[i].mData);
-  }
-
-  // initialize a pointer to an appropriate location, for storing the result
-  nsNativeValue resultValue;
-  PrepareReturnValue(mResultType, resultValue);
-
-  // suspend the request before we call into the function, since the call
-  // may block or otherwise take a long time to return.
-  jsrefcount rc = JS_SuspendRequest(aContext);
-
-  ffi_call(&mCIF, mFunc, resultValue.mData, values.Elements());
-
-  JS_ResumeRequest(aContext, rc);
-
-  // prepare a JS object from the result
-  rv = ConvertReturnValue(aContext, mResultType, resultValue, aValue);
-  if (NS_FAILED(rv)) return PR_FALSE;
-
-  return PR_TRUE;
-}
-
-/*******************************************************************************
-** nsIXPCScriptable implementation
-*******************************************************************************/
-
-#define XPC_MAP_CLASSNAME nsNativeMethod
-#define XPC_MAP_QUOTED_CLASSNAME "ctypes"
-#define XPC_MAP_WANT_CALL
-#define XPC_MAP_FLAGS nsIXPCScriptable::WANT_CALL
-
-#include "xpc_map_end.h"
-
-NS_IMETHODIMP
-nsNativeMethod::Call(nsIXPConnectWrappedNative* wrapper,
-                     JSContext* cx,
-                     JSObject* obj, 
-                     PRUint32 argc, 
-                     jsval* argv, 
-                     jsval* vp, 
-                     PRBool* _retval)
-{
-  JSAutoRequest ar(cx);
-
-  if (!mLibrary->IsOpen()) {
-    JS_ReportError(cx, "Library is not open");
-    *_retval = PR_FALSE;
-    return NS_ERROR_FAILURE;
-  }
-
-  if (argc != mArgTypes.Length()) {
-    JS_ReportError(cx, "Number of arguments does not match declaration");
-    *_retval = PR_FALSE;
-    return NS_ERROR_FAILURE;
-  }
-
-  *_retval = Execute(cx, argc, argv, vp);
-  if (!*_retval)
-    return NS_ERROR_FAILURE;
-
-  return NS_OK;
-}
-
deleted file mode 100644
--- a/js/ctypes/nsNativeMethod.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is js-ctypes.
- *
- * The Initial Developer of the Original Code is
- * The Mozilla Foundation <http://www.mozilla.org/>.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *  Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
- *  Dan Witte <dwitte@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef NSNATIVEMETHOD_H
-#define NSNATIVEMETHOD_H
-
-#include "nsNativeTypes.h"
-#include "nsIXPCScriptable.h"
-#include "nsString.h"
-#include "nsTArray.h"
-#include "nsAutoPtr.h"
-#include "prlink.h"
-#include "jsapi.h"
-#include "ffi.h"
-
-struct nsNativeType
-{
-  ffi_type mType;
-  PRUint16 mNativeType;
-};
-
-struct nsNativeValue
-{
-  void* mData;
-  union {
-    PRInt8   mInt8;
-    PRInt16  mInt16;
-    PRInt32  mInt32;
-    PRInt64  mInt64;
-    PRUint8  mUint8;
-    PRUint16 mUint16;
-    PRUint32 mUint32;
-    PRUint64 mUint64;
-    float    mFloat;
-    double   mDouble;
-    void*    mPointer;
-  } mValue;
-};
-
-class nsNativeMethod : public nsIXPCScriptable
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIXPCSCRIPTABLE
-
-  nsNativeMethod();
-
-  nsresult Init(JSContext* aContext, nsNativeTypes* aLibrary, PRFuncPtr aFunc, PRUint16 aCallType, jsval aResultType, const nsTArray<jsval>& aArgTypes);
-
-private:
-  ~nsNativeMethod();
-
-  PRBool Execute(JSContext* aContext, PRUint32 aArgc, jsval* aArgv, jsval* aValue);
-
-protected:
-  // reference to the library our function is in
-  nsRefPtr<nsNativeTypes> mLibrary;
-
-  PRFuncPtr mFunc;
-
-  ffi_abi mCallType;
-  nsNativeType mResultType;
-  nsAutoTArray<nsNativeType, 16> mArgTypes;
-  nsAutoTArray<ffi_type*, 16> mFFITypes;
-
-  ffi_cif mCIF;
-};
-
-#endif
deleted file mode 100644
--- a/js/ctypes/nsNativeModule.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is js-ctypes.
- *
- * The Initial Developer of the Original Code is
- * The Mozilla Foundation <http://www.mozilla.org/>.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *  Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
- *  Dan Witte <dwitte@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "nsIGenericFactory.h"
-#include "nsNativeTypes.h"
-
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsNativeTypes)
-
-static nsModuleComponentInfo components[] =
-{
-  {
-    "jsctypes",
-    NATIVETYPES_CID,
-    NATIVETYPES_CONTRACTID,
-    nsNativeTypesConstructor,
-  }
-};
-
-NS_IMPL_NSGETMODULE(jsctypes, components)
deleted file mode 100644
--- a/js/ctypes/nsNativeTypes.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is js-ctypes.
- *
- * The Initial Developer of the Original Code is
- * The Mozilla Foundation <http://www.mozilla.org/>.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *  Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
- *  Dan Witte <dwitte@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "nsNativeTypes.h"
-#include "nsNativeMethod.h"
-#include "nsServiceManagerUtils.h"
-#include "nsAutoPtr.h"
-#include "nsILocalFile.h"
-#include "prlink.h"
-#include "jsapi.h"
-
-static inline nsresult
-jsvalToUint16(JSContext* aContext, jsval aVal, PRUint16& aResult)
-{
-  if (JSVAL_IS_INT(aVal)) {
-    PRUint32 i = JSVAL_TO_INT(aVal);
-    if (i <= PR_UINT16_MAX) {
-      aResult = i;
-      return NS_OK;
-    }
-  }
-
-  JS_ReportError(aContext, "Parameter must be an integer");
-  return NS_ERROR_INVALID_ARG;
-}
-
-static inline nsresult
-jsvalToCString(JSContext* aContext, jsval aVal, const char*& aResult)
-{
-  if (JSVAL_IS_STRING(aVal)) {
-    aResult = JS_GetStringBytes(JSVAL_TO_STRING(aVal));
-    return NS_OK;
-  }
-
-  JS_ReportError(aContext, "Parameter must be a string");
-  return NS_ERROR_INVALID_ARG;
-}
-
-NS_IMPL_ISUPPORTS1(nsNativeTypes, nsINativeTypes)
-
-nsNativeTypes::nsNativeTypes()
-  : mLibrary(nsnull)
-{
-}
-
-nsNativeTypes::~nsNativeTypes()
-{
-  Close();
-}
-
-NS_IMETHODIMP
-nsNativeTypes::Open(nsILocalFile* aFile)
-{
-  NS_ENSURE_ARG(aFile);
-  NS_ENSURE_TRUE(!mLibrary, NS_ERROR_ALREADY_INITIALIZED);
-
-  return aFile->Load(&mLibrary);
-}
-
-NS_IMETHODIMP
-nsNativeTypes::Close()
-{
-  if (mLibrary) {
-    PR_UnloadLibrary(mLibrary);
-    mLibrary = nsnull;
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsNativeTypes::Declare(nsISupports** aResult)
-{
-  NS_ENSURE_ARG_POINTER(aResult);
-  NS_ENSURE_TRUE(mLibrary, NS_ERROR_NOT_INITIALIZED);
-
-  nsresult rv;
-
-  nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
-
-  nsAXPCNativeCallContext* ncc;
-  rv = xpc->GetCurrentNativeCallContext(&ncc);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  JSContext *ctx;
-  rv = ncc->GetJSContext(&ctx);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  JSAutoRequest ar(ctx);
-
-  PRUint32 argc;
-  jsval *argv;
-  ncc->GetArgc(&argc);
-  ncc->GetArgvPtr(&argv);
-
-  // we always need at least a method name, a call type and a return type
-  if (argc < 3) {
-    JS_ReportError(ctx, "Insufficient number of arguments");
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  const char* name;
-  rv = jsvalToCString(ctx, argv[0], name);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  PRUint16 callType;
-  rv = jsvalToUint16(ctx, argv[1], callType);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoTArray<jsval, 16> argTypes;
-  for (PRUint32 i = 3; i < argc; ++i) {
-    argTypes.AppendElement(argv[i]);
-  }
-
-  PRFuncPtr func = PR_FindFunctionSymbol(mLibrary, name);
-  if (!func) {
-    JS_ReportError(ctx, "Couldn't find function symbol in library");
-    return NS_ERROR_FAILURE;
-  }
-
-  nsRefPtr<nsNativeMethod> call = new nsNativeMethod;
-  rv = call->Init(ctx, this, func, callType, argv[2], argTypes);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  call.forget(aResult);
-  return rv;
-}
-
deleted file mode 100644
--- a/js/ctypes/nsNativeTypes.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is js-ctypes.
- *
- * The Initial Developer of the Original Code is
- * The Mozilla Foundation <http://www.mozilla.org/>.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *  Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
- *  Dan Witte <dwitte@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef NSNATIVETYPES_H
-#define NSNATIVETYPES_H
-
-#include "nsINativeTypes.h"
-
-#define NATIVETYPES_CONTRACTID \
-  "@mozilla.org/jsctypes;1"
-
-#define NATIVETYPES_CID \
-{ 0xc797702, 0x1c60, 0x4051, { 0x9d, 0xd7, 0x4d, 0x74, 0x5, 0x60, 0x56, 0x42 } }
-
-struct PRLibrary;
-
-class nsNativeTypes : public nsINativeTypes
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSINATIVETYPES
-
-  nsNativeTypes();
-
-  PRBool IsOpen() { return mLibrary != nsnull; }
-
-private:
-  ~nsNativeTypes();
-
-  PRLibrary* mLibrary;
-};
-
-#endif
--- a/js/ctypes/tests/jsctypes-test.cpp
+++ b/js/ctypes/tests/jsctypes-test.cpp
@@ -15,16 +15,17 @@
  * The Original Code is js-ctypes.
  *
  * The Initial Developer of the Original Code is
  * The Mozilla Foundation <http://www.mozilla.org/>.
  * Portions created by the Initial Developer are Copyright (C) 2009
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
+ *  Fredrik Larsson <nossralf@gmail.com>
  *  Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
  *  Dan Witte <dwitte@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
@@ -33,17 +34,16 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "jsctypes-test.h"
-#include "nsStringAPI.h"
 #include "nsCRT.h"
 #include <math.h>
 
 void
 test_v()
 {
   // do nothing
   return;
@@ -119,23 +119,23 @@ double
 test_d_dd(double number1, double number2)
 {
   return (number1 + number2);
 }
 
 int
 test_ansi_len(const char* string)
 {
-  return strlen(string);
+  return int(strlen(string));
 }
 
 int
 test_wide_len(const PRUnichar* string)
 {
-  return nsCRT::strlen(string);
+  return int(nsCRT::strlen(string));
 }
 
 const char *
 test_ansi_ret()
 {
   return "success";
 }
 
@@ -150,31 +150,11 @@ char *
 test_ansi_echo(const char* string)
 {
   return (char*)string;
 }
 
 int
 test_i_if_floor(int number1, float number2)
 {
-  return floor(float(number1) + number2);
+  return int(floor(float(number1) + number2));
 }
 
-int
-test_pt_in_rect(RECT rc, POINT pt)
-{
-  if (pt.x < rc.left || pt.x > rc.right)
-    return 0;
-  if (pt.y < rc.bottom || pt.y > rc.top)
-    return 0;
-  return 1;
-}
-
-int test_nested_struct(NESTED n) {
-  return n.n1 + n.n2 + n.inner.i1 + n.inner.i2 + n.inner.i3 + n.n3 + n.n4;
-}
-
-POINT test_struct_return(RECT r) {
-  POINT p;
-  p.x = r.left; p.y = r.top;
-  return p;
-}
-
--- a/js/ctypes/tests/jsctypes-test.h
+++ b/js/ctypes/tests/jsctypes-test.h
@@ -15,16 +15,17 @@
  * The Original Code is js-ctypes.
  *
  * The Initial Developer of the Original Code is
  * The Mozilla Foundation <http://www.mozilla.org/>.
  * Portions created by the Initial Developer are Copyright (C) 2009
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
+ *  Fredrik Larsson <nossralf@gmail.com>
  *  Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
  *  Dan Witte <dwitte@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
--- a/js/ctypes/tests/unit/test_jsctypes.js.in
+++ b/js/ctypes/tests/unit/test_jsctypes.js.in
@@ -15,16 +15,17 @@
  * The Original Code is js-ctypes.
  *
  * The Initial Developer of the Original Code is
  * The Mozilla Foundation <http://www.mozilla.org/>.
  * Portions created by the Initial Developer are Copyright (C) 2009
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
+ *  Fredrik Larsson <nossralf@gmail.com>
  *  Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
  *  Dan Witte <dwitte@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
@@ -39,48 +40,16 @@
 
 Components.utils.import("resource://gre/modules/ctypes.jsm");
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 const Types = ctypes.types;
 
-function POINT(x, y) {
-  this.x = x; this.y = y;
-}
-
-POINT.prototype = {
-  _fields_ : [{"x" : Types.INT32}, {"y" : Types.INT32}]
-}
-
-function RECT(top, left, bottom, right) {
-  this.top = top; this.left = left; this.bottom = bottom; this.right = right;
-}
-
-RECT.prototype = {
-  _fields_ : [{"top" : Types.INT32}, {"left" : Types.INT32}, {"bottom" : Types.INT32}, {"right" : Types.INT32}]
-}
-
-function INNER(i1, i2, i3) {
-  this.i1 = i1; this.i2 = i2; this.i3 = i3;
-}
-
-INNER.prototype = {
-  _fields_ : [{"i1" : Types.INT8}, {"i2" : Types.INT64}, {"i3" : Types.INT8}]
-}
-
-function NESTED(n1, n2, inner, n3, n4) {
-  this.n1 = n1; this.n2 = n2; this.inner = inner; this.n3 = n3; this.n4 = n4;
-}
-
-NESTED.prototype = {
-  _fields_ : [{"n1" : Types.INT32}, {"n2" : Types.INT16}, {"inner" : INNER}, {"n3" : Types.INT64}, {"n4" : Types.INT32}]
-}
-
 function do_check_throws(f, type, stack)
 {
   if (!stack)
     stack = Components.stack.caller;
 
   try {
     f();
   } catch (exc) {
@@ -114,19 +83,16 @@ function run_test()
   run_double_tests(library);
   run_string_tests(library);
   run_mixed_tests(library);
 
   // test the string version of ctypes.open() as well
   var libpath = libfile.path;
   library = ctypes.open(libpath);
   run_void_tests(library);
-
-  // structs not supported yet
-  //run_struct_tests(library);
 }
 
 function run_void_tests(library) {
   var test_v = library.declare("test_v", Types.DEFAULT, Types.VOID);
   do_check_eq(test_v(), undefined);
 }
 
 function run_short_tests(library) {
@@ -136,17 +102,16 @@ function run_short_tests(library) {
   var test_s_s = library.declare("test_s_s", Types.DEFAULT, Types.INT16, Types.INT16);
   do_check_eq(test_s_s(5), 5);
   do_check_eq(test_s_s(0), 0);
   do_check_eq(test_s_s(0x7fff), 0x7fff);
   do_check_eq(test_s_s(-0x8000), -0x8000);
   do_check_eq(1/test_s_s(-0), 1/0);  // that is, test_s_s(-0) is +0
   do_check_eq(test_s_s(true), 1);
   do_check_eq(test_s_s(false), 0);
-  do_check_eq(test_s_s(Number(16)), 16);
 
   // don't convert anything else to an int16
   var vals = [0x8000, -0x8001, 0x100000000, Infinity, -Infinity, NaN,
               null, undefined, "", "0", {}, [], new Number(16),
               {toString: function () { return 7; }},
               {valueOf: function () { return 7; }}];
   for (var i = 0; i < vals.length; i++)
     do_check_throws(function () { test_s_s(vals[i]); }, Error);
@@ -154,32 +119,31 @@ function run_short_tests(library) {
   var test_s_ss = library.declare("test_s_ss", Types.DEFAULT, Types.INT16, Types.INT16, Types.INT16);
   do_check_eq(test_s_ss(5, 5), 10);
 
   // test the range of unsigned. (we can reuse the signed C function
   // here, since it's binary-compatible.)
   var test_us_us = library.declare("test_s_s", Types.DEFAULT, Types.UINT16, Types.UINT16);
   do_check_eq(test_us_us(0xffff), 0xffff);
   do_check_throws(function () { test_us_us(0x10000); }, Error);
-
+  do_check_throws(function () { test_us_us(-1); }, Error);
 }
 
 function run_int_tests(library) {
   var test_i = library.declare("test_i", Types.DEFAULT, Types.INT32);
   do_check_eq(test_i(), 123456789);
 
   var test_i_i = library.declare("test_i_i", Types.DEFAULT, Types.INT32, Types.INT32);
   do_check_eq(test_i_i(5), 5);
   do_check_eq(test_i_i(0), 0);
   do_check_eq(test_i_i(0x7fffffff), 0x7fffffff);
   do_check_eq(test_i_i(-0x80000000), -0x80000000);
   do_check_eq(1/test_i_i(-0), 1/0);  // that is, test_i_i(-0) is +0
   do_check_eq(test_i_i(true), 1);
   do_check_eq(test_i_i(false), 0);
-  do_check_eq(test_i_i(Number(16)), 16);
 
   // don't convert anything else to an int
   var vals = [0x80000000, -0x80000001, Infinity, -Infinity, NaN,
               null, undefined, "", "0", {}, [], new Number(16),
               {toString: function () { return 7; }},
               {valueOf: function () { return 7; }}];
   for (var i = 0; i < vals.length; i++)
     do_check_throws(function () { test_i_i(vals[i]); }, Error);
@@ -187,30 +151,30 @@ function run_int_tests(library) {
   var test_i_ii = library.declare("test_i_ii", Types.DEFAULT, Types.INT32, Types.INT32, Types.INT32);
   do_check_eq(test_i_ii(5, 5), 10);
 
   // test the range of unsigned. (we can reuse the signed C function
   // here, since it's binary-compatible.)
   var test_ui_ui = library.declare("test_i_i", Types.DEFAULT, Types.UINT32, Types.UINT32);
   do_check_eq(test_ui_ui(0xffffffff), 0xffffffff);
   do_check_throws(function () { test_ui_ui(0x100000000); }, Error);
+  do_check_throws(function () { test_ui_ui(-1); }, Error);
 }
 
 function run_float_tests(library) {
   var test_f = library.declare("test_f", Types.DEFAULT, Types.FLOAT);
   do_check_eq(test_f(), 123456.5);
 
   var test_f_f = library.declare("test_f_f", Types.DEFAULT, Types.FLOAT, Types.FLOAT);
   do_check_eq(test_f_f(5), 5);
   do_check_eq(test_f_f(5.25), 5.25);
   do_check_eq(test_f_f(Infinity), Infinity);
   do_check_eq(test_f_f(-Infinity), -Infinity);
   do_check_eq(isNaN(test_f_f(NaN)), true);
   do_check_eq(1/test_f_f(-0), 1/-0); // that is, test_f_f(-0) is -0
-  do_check_eq(test_f_f(Number(16.5)), 16.5);
 
   // allow values that can't be represented precisely as a float
   do_check_eq(test_f_f(1 + 1/0x80000000), 1);
 
   // don't convert anything else to a float
   var vals = [true, false, null, undefined, "", "0", {}, [], new Number(16),
               {toString: function () { return 7; }},
               {valueOf: function () { return 7; }}];
@@ -228,17 +192,16 @@ function run_double_tests(library) {
 
   var test_d_d = library.declare("test_d_d", Types.DEFAULT, Types.DOUBLE, Types.DOUBLE);
   do_check_eq(test_d_d(5), 5);
   do_check_eq(test_d_d(5.25), 5.25);
   do_check_eq(test_d_d(Infinity), Infinity);
   do_check_eq(test_d_d(-Infinity), -Infinity);
   do_check_eq(isNaN(test_d_d(NaN)), true);
   do_check_eq(1/test_d_d(-0), 1/-0); // that is, test_d_d(-0) is -0
-  do_check_eq(test_d_d(Number(16.5)), 16.5);
 
   // don't convert anything else to a double
   var vals = [true, false, null, undefined, "", "0", {}, [], new Number(16),
               {toString: function () { return 7; }},
               {valueOf: function () { return 7; }}];
   for (var i = 0; i < vals.length; i++)
     do_check_throws(function () { test_d_d(vals[i]); }, Error);
 
@@ -272,33 +235,8 @@ function run_string_tests(library) {
 }
 
 function run_mixed_tests(library) {
   var test_i_if_floor = library.declare("test_i_if_floor", Types.DEFAULT, Types.INT32, Types.INT32, Types.FLOAT);
   do_check_eq(test_i_if_floor(5, 5.5), 10);
   do_check_throws(function() { test_i_if_floor(5.5, 5); }, Error);
 }
 
-function run_struct_tests(library) {
-  var test_pt_in_rect = library.declare("test_pt_in_rect", Types.DEFAULT, Types.INT32, RECT, POINT);
-  var rect = new RECT(10, 5, 5, 10);
-  var pt1 = new POINT(6, 6);
-  do_check_eq(test_pt_in_rect(rect, pt1), 1);
-  var pt2 = new POINT(2, 2);
-  do_check_eq(test_pt_in_rect(rect, pt2), 0);
-
-  // don't allow 0 or null when passing by value
-  do_check_throws(function () { test_pt_in_rect(rect, 0); }, Error);
-  do_check_throws(function () { test_pt_in_rect(rect, null); }, Error);
-  do_check_throws(function () { test_pt_in_rect(rect, undefined); }, Error);
-
-  var test_nested_struct = library.declare("test_nested_struct", Types.DEFAULT, Types.INT32, NESTED);
-  var inner = new INNER(161, 523412, 43);
-  var nested = new NESTED(13155, 1241, inner, 24512115, 1234111);
-  // add up all the numbers and make sure the C function agrees
-  do_check_eq(test_nested_struct(nested), 26284238);
-
-  var test_struct_return = library.declare("test_struct_return", Types.DEFAULT, POINT, RECT);
-  var ret = test_struct_return(rect);
-  do_check_eq(ret.x, rect.left);
-  do_check_eq(ret.y, rect.top);
-}
-