Merge tracemonkey to mozilla-central.
authorRobert Sayre <sayrer@gmail.com>
Mon, 05 Apr 2010 13:17:29 -0400
changeset 40456 1942c0b4e1018bb85fc17676c634d6e631662073
parent 40220 fabb17b2c94eb5e9ea9d494873a1fab22c45ee77 (current diff)
parent 40455 df40cdde12730b8b6874e7dd2595c3fbaec63248 (diff)
child 40457 17e554c5087c879dad418409fd47e9a463b09d50
push id12610
push userrsayre@mozilla.com
push dateMon, 05 Apr 2010 17:26:41 +0000
treeherdermozilla-central@1942c0b4e101 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.3a4pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
Merge tracemonkey to mozilla-central.
content/base/public/nsContentUtils.h
content/base/src/nsContentUtils.cpp
js/ctypes/CTypes.cpp
js/ctypes/CTypes.h
js/ctypes/Library.cpp
js/ctypes/Library.h
js/ctypes/Makefile.in
js/ctypes/Module.cpp
js/ctypes/Module.h
js/ctypes/ctypes.jsm
js/ctypes/ctypes.msg
js/ctypes/libffi.patch
js/ctypes/libffi/ChangeLog
js/ctypes/libffi/ChangeLog.libffi
js/ctypes/libffi/ChangeLog.libgcj
js/ctypes/libffi/ChangeLog.v1
js/ctypes/libffi/LICENSE
js/ctypes/libffi/Makefile.am
js/ctypes/libffi/Makefile.in
js/ctypes/libffi/README
js/ctypes/libffi/acinclude.m4
js/ctypes/libffi/aclocal.m4
js/ctypes/libffi/compile
js/ctypes/libffi/config.guess
js/ctypes/libffi/config.sub
js/ctypes/libffi/configure
js/ctypes/libffi/configure.ac
js/ctypes/libffi/configure.host
js/ctypes/libffi/depcomp
js/ctypes/libffi/doc/libffi.info
js/ctypes/libffi/doc/libffi.texi
js/ctypes/libffi/doc/stamp-vti
js/ctypes/libffi/doc/version.texi
js/ctypes/libffi/fficonfig.h.in
js/ctypes/libffi/include/Makefile.am
js/ctypes/libffi/include/Makefile.in
js/ctypes/libffi/include/ffi.h.in
js/ctypes/libffi/include/ffi_common.h
js/ctypes/libffi/install-sh
js/ctypes/libffi/libffi.pc.in
js/ctypes/libffi/libtool-version
js/ctypes/libffi/ltmain.sh
js/ctypes/libffi/m4/libtool.m4
js/ctypes/libffi/m4/ltoptions.m4
js/ctypes/libffi/m4/ltsugar.m4
js/ctypes/libffi/m4/ltversion.m4
js/ctypes/libffi/m4/lt~obsolete.m4
js/ctypes/libffi/man/Makefile.am
js/ctypes/libffi/man/Makefile.in
js/ctypes/libffi/man/ffi.3
js/ctypes/libffi/man/ffi_call.3
js/ctypes/libffi/man/ffi_prep_cif.3
js/ctypes/libffi/mdate-sh
js/ctypes/libffi/missing
js/ctypes/libffi/msvcc.sh
js/ctypes/libffi/src/alpha/ffi.c
js/ctypes/libffi/src/alpha/ffitarget.h
js/ctypes/libffi/src/alpha/osf.S
js/ctypes/libffi/src/arm/ffi.c
js/ctypes/libffi/src/arm/ffitarget.h
js/ctypes/libffi/src/arm/sysv.S
js/ctypes/libffi/src/avr32/ffi.c
js/ctypes/libffi/src/avr32/ffitarget.h
js/ctypes/libffi/src/avr32/sysv.S
js/ctypes/libffi/src/closures.c
js/ctypes/libffi/src/cris/ffi.c
js/ctypes/libffi/src/cris/ffitarget.h
js/ctypes/libffi/src/cris/sysv.S
js/ctypes/libffi/src/debug.c
js/ctypes/libffi/src/dlmalloc.c
js/ctypes/libffi/src/frv/eabi.S
js/ctypes/libffi/src/frv/ffi.c
js/ctypes/libffi/src/frv/ffitarget.h
js/ctypes/libffi/src/ia64/ffi.c
js/ctypes/libffi/src/ia64/ffitarget.h
js/ctypes/libffi/src/ia64/ia64_flags.h
js/ctypes/libffi/src/ia64/unix.S
js/ctypes/libffi/src/java_raw_api.c
js/ctypes/libffi/src/m32r/ffi.c
js/ctypes/libffi/src/m32r/ffitarget.h
js/ctypes/libffi/src/m32r/sysv.S
js/ctypes/libffi/src/m68k/ffi.c
js/ctypes/libffi/src/m68k/ffitarget.h
js/ctypes/libffi/src/m68k/sysv.S
js/ctypes/libffi/src/mips/ffi.c
js/ctypes/libffi/src/mips/ffitarget.h
js/ctypes/libffi/src/mips/n32.S
js/ctypes/libffi/src/mips/o32.S
js/ctypes/libffi/src/moxie/eabi.S
js/ctypes/libffi/src/moxie/ffi.c
js/ctypes/libffi/src/moxie/ffitarget.h
js/ctypes/libffi/src/pa/ffi.c
js/ctypes/libffi/src/pa/ffitarget.h
js/ctypes/libffi/src/pa/hpux32.S
js/ctypes/libffi/src/pa/linux.S
js/ctypes/libffi/src/powerpc/aix.S
js/ctypes/libffi/src/powerpc/aix_closure.S
js/ctypes/libffi/src/powerpc/asm.h
js/ctypes/libffi/src/powerpc/darwin.S
js/ctypes/libffi/src/powerpc/darwin_closure.S
js/ctypes/libffi/src/powerpc/ffi.c
js/ctypes/libffi/src/powerpc/ffi_darwin.c
js/ctypes/libffi/src/powerpc/ffitarget.h
js/ctypes/libffi/src/powerpc/linux64.S
js/ctypes/libffi/src/powerpc/linux64_closure.S
js/ctypes/libffi/src/powerpc/ppc_closure.S
js/ctypes/libffi/src/powerpc/sysv.S
js/ctypes/libffi/src/prep_cif.c
js/ctypes/libffi/src/raw_api.c
js/ctypes/libffi/src/s390/ffi.c
js/ctypes/libffi/src/s390/ffitarget.h
js/ctypes/libffi/src/s390/sysv.S
js/ctypes/libffi/src/sh/ffi.c
js/ctypes/libffi/src/sh/ffitarget.h
js/ctypes/libffi/src/sh/sysv.S
js/ctypes/libffi/src/sh64/ffi.c
js/ctypes/libffi/src/sh64/ffitarget.h
js/ctypes/libffi/src/sh64/sysv.S
js/ctypes/libffi/src/sparc/ffi.c
js/ctypes/libffi/src/sparc/ffitarget.h
js/ctypes/libffi/src/sparc/v8.S
js/ctypes/libffi/src/sparc/v9.S
js/ctypes/libffi/src/types.c
js/ctypes/libffi/src/x86/darwin.S
js/ctypes/libffi/src/x86/darwin64.S
js/ctypes/libffi/src/x86/ffi.c
js/ctypes/libffi/src/x86/ffi64.c
js/ctypes/libffi/src/x86/ffitarget.h
js/ctypes/libffi/src/x86/freebsd.S
js/ctypes/libffi/src/x86/sysv.S
js/ctypes/libffi/src/x86/unix64.S
js/ctypes/libffi/src/x86/win32.S
js/ctypes/libffi/src/x86/win64.S
js/ctypes/libffi/testsuite/Makefile.am
js/ctypes/libffi/testsuite/Makefile.in
js/ctypes/libffi/testsuite/config/default.exp
js/ctypes/libffi/testsuite/lib/libffi-dg.exp
js/ctypes/libffi/testsuite/lib/target-libpath.exp
js/ctypes/libffi/testsuite/lib/wrapper.exp
js/ctypes/libffi/testsuite/libffi.call/call.exp
js/ctypes/libffi/testsuite/libffi.call/closure_fn0.c
js/ctypes/libffi/testsuite/libffi.call/closure_fn1.c
js/ctypes/libffi/testsuite/libffi.call/closure_fn2.c
js/ctypes/libffi/testsuite/libffi.call/closure_fn3.c
js/ctypes/libffi/testsuite/libffi.call/closure_fn4.c
js/ctypes/libffi/testsuite/libffi.call/closure_fn5.c
js/ctypes/libffi/testsuite/libffi.call/closure_fn6.c
js/ctypes/libffi/testsuite/libffi.call/closure_loc_fn0.c
js/ctypes/libffi/testsuite/libffi.call/closure_stdcall.c
js/ctypes/libffi/testsuite/libffi.call/cls_12byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_16byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_18byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_19byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_1_1byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_20byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_20byte1.c
js/ctypes/libffi/testsuite/libffi.call/cls_24byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_2byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_3_1byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_3byte1.c
js/ctypes/libffi/testsuite/libffi.call/cls_3byte2.c
js/ctypes/libffi/testsuite/libffi.call/cls_4_1byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_4byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_5_1_byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_5byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_64byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_6_1_byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_6byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_7_1_byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_7byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_8byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_9byte1.c
js/ctypes/libffi/testsuite/libffi.call/cls_9byte2.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_double.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_float.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_longdouble.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_longdouble_split.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_pointer.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_sint16.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_sint32.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_sint64.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_uint16.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_uint32.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_uint64.c
js/ctypes/libffi/testsuite/libffi.call/cls_dbls_struct.c
js/ctypes/libffi/testsuite/libffi.call/cls_double.c
js/ctypes/libffi/testsuite/libffi.call/cls_double_va.c
js/ctypes/libffi/testsuite/libffi.call/cls_float.c
js/ctypes/libffi/testsuite/libffi.call/cls_longdouble.c
js/ctypes/libffi/testsuite/libffi.call/cls_longdouble_va.c
js/ctypes/libffi/testsuite/libffi.call/cls_multi_schar.c
js/ctypes/libffi/testsuite/libffi.call/cls_multi_sshort.c
js/ctypes/libffi/testsuite/libffi.call/cls_multi_sshortchar.c
js/ctypes/libffi/testsuite/libffi.call/cls_multi_uchar.c
js/ctypes/libffi/testsuite/libffi.call/cls_multi_ushort.c
js/ctypes/libffi/testsuite/libffi.call/cls_multi_ushortchar.c
js/ctypes/libffi/testsuite/libffi.call/cls_pointer.c
js/ctypes/libffi/testsuite/libffi.call/cls_pointer_stack.c
js/ctypes/libffi/testsuite/libffi.call/cls_schar.c
js/ctypes/libffi/testsuite/libffi.call/cls_sint.c
js/ctypes/libffi/testsuite/libffi.call/cls_sshort.c
js/ctypes/libffi/testsuite/libffi.call/cls_uchar.c
js/ctypes/libffi/testsuite/libffi.call/cls_uint.c
js/ctypes/libffi/testsuite/libffi.call/cls_ulonglong.c
js/ctypes/libffi/testsuite/libffi.call/cls_ushort.c
js/ctypes/libffi/testsuite/libffi.call/err_bad_abi.c
js/ctypes/libffi/testsuite/libffi.call/err_bad_typedef.c
js/ctypes/libffi/testsuite/libffi.call/ffitest.h
js/ctypes/libffi/testsuite/libffi.call/float.c
js/ctypes/libffi/testsuite/libffi.call/float1.c
js/ctypes/libffi/testsuite/libffi.call/float2.c
js/ctypes/libffi/testsuite/libffi.call/float3.c
js/ctypes/libffi/testsuite/libffi.call/float4.c
js/ctypes/libffi/testsuite/libffi.call/huge_struct.c
js/ctypes/libffi/testsuite/libffi.call/many.c
js/ctypes/libffi/testsuite/libffi.call/many_win32.c
js/ctypes/libffi/testsuite/libffi.call/negint.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct1.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct10.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct2.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct3.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct4.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct5.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct6.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct7.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct8.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct9.c
js/ctypes/libffi/testsuite/libffi.call/problem1.c
js/ctypes/libffi/testsuite/libffi.call/promotion.c
js/ctypes/libffi/testsuite/libffi.call/pyobjc-tc.c
js/ctypes/libffi/testsuite/libffi.call/return_dbl.c
js/ctypes/libffi/testsuite/libffi.call/return_dbl1.c
js/ctypes/libffi/testsuite/libffi.call/return_dbl2.c
js/ctypes/libffi/testsuite/libffi.call/return_fl.c
js/ctypes/libffi/testsuite/libffi.call/return_fl1.c
js/ctypes/libffi/testsuite/libffi.call/return_fl2.c
js/ctypes/libffi/testsuite/libffi.call/return_fl3.c
js/ctypes/libffi/testsuite/libffi.call/return_ldl.c
js/ctypes/libffi/testsuite/libffi.call/return_ll.c
js/ctypes/libffi/testsuite/libffi.call/return_ll1.c
js/ctypes/libffi/testsuite/libffi.call/return_sc.c
js/ctypes/libffi/testsuite/libffi.call/return_sl.c
js/ctypes/libffi/testsuite/libffi.call/return_uc.c
js/ctypes/libffi/testsuite/libffi.call/return_ul.c
js/ctypes/libffi/testsuite/libffi.call/stret_large.c
js/ctypes/libffi/testsuite/libffi.call/stret_large2.c
js/ctypes/libffi/testsuite/libffi.call/stret_medium.c
js/ctypes/libffi/testsuite/libffi.call/stret_medium2.c
js/ctypes/libffi/testsuite/libffi.call/strlen.c
js/ctypes/libffi/testsuite/libffi.call/strlen_win32.c
js/ctypes/libffi/testsuite/libffi.call/struct1.c
js/ctypes/libffi/testsuite/libffi.call/struct2.c
js/ctypes/libffi/testsuite/libffi.call/struct3.c
js/ctypes/libffi/testsuite/libffi.call/struct4.c
js/ctypes/libffi/testsuite/libffi.call/struct5.c
js/ctypes/libffi/testsuite/libffi.call/struct6.c
js/ctypes/libffi/testsuite/libffi.call/struct7.c
js/ctypes/libffi/testsuite/libffi.call/struct8.c
js/ctypes/libffi/testsuite/libffi.call/struct9.c
js/ctypes/libffi/testsuite/libffi.call/testclosure.c
js/ctypes/libffi/testsuite/libffi.special/ffitestcxx.h
js/ctypes/libffi/testsuite/libffi.special/special.exp
js/ctypes/libffi/testsuite/libffi.special/unwindtest.cc
js/ctypes/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc
js/ctypes/libffi/texinfo.tex
js/ctypes/tests/Makefile.in
js/ctypes/tests/jsctypes-test.cpp
js/ctypes/tests/jsctypes-test.h
js/ctypes/tests/unit/test_jsctypes.js.in
js/ctypes/typedefs.h
js/src/jsinterpinlines.h
js/src/xpconnect/src/xpcprivate.h
modules/plugin/base/src/nsNPAPIPlugin.cpp
--- a/browser/components/places/tests/unit/test_leftpane_corruption_handling.js
+++ b/browser/components/places/tests/unit/test_leftpane_corruption_handling.js
@@ -197,17 +197,18 @@ function compareJSON(aNodeJSON_1, aNodeJ
   let JSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
   node1 = JSON.decode(aNodeJSON_1);
   node2 = JSON.decode(aNodeJSON_2);
 
   // List of properties we should not compare (expected to be different).
   const SKIP_PROPS = ["dateAdded", "lastModified", "id"];
 
   function compareObjects(obj1, obj2) {
-    do_check_eq(obj1.__count__, obj2.__count__);
+    function count(o) { var n = 0; for (let p in o) n++; return n; }
+    do_check_eq(count(obj1), count(obj2));
     for (let prop in obj1) {
       // Skip everchanging values.
       if (SKIP_PROPS.indexOf(prop) != -1)
         continue;
       // Skip undefined objects, otherwise we hang on them.
       if (!obj1[prop])
         continue;
       if (typeof(obj1[prop]) == "object")
--- a/configure.in
+++ b/configure.in
@@ -6993,16 +6993,27 @@ MOZ_ARG_ENABLE_BOOL(tracevis,
 [  --enable-tracevis       Enable TraceVis tracing tool (default=no)],
     MOZ_TRACEVIS=1,
     MOZ_TRACEVIS= )
 if test -n "$MOZ_TRACEVIS"; then
     AC_DEFINE(MOZ_TRACEVIS)
 fi
 
 dnl ========================================================
+dnl = Use GCTimer
+dnl ========================================================
+MOZ_ARG_ENABLE_BOOL(gctimer,
+[  --enable-gctimer       Enable GC timer (default=no)],
+    MOZ_GCTIMER=1,
+    MOZ_GCTIMER= )
+if test -n "$MOZ_GCTIMER"; then
+    AC_DEFINE(MOZ_GCTIMER)
+fi
+
+dnl ========================================================
 dnl = Use Valgrind
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(valgrind,
 [  --enable-valgrind       Enable Valgrind integration hooks (default=no)],
     MOZ_VALGRIND=1,
     MOZ_VALGRIND= )
 if test -n "$MOZ_VALGRIND"; then
     AC_CHECK_HEADER([valgrind/valgrind.h], [],
@@ -8123,19 +8134,16 @@ MOZ_ARG_DISABLE_BOOL(ctypes,
 [  --disable-ctypes        Disable js-ctypes],
     BUILD_CTYPES=,
     BUILD_CTYPES=1)
 AC_SUBST(BUILD_CTYPES)
 if test "$BUILD_CTYPES"; then
   if test "$OS_ARCH" = "WINCE" -a `echo $OS_TEST | grep -ic arm` = 1; then
     # Disable ctypes for arm/wince.
     BUILD_CTYPES=
-  elif test "$_MSC_VER" && test -z $AS; then
-    # Disable ctypes if we're on MSVC and MASM is unavailable.
-    AC_MSG_ERROR([No suitable assembler found. An assembler is required to build js-ctypes. You may --disable-ctypes to avoid this. If you are building with MS Visual Studio 8 Express, you may download the MASM 8.0 package, upgrade to Visual Studio 9 Express, or install the Vista SDK.])
   else
     AC_DEFINE(BUILD_CTYPES)
   fi
 fi
 
 dnl NECKO_ configuration options are not global
 _NON_GLOBAL_ACDEFINES="$_NON_GLOBAL_ACDEFINES NECKO_"
 
@@ -8716,80 +8724,36 @@ if test -z "$MOZ_NATIVE_NSPR"; then
     fi
     rm -f config/autoconf.mk.bak
 fi
 
 # Run the SpiderMonkey 'configure' script.
 dist=$MOZ_BUILD_ROOT/dist
 ac_configure_args="$_SUBDIR_CONFIG_ARGS"
 ac_configure_args="$ac_configure_args --enable-threadsafe"
+if test "$BUILD_CTYPES"; then
+    # Build js-ctypes on the platforms we can.
+    ac_configure_args="$ac_configure_args --enable-ctypes"
+fi
 if test -z "$MOZ_NATIVE_NSPR"; then
     ac_configure_args="$ac_configure_args --with-nspr-cflags='$NSPR_CFLAGS'"
     ac_configure_args="$ac_configure_args --with-nspr-libs='$NSPR_LIBS'"
 fi
 ac_configure_args="$ac_configure_args --with-dist-dir=../../dist"
 ac_configure_args="$ac_configure_args --prefix=$dist"
 ac_configure_args="$ac_configure_args --with-sync-build-files=$_topsrcdir"
 if test "$MOZ_MEMORY"; then
    ac_configure_args="$ac_configure_args --enable-jemalloc"
    if test -n "$MOZ_MEMORY_LDFLAGS"; then
      export MOZ_MEMORY_LDFLAGS
    fi
 fi
 AC_OUTPUT_SUBDIRS(js/src)
 ac_configure_args="$_SUBDIR_CONFIG_ARGS"
 
-# Build jsctypes on the platforms we can.
-if test "$BUILD_CTYPES"; then
-  # Run the libffi 'configure' script.
-  ac_configure_args="--disable-shared --enable-static --disable-raw-api"
-  if test "$MOZ_DEBUG"; then
-    ac_configure_args="$ac_configure_args --enable-debug"
-  fi
-  if test "$DSO_PIC_CFLAGS"; then
-    ac_configure_args="$ac_configure_args --with-pic"
-  fi
-  if test "$CROSS_COMPILE"; then
-    case "$target" in
-    *-mingw*)
-      ac_configure_args="$ac_configure_args --build=$build --host=${target_cpu}-${target_os} HOST_CC=\"$HOST_CC\" CC=\"$CC\""
-      ;;
-    *)
-      ac_configure_args="$ac_configure_args --build=$build --host=$target HOST_CC=\"$HOST_CC\" CC=\"$CC\""
-      ;;
-    esac
-  fi
-  if test "$_MSC_VER"; then
-    # Use a wrapper script for cl and ml that looks more like gcc.
-    # autotools can't quite handle an MSVC build environment yet.
-    ac_configure_args="$ac_configure_args LD=link CPP=\"cl -nologo -EP\" SHELL=sh.exe"
-    case "${target_cpu}" in
-    x86_64)
-      # Need target since MSYS tools into mozilla-build may be 32bit
-      ac_configure_args="$ac_configure_args CC=\"$_topsrcdir/js/ctypes/libffi/msvcc.sh -m64\" --build=$build --host=$target"
-      ;;
-    *)
-      ac_configure_args="$ac_configure_args CC=$_topsrcdir/js/ctypes/libffi/msvcc.sh"
-      ;;
-    esac
-  fi
-  if test "$SOLARIS_SUNPRO_CC"; then
-    # Always use gcc for libffi on Solaris
-    ac_configure_args="$ac_configure_args CC=gcc"
-  fi
-
-  # Use a separate cache file for libffi, since it does things differently
-  # from our configure.
-  old_cache_file=$cache_file
-  cache_file=js/ctypes/libffi/config.cache
-  AC_OUTPUT_SUBDIRS(js/ctypes/libffi)
-  cache_file=$old_cache_file
-  ac_configure_args="$_SUBDIR_CONFIG_ARGS"
-fi
-
 fi # COMPILE_ENVIRONMENT && !LIBXUL_SDK_DIR
 
 dnl Prevent the regeneration of autoconf.mk forcing rebuilds of the world
 dnl Needs to be at the end to respect possible changes from NSPR configure
 if cmp -s config/autoconf.mk config/autoconf.mk.orig; then
   echo "config/autoconf.mk is unchanged"
   mv -f config/autoconf.mk.orig config/autoconf.mk 2> /dev/null
 else
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -5402,17 +5402,17 @@ class CloneStackFrame
   friend class CloneStack;
 
 public:
   // These three jsvals must all stick together as they're treated as a jsval
   // array!
   jsval source;
   jsval clone;
   jsval temp;
-  JSAutoIdArray ids;
+  js::AutoIdArray ids;
   jsuint index;
 
 private:
   // Only let CloneStack access these.
   CloneStackFrame(JSContext* aCx, jsval aSource, jsval aClone, JSIdArray* aIds)
   : source(aSource), clone(aClone), temp(JSVAL_NULL), ids(aCx, aIds), index(0),
     prevFrame(nsnull),  tvrVals(aCx, 3, &source)
   {
@@ -5420,17 +5420,17 @@ private:
   }
 
   ~CloneStackFrame()
   {
     MOZ_COUNT_DTOR(CloneStackFrame);
   }
 
   CloneStackFrame* prevFrame;
-  JSAutoTempValueRooter tvrVals;
+  js::AutoArrayRooter tvrVals;
 };
 
 class CloneStack
 {
 public:
   CloneStack(JSContext* cx)
   : mCx(cx), mLastFrame(nsnull) {
     mObjectSet.Init();
@@ -5686,17 +5686,17 @@ nsContentUtils::CreateStructuredClone(JS
 
   NS_ASSERTION(JSVAL_IS_OBJECT(val), "Not an object?!");
   JSObject* obj = CreateEmptyObjectOrArray(cx, JSVAL_TO_OBJECT(val));
   if (!obj) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   jsval output = OBJECT_TO_JSVAL(obj);
-  JSAutoTempValueRooter tvr(cx, output);
+  js::AutoValueRooter tvr(cx, output);
 
   CloneStack stack(cx);
   if (!stack.Push(val, OBJECT_TO_JSVAL(obj),
                   JS_Enumerate(cx, JSVAL_TO_OBJECT(val)))) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   while (!stack.IsEmpty()) {
--- a/content/canvas/src/CustomQS_Canvas2D.h
+++ b/content/canvas/src/CustomQS_Canvas2D.h
@@ -45,17 +45,17 @@ typedef nsresult (NS_STDCALL nsIDOMCanva
 
 static JSBool
 Canvas2D_SetStyleHelper(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
                         CanvasStyleSetterType setfunc)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     nsIDOMCanvasRenderingContext2D *self;
     xpc_qsSelfRef selfref;
-    JSAutoTempValueRooter tvr(cx);
+    js::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
         return JS_FALSE;
 
     nsresult rv;
 
     if (JSVAL_IS_STRING(*vp)) {
         xpc_qsDOMString arg0(cx, *vp, vp,
                              xpc_qsDOMString::eDefaultNullBehavior,
@@ -174,24 +174,24 @@ nsIDOMCanvasRenderingContext2D_CreateIma
         return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
 
     uint32 len = len0 * 4;
     if (len / 4 != len0)
         return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
 
     // create the fast typed array; it's initialized to 0 by default
     JSObject *darray = js_CreateTypedArray(cx, js::TypedArray::TYPE_UINT8_CLAMPED, len);
-    JSAutoTempValueRooter rd(cx, darray);
+    js::AutoValueRooter rd(cx, darray);
     if (!darray)
         return JS_FALSE;
 
     // Do JS_NewObject after CreateTypedArray, so that gc will get
     // triggered here if necessary
     JSObject *result = JS_NewObject(cx, NULL, NULL, NULL);
-    JSAutoTempValueRooter rr(cx, result);
+    js::AutoValueRooter rr(cx, result);
     if (!result)
         return JS_FALSE;
 
     if (!JS_DefineProperty(cx, result, "width", INT_TO_JSVAL(w), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) ||
         !JS_DefineProperty(cx, result, "height", INT_TO_JSVAL(h), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) ||
         !JS_DefineProperty(cx, result, "data", OBJECT_TO_JSVAL(darray), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT))
         return JS_FALSE;
 
@@ -207,17 +207,17 @@ nsIDOMCanvasRenderingContext2D_GetImageD
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsIDOMCanvasRenderingContext2D *self;
     xpc_qsSelfRef selfref;
-    JSAutoTempValueRooter tvr(cx);
+    js::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 4)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -241,31 +241,31 @@ nsIDOMCanvasRenderingContext2D_GetImageD
         return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
 
     uint32 len = len0 * 4;
     if (len / 4 != len0)
         return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
 
     // create the fast typed array
     JSObject *darray = js_CreateTypedArray(cx, js::TypedArray::TYPE_UINT8_CLAMPED, len);
-    JSAutoTempValueRooter rd(cx, darray);
+    js::AutoValueRooter rd(cx, darray);
     if (!darray)
         return JS_FALSE;
 
     js::TypedArray *tdest = js::TypedArray::fromJSObject(darray);
 
     // make the call
     rv = self->GetImageData_explicit(x, y, w, h, (PRUint8*) tdest->data, tdest->byteLength);
     if (NS_FAILED(rv))
         return xpc_qsThrowMethodFailed(cx, rv, vp);
 
     // Do JS_NewObject after CreateTypedArray, so that gc will get
     // triggered here if necessary
     JSObject *result = JS_NewObject(cx, NULL, NULL, NULL);
-    JSAutoTempValueRooter rr(cx, result);
+    js::AutoValueRooter rr(cx, result);
     if (!result)
         return JS_FALSE;
 
     if (!JS_DefineProperty(cx, result, "width", INT_TO_JSVAL(w), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) ||
         !JS_DefineProperty(cx, result, "height", INT_TO_JSVAL(h), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) ||
         !JS_DefineProperty(cx, result, "data", OBJECT_TO_JSVAL(darray), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT))
         return JS_FALSE;
 
@@ -281,17 +281,17 @@ nsIDOMCanvasRenderingContext2D_PutImageD
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsIDOMCanvasRenderingContext2D *self;
     xpc_qsSelfRef selfref;
-    JSAutoTempValueRooter tvr(cx);
+    js::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 3)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -303,17 +303,17 @@ nsIDOMCanvasRenderingContext2D_PutImageD
     if (!JS_ValueToECMAInt32(cx, argv[1], &x) ||
         !JS_ValueToECMAInt32(cx, argv[2], &y))
         return JS_FALSE;
 
     int32 wi, hi;
     JSObject *darray;
 
     // grab width, height, and the dense array from the dataObject
-    JSAutoTempValueRooter tv(cx);
+    js::AutoValueRooter tv(cx);
 
     if (!JS_GetProperty(cx, dataObject, "width", tv.addr()) ||
         !JS_ValueToECMAInt32(cx, tv.value(), &wi))
         return JS_FALSE;
 
     if (!JS_GetProperty(cx, dataObject, "height", tv.addr()) ||
         !JS_ValueToECMAInt32(cx, tv.value(), &hi))
         return JS_FALSE;
@@ -324,17 +324,17 @@ nsIDOMCanvasRenderingContext2D_PutImageD
     uint32 w = (uint32) wi;
     uint32 h = (uint32) hi;
 
     if (!JS_GetProperty(cx, dataObject, "data", tv.addr()) ||
         JSVAL_IS_PRIMITIVE(tv.value()))
         return JS_FALSE;
     darray = JSVAL_TO_OBJECT(tv.value());
 
-    JSAutoTempValueRooter tsrc_tvr(cx);
+    js::AutoValueRooter tsrc_tvr(cx);
 
     js::TypedArray *tsrc = NULL;
     if (darray->getClass() == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8] ||
         darray->getClass() == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8_CLAMPED])
     {
         tsrc = js::TypedArray::fromJSObject(darray);
     } else if (JS_IsArrayObject(cx, darray) || js_IsTypedArray(darray)) {
         // ugh, this isn't a uint8 typed array, someone made their own object; convert it to a typed array
--- a/content/canvas/src/CustomQS_WebGL.h
+++ b/content/canvas/src/CustomQS_WebGL.h
@@ -63,17 +63,17 @@ nsICanvasRenderingContextWebGL_BufferDat
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
-    JSAutoTempValueRooter tvr(cx);
+    js::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 3)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -129,17 +129,17 @@ nsICanvasRenderingContextWebGL_BufferSub
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
-    JSAutoTempValueRooter tvr(cx);
+    js::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 3)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -199,17 +199,17 @@ nsICanvasRenderingContextWebGL_TexImage2
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
-    JSAutoTempValueRooter tvr(cx);
+    js::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 3)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -301,17 +301,17 @@ nsICanvasRenderingContextWebGL_TexSubIma
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
-    JSAutoTempValueRooter tvr(cx);
+    js::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 7)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -402,17 +402,17 @@ helper_nsICanvasRenderingContextWebGL_Un
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
-    JSAutoTempValueRooter tvr(cx);
+    js::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 2)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -422,17 +422,17 @@ helper_nsICanvasRenderingContextWebGL_Un
 
     if (!JSVAL_IS_OBJECT(argv[1])) {
         xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1);
         return JS_FALSE;
     }
 
     JSObject *arg1 = JSVAL_TO_OBJECT(argv[1]);
 
-    JSAutoTempValueRooter obj_tvr(cx);
+    js::AutoValueRooter obj_tvr(cx);
 
     js::TypedArray *wa = 0;
 
     if (helper_isInt32Array(arg1)) {
         wa = js::TypedArray::fromJSObject(arg1);
     }  else if (JS_IsArrayObject(cx, arg1)) {
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_INT32, arg1);
         if (!nobj) {
@@ -472,17 +472,17 @@ helper_nsICanvasRenderingContextWebGL_Un
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
-    JSAutoTempValueRooter tvr(cx);
+    js::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 2)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -492,17 +492,17 @@ helper_nsICanvasRenderingContextWebGL_Un
 
     if (!JSVAL_IS_OBJECT(argv[1])) {
         xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1);
         return JS_FALSE;
     }
 
     JSObject *arg1 = JSVAL_TO_OBJECT(argv[1]);
 
-    JSAutoTempValueRooter obj_tvr(cx);
+    js::AutoValueRooter obj_tvr(cx);
 
     js::TypedArray *wa = 0;
 
     if (helper_isFloat32Array(arg1)) {
         wa = js::TypedArray::fromJSObject(arg1);
     }  else if (JS_IsArrayObject(cx, arg1)) {
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_FLOAT32, arg1);
         if (!nobj) {
@@ -542,17 +542,17 @@ helper_nsICanvasRenderingContextWebGL_Un
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
-    JSAutoTempValueRooter tvr(cx);
+    js::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 3)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -566,17 +566,17 @@ helper_nsICanvasRenderingContextWebGL_Un
 
     if (!JSVAL_IS_OBJECT(argv[2])) {
         xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 2);
         return JS_FALSE;
     }
 
     JSObject *arg2 = JSVAL_TO_OBJECT(argv[2]);
 
-    JSAutoTempValueRooter obj_tvr(cx);
+    js::AutoValueRooter obj_tvr(cx);
 
     js::TypedArray *wa = 0;
 
     if (helper_isFloat32Array(arg2)) {
         wa = js::TypedArray::fromJSObject(arg2);
     }  else if (JS_IsArrayObject(cx, arg2)) {
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_FLOAT32, arg2);
         if (!nobj) {
@@ -613,17 +613,17 @@ helper_nsICanvasRenderingContextWebGL_Ve
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
-    JSAutoTempValueRooter tvr(cx);
+    js::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 2)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -633,17 +633,17 @@ helper_nsICanvasRenderingContextWebGL_Ve
 
     if (!JSVAL_IS_OBJECT(argv[1])) {
         xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1);
         return JS_FALSE;
     }
 
     JSObject *arg1 = JSVAL_TO_OBJECT(argv[1]);
 
-    JSAutoTempValueRooter obj_tvr(cx);
+    js::AutoValueRooter obj_tvr(cx);
 
     js::TypedArray *wa = 0;
 
     if (helper_isFloat32Array(arg1)) {
         wa = js::TypedArray::fromJSObject(arg1);
     }  else if (JS_IsArrayObject(cx, arg1)) {
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_FLOAT32, arg1);
         if (!nobj) {
@@ -775,17 +775,17 @@ helper_nsICanvasRenderingContextWebGL_Un
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
     xpc_qsArgValArray<3> vp(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) {
         js_SetTraceableNativeFailed(cx);
         return JSVAL_VOID;
     }
 
-    JSAutoTempValueRooter obj_tvr(cx);
+    js::AutoValueRooter obj_tvr(cx);
 
     js::TypedArray *wa = 0;
 
     if (helper_isInt32Array(arg)) {
         wa = js::TypedArray::fromJSObject(arg);
     }  else if (JS_IsArrayObject(cx, arg)) {
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_INT32, arg);
         if (!nobj) {
@@ -830,17 +830,17 @@ helper_nsICanvasRenderingContextWebGL_Un
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
     xpc_qsArgValArray<3> vp(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) {
         js_SetTraceableNativeFailed(cx);
         return JSVAL_VOID;
     }
 
-    JSAutoTempValueRooter obj_tvr(cx);
+    js::AutoValueRooter obj_tvr(cx);
 
     js::TypedArray *wa = 0;
 
     if (helper_isFloat32Array(arg)) {
         wa = js::TypedArray::fromJSObject(arg);
     }  else if (JS_IsArrayObject(cx, arg)) {
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_FLOAT32, arg);
         if (!nobj) {
@@ -885,17 +885,17 @@ helper_nsICanvasRenderingContextWebGL_Un
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
     xpc_qsArgValArray<4> vp(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) {
         js_SetTraceableNativeFailed(cx);
         return JSVAL_VOID;
     }
 
-    JSAutoTempValueRooter obj_tvr(cx);
+    js::AutoValueRooter obj_tvr(cx);
 
     js::TypedArray *wa = 0;
 
     if (helper_isFloat32Array(arg)) {
         wa = js::TypedArray::fromJSObject(arg);
     }  else if (JS_IsArrayObject(cx, arg)) {
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_FLOAT32, arg);
         if (!nobj) {
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -36,16 +36,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // JavaScript includes
 #include "jsapi.h"
 #include "jsprvtd.h"    // we are using private JS typedefs...
 #include "jscntxt.h"
+#include "jsobj.h"
 #include "jsdbgapi.h"
 
 #include "nscore.h"
 #include "nsDOMClassInfo.h"
 #include "nsCRT.h"
 #include "nsCRTGlue.h"
 #include "nsIServiceManager.h"
 #include "nsICategoryManager.h"
@@ -1464,17 +1465,17 @@ jsval nsDOMClassInfo::sNodePrincipal_id 
 jsval nsDOMClassInfo::sDocumentURIObject_id=JSVAL_VOID;
 jsval nsDOMClassInfo::sOncopy_id          = JSVAL_VOID;
 jsval nsDOMClassInfo::sOncut_id           = JSVAL_VOID;
 jsval nsDOMClassInfo::sOnpaste_id         = JSVAL_VOID;
 jsval nsDOMClassInfo::sJava_id            = JSVAL_VOID;
 jsval nsDOMClassInfo::sPackages_id        = JSVAL_VOID;
 
 static const JSClass *sObjectClass = nsnull;
-const JSClass *nsDOMClassInfo::sXPCNativeWrapperClass = nsnull;
+JSPropertyOp nsDOMClassInfo::sXPCNativeWrapperGetPropertyOp = nsnull;
 
 /**
  * Set our JSClass pointer for the Object class
  */
 static void
 FindObjectClass(JSObject* aGlobalObject)
 {
   NS_ASSERTION(!sObjectClass,
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -169,43 +169,43 @@ public:
     return WrapNative(cx, scope, native, nsnull, aAllowWrapping, vp, aHolder);
   }
 
   static nsresult ThrowJSException(JSContext *cx, nsresult aResult);
 
   /**
    * Get our JSClass pointer for the XPCNativeWrapper class
    */
-  static const JSClass* GetXPCNativeWrapperClass() {
-    return sXPCNativeWrapperClass;
+  static JSPropertyOp GetXPCNativeWrapperGetPropertyOp() {
+    return sXPCNativeWrapperGetPropertyOp;
   }
 
   /**
    * Set our JSClass pointer for the XPCNativeWrapper class
    */
-  static void SetXPCNativeWrapperClass(JSClass* aClass) {
-    NS_ASSERTION(!sXPCNativeWrapperClass,
-                 "Double set of sXPCNativeWrapperClass");
-    sXPCNativeWrapperClass = aClass;
+  static void SetXPCNativeWrapperGetPropertyOp(JSPropertyOp getPropertyOp) {
+    NS_ASSERTION(!sXPCNativeWrapperGetPropertyOp,
+                 "Double set of sXPCNativeWrapperGetPropertyOp");
+    sXPCNativeWrapperGetPropertyOp = getPropertyOp;
   }
 
   static PRBool ObjectIsNativeWrapper(JSContext* cx, JSObject* obj)
   {
 #ifdef DEBUG
     {
       nsIScriptContext *scx = GetScriptContextFromJSContext(cx);
 
       NS_PRECONDITION(!scx || !scx->IsContextInitialized() ||
-                      sXPCNativeWrapperClass,
-                      "Must know what the XPCNativeWrapper class is!");
+                      sXPCNativeWrapperGetPropertyOp,
+                      "Must know what the XPCNativeWrapper class GetProperty op is!");
     }
 #endif
 
-    return sXPCNativeWrapperClass &&
-      ::JS_GET_CLASS(cx, obj) == sXPCNativeWrapperClass;
+    return sXPCNativeWrapperGetPropertyOp &&
+      ::JS_GET_CLASS(cx, obj)->getProperty == sXPCNativeWrapperGetPropertyOp;
   }
 
   static void PreserveNodeWrapper(nsIXPConnectWrappedNative *aWrapper);
 
   static nsISupports *GetNative(nsIXPConnectWrappedNative *wrapper, JSObject *obj);
 
   static nsIXPConnect *XPConnect()
   {
@@ -360,17 +360,17 @@ protected:
   static jsval sNodePrincipal_id;
   static jsval sDocumentURIObject_id;
   static jsval sOncopy_id;
   static jsval sOncut_id;
   static jsval sOnpaste_id;
   static jsval sJava_id;
   static jsval sPackages_id;
 
-  static const JSClass *sXPCNativeWrapperClass;
+  static JSPropertyOp sXPCNativeWrapperGetPropertyOp;
 };
 
 
 inline
 const nsQueryInterface
 do_QueryWrappedNative(nsIXPConnectWrappedNative *wrapper, JSObject *obj)
 {
   return nsQueryInterface(nsDOMClassInfo::GetNative(wrapper, obj));
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -2103,25 +2103,21 @@ nsJSContext::CallEventHandler(nsISupport
                               nsIArray *aargv, nsIVariant **arv)
 {
   NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
 
   if (!mScriptsEnabled) {
     return NS_OK;
   }
 
-  jsval targetVal = JSVAL_VOID;
-  JSAutoTempValueRooter tvr(mContext, 1, &targetVal);
-
   JSObject* target = nsnull;
   nsresult rv = JSObjectFromInterface(aTarget, aScope, &target);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  targetVal = OBJECT_TO_JSVAL(target);
-
+  js::AutoObjectRooter targetVal(mContext, target);
   jsval rval = JSVAL_VOID;
 
   // This one's a lot easier than EvaluateString because we don't have to
   // hassle with principals: they're already compiled into the JS function.
   // xxxmarkh - this comment is no longer true - principals are not used at
   // all now, and never were in some cases.
 
   nsCOMPtr<nsIJSContextStack> stack =
@@ -2135,17 +2131,17 @@ nsJSContext::CallEventHandler(nsISupport
   nsJSContext::TerminationFuncHolder holder(this);
 
   if (NS_SUCCEEDED(rv)) {
     // Convert args to jsvals.
     PRUint32 argc = 0;
     jsval *argv = nsnull;
 
     js::LazilyConstructed<nsAutoPoolRelease> poolRelease;
-    js::LazilyConstructed<JSAutoTempValueRooter> tvr;
+    js::LazilyConstructed<js::AutoArrayRooter> tvr;
 
     // Use |target| as the scope for wrapping the arguments, since aScope is
     // the safe scope in many cases, which isn't very useful.  Wrapping aTarget
     // was OK because those typically have PreCreate methods that give them the
     // right scope anyway, and we want to make sure that the arguments end up
     // in the same scope as aTarget.
     rv = ConvertSupportsTojsvals(aargv, target, &argc,
                                  &argv, poolRelease, tvr);
@@ -2582,18 +2578,20 @@ nsJSContext::InitContext(nsIScriptGlobal
     rv = xpc->InitClassesWithNewWrappedGlobal(mContext, aGlobalObject,
                                               NS_GET_IID(nsISupports),
                                               flags,
                                               getter_AddRefs(holder));
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Now check whether we need to grab a pointer to the
     // XPCNativeWrapper class
-    if (!nsDOMClassInfo::GetXPCNativeWrapperClass()) {
-      nsDOMClassInfo::SetXPCNativeWrapperClass(xpc->GetNativeWrapperClass());
+    if (!nsDOMClassInfo::GetXPCNativeWrapperGetPropertyOp()) {
+      JSPropertyOp getProperty;
+      xpc->GetNativeWrapperGetPropertyOp(&getProperty);
+      nsDOMClassInfo::SetXPCNativeWrapperGetPropertyOp(getProperty);
     }
   } else {
     // There's already a global object. We are preparing this outer window
     // object for use as a real outer window (i.e. everything needs to live on
     // the inner window).
 
     // Call ClearScope to nuke any properties (e.g. Function and Object) on the
     // outer object. From now on, anybody asking the outer object for these
@@ -2647,17 +2645,17 @@ nsresult
 nsJSContext::SetProperty(void *aTarget, const char *aPropName, nsISupports *aArgs)
 {
   PRUint32  argc;
   jsval    *argv = nsnull;
 
   JSAutoRequest ar(mContext);
 
   js::LazilyConstructed<nsAutoPoolRelease> poolRelease;
-  js::LazilyConstructed<JSAutoTempValueRooter> tvr;
+  js::LazilyConstructed<js::AutoArrayRooter> tvr;
 
   nsresult rv;
   rv = ConvertSupportsTojsvals(aArgs, GetNativeGlobal(), &argc,
                                &argv, poolRelease, tvr);
   NS_ENSURE_SUCCESS(rv, rv);
 
   jsval vargs;
 
@@ -2682,17 +2680,17 @@ nsJSContext::SetProperty(void *aTarget, 
 }
 
 nsresult
 nsJSContext::ConvertSupportsTojsvals(nsISupports *aArgs,
                                      void *aScope,
                                      PRUint32 *aArgc,
                                      jsval **aArgv,
                                      js::LazilyConstructed<nsAutoPoolRelease> &aPoolRelease,
-                                     js::LazilyConstructed<JSAutoTempValueRooter> &aRooter)
+                                     js::LazilyConstructed<js::AutoArrayRooter> &aRooter)
 {
   nsresult rv = NS_OK;
 
   // If the array implements nsIJSArgArray, just grab the values directly.
   nsCOMPtr<nsIJSArgArray> fastArray = do_QueryInterface(aArgs);
   if (fastArray != nsnull)
     return fastArray->GetArgs(aArgc, reinterpret_cast<void **>(aArgv));
 
--- a/dom/base/nsJSEnvironment.h
+++ b/dom/base/nsJSEnvironment.h
@@ -44,18 +44,20 @@
 #include "nsIObserver.h"
 #include "nsIXPCScriptNotify.h"
 #include "prtime.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsScriptNameSpaceManager.h"
 
 class nsIXPConnectJSObjectHolder;
 class nsAutoPoolRelease;
-class JSAutoTempValueRooter;
-namespace js { template <class> class LazilyConstructed; }
+namespace js {
+class AutoArrayRooter;
+template <class> class LazilyConstructed;
+}
 
 class nsJSContext : public nsIScriptContext,
                     public nsIXPCScriptNotify
 {
 public:
   nsJSContext(JSRuntime *aRuntime);
   virtual ~nsJSContext();
 
@@ -210,17 +212,17 @@ protected:
   nsresult InitializeExternalClasses();
 
   // Helper to convert xpcom datatypes to jsvals.
   nsresult ConvertSupportsTojsvals(nsISupports *aArgs,
                                    void *aScope,
                                    PRUint32 *aArgc,
                                    jsval **aArgv,
                                    js::LazilyConstructed<nsAutoPoolRelease> &aPoolRelease,
-                                   js::LazilyConstructed<JSAutoTempValueRooter> &aRooter);
+                                   js::LazilyConstructed<js::AutoArrayRooter> &aRooter);
 
   nsresult AddSupportsPrimitiveTojsvals(nsISupports *aArg, jsval *aArgv);
 
   // given an nsISupports object (presumably an event target or some other
   // DOM object), get (or create) the JSObject wrapping it.
   nsresult JSObjectFromInterface(nsISupports *aSup, void *aScript, 
                                  JSObject **aRet);
 
--- a/dom/src/threads/nsDOMThreadService.cpp
+++ b/dom/src/threads/nsDOMThreadService.cpp
@@ -1,9 +1,9 @@
-/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* ***** 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/
  *
@@ -499,81 +499,59 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(nsDOMWorke
  */
 
 JSBool
 DOMWorkerOperationCallback(JSContext* aCx)
 {
   nsDOMWorker* worker = (nsDOMWorker*)JS_GetContextPrivate(aCx);
   NS_ASSERTION(worker, "This must never be null!");
 
-  PRBool wasSuspended = PR_FALSE;
-  PRBool extraThreadAllowed = PR_FALSE;
-  jsrefcount suspendDepth = 0;
+  PRBool canceled = worker->IsCanceled();
+  if (!canceled && worker->IsSuspended()) {
+    JSAutoSuspendRequest suspended(aCx);
 
-  for (;;) {
-    // Kill execution if we're canceled.
-    if (worker->IsCanceled()) {
-      LOG(("Forcefully killing JS for worker [0x%p]",
-           static_cast<void*>(worker)));
+    // Since we're going to block this thread we should open up a new thread
+    // in the thread pool for other workers. Must check the return value to
+    // make sure we don't decrement when we failed.
+    PRBool extraThreadAllowed =
+      NS_SUCCEEDED(gDOMThreadService->ChangeThreadPoolMaxThreads(1));
+
+    // Flush JIT caches now before suspending to avoid holding memory that we
+    // are not going to use.
+    JS_FlushCaches(aCx);
 
-      if (wasSuspended) {
-        if (extraThreadAllowed) {
-          gDOMThreadService->ChangeThreadPoolMaxThreads(-1);
-        }
-        JS_ResumeRequest(aCx, suspendDepth);
+    for (;;) {
+      nsAutoMonitor mon(worker->Pool()->Monitor());
+
+      // There's a small chance that the worker was canceled after our check
+      // above in which case we shouldn't wait here. We're guaranteed not to
+      // race here because the pool reenters its monitor after canceling each
+      // worker in order to notify its condition variable.
+      canceled = worker->IsCanceled();
+      if (!canceled && worker->IsSuspended()) {
+        mon.Wait();
       }
-
-      // Kill execution of the currently running JS.
-      JS_ClearPendingException(aCx);
-      return JS_FALSE;
+      else {
+        break;
+      }
     }
 
-    // Break out if we're not suspended.
-    if (!worker->IsSuspended()) {
-      if (wasSuspended) {
-        if (extraThreadAllowed) {
-          gDOMThreadService->ChangeThreadPoolMaxThreads(-1);
-        }
-        JS_ResumeRequest(aCx, suspendDepth);
-      }
-      return JS_TRUE;
-    }
-
-    if (!wasSuspended) {
-      // Make sure to suspend our request while we block like this, otherwise we
-      // prevent GC for everyone.
-      suspendDepth = JS_SuspendRequest(aCx);
-
-      // Since we're going to block this thread we should open up a new thread
-      // in the thread pool for other workers. Must check the return value to
-      // make sure we don't decrement when we failed.
-      extraThreadAllowed =
-        NS_SUCCEEDED(gDOMThreadService->ChangeThreadPoolMaxThreads(1));
-
-      // Flush JIT caches now before suspending to avoid holding memory that we
-      // are not going to use.
-      JS_FlushCaches(aCx);
-
-      // Only do all this setup once.
-      wasSuspended = PR_TRUE;
-    }
-
-    nsAutoMonitor mon(worker->Pool()->Monitor());
-
-    // There's a small chance that the worker was canceled after our check
-    // above in which case we shouldn't wait here. We're guaranteed not to race
-    // here because the pool reenters its monitor after canceling each worker
-    // in order to notify its condition variable.
-    if (worker->IsSuspended() && !worker->IsCanceled()) {
-      mon.Wait();
+    if (extraThreadAllowed) {
+      gDOMThreadService->ChangeThreadPoolMaxThreads(-1);
     }
   }
 
-  NS_NOTREACHED("Should never get here!");
-  return JS_FALSE;
+  if (canceled) {
+    LOG(("Forcefully killing JS for worker [0x%p]",
+         static_cast<void*>(worker)));
+    // Kill execution of the currently running JS.
+    JS_ClearPendingException(aCx);
+    return JS_FALSE;
+  }
+  return JS_TRUE;
 }
 
 void
 DOMWorkerErrorReporter(JSContext* aCx,
                        const char* aMessage,
                        JSErrorReport* aReport)
 {
   NS_ASSERTION(!NS_IsMainThread(), "Huh?!");
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -147,16 +147,18 @@ CPPSRCS		= \
 		jslog2.cpp \
 		jsmath.cpp \
 		jsnum.cpp \
 		jsobj.cpp \
 		json.cpp \
 		jsopcode.cpp \
 		jsparse.cpp \
 		jsprf.cpp \
+		jspropertycache.cpp \
+		jspropertytree.cpp \
 		jsregexp.cpp \
 		jsscan.cpp \
 		jsscope.cpp \
 		jsscript.cpp \
 		jsstr.cpp \
 		jstask.cpp \
 		jstypedarray.cpp \
 		jsutil.cpp \
@@ -201,16 +203,19 @@ INSTALLED_HEADERS = \
 		jsobj.h \
 		jsobjinlines.h \
 		json.h \
 		jsopcode.tbl \
 		jsopcode.h \
 		jsotypes.h \
 		jsparse.h \
 		jsprf.h \
+		jspropertycache.h \
+		jspropertycacheinlines.h \
+		jspropertytree.h \
 		jsproto.tbl \
 		jsprvtd.h \
 		jspubtd.h \
 		jsregexp.h \
 		jsscan.h \
 		jsscope.h \
 		jsscript.h \
 		jsscriptinlines.h \
@@ -269,16 +274,37 @@ ifdef WINCE
 # don't need -c
 AS_DASH_C_FLAG =
 ASFLAGS += -arch 6
 ASFILES += jswince.asm
 endif
 
 endif # ENABLE_TRACEJIT
 
+ifdef JS_HAS_CTYPES
+CPPSRCS += \
+    ctypes/CTypes.cpp \
+    ctypes/Library.cpp \
+    $(NULL)
+
+LOCAL_INCLUDES = \
+    -Ictypes/libffi/include \
+    $(NULL)
+
+ifeq ($(OS_ARCH),OS2)
+# libffi builds an aout lib on OS/2; convert it to an OMF lib.
+ctypes/libffi/.libs/libffi.$(LIB_SUFFIX): ctypes/libffi/.libs/libffi.a
+	emxomf $<
+endif
+
+SHARED_LIBRARY_LIBS = \
+    ctypes/libffi/.libs/libffi.$(LIB_SUFFIX) \
+    $(NULL)
+endif # JS_HAS_CTYPES
+
 ifdef HAVE_DTRACE
 INSTALLED_HEADERS += \
 		jsdtracef.h \
 		$(CURDIR)/javascript-trace.h \
 		$(NULL)
 endif
 
 ifeq (,$(filter-out WINNT WINCE,$(OS_ARCH)))
@@ -338,16 +364,26 @@ export:: config/nsinstall$(HOST_BIN_SUFF
 
 config/nsinstall$(HOST_BIN_SUFFIX): $(srcdir)/config/nsinstall.c $(srcdir)/config/pathsub.c
 	$(MAKE) -C config/ nsinstall$(HOST_BIN_SUFFIX)
 endif
 endif
 
 include $(topsrcdir)/config/rules.mk
 
+ifdef JS_HAS_CTYPES
+# Build libffi proper as part of the 'exports' target, so things get built
+# in the right order.
+export::
+		$(call SUBMAKE,,ctypes/libffi)
+
+clean::
+		$(call SUBMAKE,clean,ctypes/libffi)
+endif
+
 ifdef MOZ_SYNC_BUILD_FILES
 # Because the SpiderMonkey can be distributed and built independently
 # of the Mozilla source tree, it contains its own copies of many of
 # the files used by the top-level Mozilla build process, from the
 # 'config' and 'build' subtrees.
 #
 # To make it simpler to keep the copies in sync, we follow the policy
 # that the SpiderMonkey copies must always be exact copies of those in
@@ -400,16 +436,20 @@ GARBAGE		+= jscpucfg.o jsautocfg.h jsaut
 ifneq (,$(CROSS_COMPILE)$(filter-out WINNT,$(OS_ARCH)))
 TARGETS		+= jscpucfg$(HOST_BIN_SUFFIX)
 endif
 
 ifdef JS_THREADSAFE
 DEFINES		+= -DJS_THREADSAFE
 endif
 
+ifdef JS_HAS_CTYPES
+DEFINES		+= -DJS_HAS_CTYPES
+endif
+
 ifdef JS_NO_THIN_LOCKS
 DEFINES		+= -DJS_USE_ONLY_NSPR_LOCKS
 endif
 
 ifdef JS_VERSION
 DEFINES		+= -DJS_VERSION=$(JS_VERSION)
 endif
 
--- a/js/src/Makefile.ref
+++ b/js/src/Makefile.ref
@@ -86,16 +86,26 @@ DEFINES += -DJS_THREADSAFE
 INCLUDES += -I$(DIST)/include/nspr
 ifdef USE_MSVC
 OTHER_LIBS += $(DIST)/lib/libnspr$(NSPR_LIBSUFFIX).lib
 else
 OTHER_LIBS += -L$(DIST)/lib -lnspr$(NSPR_LIBSUFFIX)
 endif
 endif
 
+ifdef JS_HAS_CTYPES
+DEFINES += -DJS_HAS_CTYPES
+INCLUDES += -I$(DIST)/include/nspr
+ifdef USE_MSVC
+OTHER_LIBS += $(DIST)/lib/libnspr$(NSPR_LIBSUFFIX).lib
+else
+OTHER_LIBS += -L$(DIST)/lib -lnspr$(NSPR_LIBSUFFIX)
+endif
+endif
+
 ifdef JS_NO_THIN_LOCKS
 DEFINES += -DJS_USE_ONLY_NSPR_LOCKS
 endif
 
 ifdef JS_GC_ZEAL
 DEFINES += -DJS_GC_ZEAL
 endif
 
@@ -387,16 +397,17 @@ endif
 # keeps make from concluding that js-config.h never changes.
 $(OBJDIR)/js-config.h: $(OBJDIR)/js-config.h.stamp
 	@true
 
 js-config-switch=$(if $(value $($1)),-e 's/\#undef $1/\#define $1/')
 $(OBJDIR)/js-config.h.stamp: js-config.h.in Makefile.ref
 	sed < $< > $(@:.stamp=.tmp)			\
 	    $(call js-config-switch,JS_THREADSAFE)	\
+	    $(call js-config-switch,JS_HAS_CTYPES)		\
 	    $(call js-config-switch,JS_GC_ZEAL)		\
 	    -e :dummy
 	if ! [ -f $(@:.stamp=) ] || ! cmp $(@:.stamp=.tmp) $(@:.stamp=); then \
 	    mv $(@:.stamp=.tmp) $(@:.stamp=);				      \
 	fi
 	touch $@
 
 GARBAGE += $(OBJDIR)/js-config.h $(OBJDIR)/js-config.h.stamp
--- a/js/src/config.mk
+++ b/js/src/config.mk
@@ -122,29 +122,29 @@ endif
 
 ifdef BUILD_OPT
 ifdef USE_MSVC
 OPTIMIZER  = -O2 -GL
 INTERP_OPTIMIZER = -O2 -GL
 BUILTINS_OPTIMIZER = -O2 -GL
 LDFLAGS    += -LTCG
 else
-OPTIMIZER           = -Os -fstrict-aliasing -fno-exceptions -fno-rtti -Wstrict-aliasing=2
-BUILTINS_OPTIMIZER  = -O9 -fstrict-aliasing -fno-exceptions -fno-rtti
-INTERP_OPTIMIZER    = -O3 -fstrict-aliasing -fno-exceptions -fno-rtti
+OPTIMIZER           = -Os -fno-exceptions -fno-rtti -fstrict-aliasing -Wstrict-aliasing=3
+BUILTINS_OPTIMIZER  = -O9 -fno-exceptions -fno-rtti -fstrict-aliasing
+INTERP_OPTIMIZER    = -O3 -fno-exceptions -fno-rtti -fstrict-aliasing
 endif
 DEFINES    += -UDEBUG -DNDEBUG -UDEBUG_$(USER)
 OBJDIR_TAG = _OPT
 else
 ifdef USE_MSVC
 OPTIMIZER  = -Zi
 INTERP_OPTIMIZER = -Zi
 BUILTINS_OPTIMIZER = $(INTERP_OPTIMIZER)
 else
-OPTIMIZER          = -g3 -fstrict-aliasing -fno-exceptions -fno-rtti -Wstrict-aliasing=2
+OPTIMIZER          = -g3 -fstrict-aliasing -fno-exceptions -fno-rtti -Wstrict-aliasing=3
 INTERP_OPTIMIZER   = -g3 -fstrict-aliasing -fno-exceptions -fno-rtti
 BUILTINS_OPTIMIZER = $(INTERP_OPTIMIZER)
 endif
 DEFINES    += -DDEBUG -DDEBUG_$(USER)
 OBJDIR_TAG = _DBG
 endif
 
 SO_SUFFIX = so
--- a/js/src/config/autoconf.mk.in
+++ b/js/src/config/autoconf.mk.in
@@ -87,16 +87,17 @@ MOZ_IMG_DECODERS= @MOZ_IMG_DECODERS@
 MOZ_IMG_ENCODERS= @MOZ_IMG_ENCODERS@
 MOZ_JSDEBUGGER  = @MOZ_JSDEBUGGER@
 MOZ_LEAKY	= @MOZ_LEAKY@
 MOZ_MEMORY      = @MOZ_MEMORY@
 MOZ_JPROF       = @MOZ_JPROF@
 MOZ_SHARK       = @MOZ_SHARK@
 MOZ_CALLGRIND   = @MOZ_CALLGRIND@
 MOZ_VTUNE       = @MOZ_VTUNE@
+JS_HAS_CTYPES = @JS_HAS_CTYPES@
 DEHYDRA_PATH    = @DEHYDRA_PATH@
 
 NS_TRACE_MALLOC = @NS_TRACE_MALLOC@
 INCREMENTAL_LINKER = @INCREMENTAL_LINKER@
 MACOSX_DEPLOYMENT_TARGET = @MACOSX_DEPLOYMENT_TARGET@
 BUILD_STATIC_LIBS = @BUILD_STATIC_LIBS@
 ENABLE_TESTS	= @ENABLE_TESTS@
 
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -508,16 +508,18 @@ case "$target" in
 *-cygwin*|*-mingw*|*-msvc*|*-mks*|*-wince|*-winmo)
     if test "$GCC" != "yes"; then
         # Check to see if we are really running in a msvc environemnt
         _WIN32_MSVC=1
 
         # Make sure compilers are valid
         CFLAGS="$CFLAGS -TC -nologo"
         CXXFLAGS="$CXXFLAGS -TP -nologo"
+        # MSVC warning C4345 warns of newly conformant behavior as of VS2003.
+        CXXFLAGS="$CXXFLAGS -wd4345"
         AC_LANG_SAVE
         AC_LANG_C
         AC_TRY_COMPILE([#include <stdio.h>],
             [ printf("Hello World\n"); ],,
             AC_MSG_ERROR([\$(CC) test failed.  You must have MS VC++ in your path to build.]) )
 
         AC_LANG_CPLUSPLUS
         AC_TRY_COMPILE([#include <new.h>],
@@ -4299,29 +4301,55 @@ fi
 dnl ========================================================
 dnl = Location of malloc wrapper lib
 dnl ========================================================
 MOZ_ARG_WITH_STRING(wrap-malloc,
 [  --with-wrap-malloc=DIR  Location of malloc wrapper library],
     WRAP_MALLOC_LIB=$withval)
 
 dnl ========================================================
+dnl = Build jsctypes if it's enabled
+dnl ========================================================
+MOZ_ARG_ENABLE_BOOL(ctypes,
+[  --enable-ctypes         Enable js-ctypes (default=no)],
+    JS_HAS_CTYPES=1,
+    JS_HAS_CTYPES= )
+AC_SUBST(JS_HAS_CTYPES)
+if test "$JS_HAS_CTYPES"; then
+  if test "$_MSC_VER" && test -z $AS; then
+    # Error out if we're on MSVC and MASM is unavailable.
+    AC_MSG_ERROR([No suitable assembler found. An assembler is required to build js-ctypes. If you are building with MS Visual Studio 8 Express, you may download the MASM 8.0 package, upgrade to Visual Studio 9 Express, or install the Vista SDK.])
+  fi
+  AC_DEFINE(JS_HAS_CTYPES)
+fi
+
+dnl ========================================================
 dnl = Use TraceVis
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(tracevis,
 [  --enable-tracevis       Enable TraceVis tracing tool (default=no)],
     MOZ_TRACEVIS=1,
     MOZ_TRACEVIS= )
 if test -n "$MOZ_TRACEVIS"; then
     AC_DEFINE(MOZ_TRACEVIS)
     if test -z "$ENABLE_TRACEJIT"; then
        AC_MSG_ERROR([--enable-tracevis is incompatible with --disable-tracejit])
     fi
 fi
 
+dnl ========================================================
+dnl = Use GCTimer
+dnl ========================================================
+MOZ_ARG_ENABLE_BOOL(gctimer,
+[  --enable-gctimer       Enable GC timer (default=no)],
+    MOZ_GCTIMER=1,
+    MOZ_GCTIMER= )
+if test -n "$MOZ_GCTIMER"; then
+    AC_DEFINE(MOZ_GCTIMER)
+fi
 
 dnl ========================================================
 dnl = Use Valgrind
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(valgrind,
 [  --enable-valgrind       Enable Valgrind integration hooks (default=no)],
     MOZ_VALGRIND=1,
     MOZ_VALGRIND= )
@@ -5240,16 +5268,18 @@ MOZ_DEFINES=$DEFS
 AC_SUBST(MOZ_DEFINES)
 rm -f confdefs.h
 mv confdefs.h.save confdefs.h
 
 MAKEFILES="
   Makefile
   shell/Makefile
   lirasm/Makefile
+  ctypes/Makefile
+  ctypes/tests/Makefile
   jsapi-tests/Makefile
   tests/Makefile
   config/Makefile
   config/autoconf.mk
   config/mkdepend/Makefile
 "
 
 if test -n "$JS_NATIVE_EDITLINE"; then
@@ -5290,8 +5320,60 @@ if cmp -s config/autoconf.mk config/auto
 else
   rm -f config/autoconf.mk.orig 2> /dev/null
 fi
 
 # Produce the js-config script at configure time; see the comments for
 # 'js-config' in Makefile.in.
 AC_MSG_RESULT(invoking make to create js-config script)
 $MAKE js-config
+
+# Build jsctypes if it's enabled.
+if test "$JS_HAS_CTYPES"; then
+  # Run the libffi 'configure' script.
+  ac_configure_args="--disable-shared --enable-static --disable-raw-api"
+  if test "$MOZ_DEBUG"; then
+    ac_configure_args="$ac_configure_args --enable-debug"
+  fi
+  if test "$DSO_PIC_CFLAGS"; then
+    ac_configure_args="$ac_configure_args --with-pic"
+  fi
+  if test "$CROSS_COMPILE"; then
+    case "$target" in
+    *-mingw*)
+      ac_configure_args="$ac_configure_args --build=$build --host=${target_cpu}-${target_os} HOST_CC=\"$HOST_CC\" CC=\"$CC\""
+      ;;
+    *)
+      ac_configure_args="$ac_configure_args --build=$build --host=$target HOST_CC=\"$HOST_CC\" CC=\"$CC\""
+      ;;
+    esac
+  fi
+  if test "$_MSC_VER"; then
+    # Use a wrapper script for cl and ml that looks more like gcc.
+    # autotools can't quite handle an MSVC build environment yet.
+    ac_configure_args="$ac_configure_args LD=link CPP=\"cl -nologo -EP\" SHELL=sh.exe"
+    case "${target_cpu}" in
+    x86_64)
+      # Need target since MSYS tools into mozilla-build may be 32bit
+      ac_configure_args="$ac_configure_args CC=\"$_topsrcdir/ctypes/libffi/msvcc.sh -m64\" --build=$build --host=$target"
+      ;;
+    *)
+      ac_configure_args="$ac_configure_args CC=$_topsrcdir/ctypes/libffi/msvcc.sh"
+      ;;
+    esac
+  fi
+  if test "$SOLARIS_SUNPRO_CC"; then
+    # Always use gcc for libffi on Solaris
+    ac_configure_args="$ac_configure_args CC=gcc"
+  fi
+
+  # Use a separate cache file for libffi, since it does things differently
+  # from our configure.
+  old_cache_file=$cache_file
+  cache_file=ctypes/libffi/config.cache
+  old_config_files=$CONFIG_FILES
+  unset CONFIG_FILES
+  AC_OUTPUT_SUBDIRS(ctypes/libffi)
+  cache_file=$old_cache_file
+  ac_configure_args="$_SUBDIR_CONFIG_ARGS"
+  CONFIG_FILES=$old_config_files
+fi
+
rename from js/ctypes/CTypes.cpp
rename to js/src/ctypes/CTypes.cpp
--- a/js/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -31,39 +31,34 @@
  * 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 "jscntxt.h"
 #include "CTypes.h"
 #include "Library.h"
-#include "nsAutoPtr.h"
-#include "nsUTF8Utils.h"
-#include "nsCRTGlue.h"
-#include "prlog.h"
 #include "jsdtoa.h"
 
 #include <math.h>
 #if defined(XP_WIN) || defined(XP_OS2)
 #include <float.h>
 #endif
 
 #if defined(SOLARIS)
 #include <ieeefp.h>
 #endif
 
 #ifdef HAVE_SSIZE_T
 #include <sys/types.h>
 #endif
 
-namespace mozilla {
+namespace js {
 namespace ctypes {
 
 /*******************************************************************************
 ** JSAPI function prototypes
 *******************************************************************************/
 
 static JSBool ConstructAbstract(JSContext* cx, JSObject* obj, uintN argc,
   jsval* argv, jsval* rval);
@@ -168,20 +163,20 @@ namespace CData {
     jsval* vp);
   static JSBool Address(JSContext* cx, uintN argc, jsval* vp);
   static JSBool ReadString(JSContext* cx, uintN argc, jsval* vp);
   static JSBool ToSource(JSContext* cx, uintN argc, jsval* vp);
 }
 
 // Int64Base provides functions common to Int64 and UInt64.
 namespace Int64Base {
-  JSObject* Construct(JSContext* cx, JSObject* proto, PRUint64 data,
+  JSObject* Construct(JSContext* cx, JSObject* proto, JSUint64 data,
     bool isUnsigned);
 
-  PRUint64 GetInt(JSContext* cx, JSObject* obj);
+  JSUint64 GetInt(JSContext* cx, JSObject* obj);
 
   JSBool ToString(JSContext* cx, JSObject* obj, uintN argc, jsval* vp,
     bool isUnsigned);
 
   JSBool ToSource(JSContext* cx, JSObject* obj, uintN argc, jsval* vp,
     bool isUnsigned);
 
   static void Finalize(JSContext* cx, JSObject* obj);
@@ -427,45 +422,40 @@ static JSFunctionSpec sInt64Functions[] 
 };
 
 static JSFunctionSpec sUInt64Functions[] = {
   JS_FN("toString", UInt64::ToString, 0, CTYPESFN_FLAGS),
   JS_FN("toSource", UInt64::ToSource, 0, CTYPESFN_FLAGS),
   JS_FS_END
 };
 
+static JSFunctionSpec sModuleFunctions[] = {
+  JS_FN("open", Library::Open, 1, CTYPESFN_FLAGS),
+  JS_FN("cast", CData::Cast, 2, CTYPESFN_FLAGS),
+  JS_FS_END
+};
+
 static inline bool FloatIsFinite(jsdouble f) {
 #ifdef WIN32
   return _finite(f);
 #else
   return finite(f);
 #endif
 }
 
 JS_ALWAYS_INLINE void
 ASSERT_OK(JSBool ok)
 {
   JS_ASSERT(ok);
 }
 
 JS_ALWAYS_INLINE JSString*
-NewUCString(JSContext* cx, const nsString& from)
+NewUCString(JSContext* cx, const AutoString& from)
 {
-  JS_ASSERT(from.get());
-  return JS_NewUCStringCopyN(cx,
-    reinterpret_cast<const jschar*>(from.get()), from.Length());
-}
-
-JS_ALWAYS_INLINE const nsDependentString
-GetString(JSString* str)
-{
-  JS_ASSERT(str);
-  const jschar* chars = JS_GetStringChars(str);
-  size_t length = JS_GetStringLength(str);
-  return nsDependentString(reinterpret_cast<const PRUnichar*>(chars), length);
+  return JS_NewUCStringCopyN(cx, from.begin(), from.length());
 }
 
 JS_ALWAYS_INLINE size_t
 Align(size_t val, size_t align)
 {
   return ((val - 1) | (align - 1)) + 1;
 }
 
@@ -497,17 +487,17 @@ GetErrorMessage(void* userRef, const cha
     return &ErrorFormatString[errorNumber];
   return NULL;
 }
 
 JSBool
 TypeError(JSContext* cx, const char* expected, jsval actual)
 {
   JSString* str = JS_ValueToSource(cx, actual);
-  JSAutoTempValueRooter root(cx, str);
+  js::AutoValueRooter root(cx, str);
 
   const char* src;
   if (str) {
     src = JS_GetStringBytesZ(cx, str);
     if (!src)
       return false;
   } else {
     JS_ClearPendingException(cx);
@@ -661,17 +651,17 @@ InitTypeConstructor(JSContext* cx,
 
   // Create an object to serve as the common ancestor for all CData objects
   // created from the given type constructor. This has ctypes.CData.prototype
   // as its prototype, such that it inherits the properties and functions
   // common to all CDatas.
   dataProto = JS_NewObject(cx, &sCDataProtoClass, CDataProto, parent);
   if (!dataProto)
     return false;
-  JSAutoTempValueRooter protoroot(cx, dataProto);
+  js::AutoValueRooter protoroot(cx, dataProto);
 
   // Define functions and properties on the 'dataProto' object that are common
   // to all CData objects created from this type constructor. (These will
   // become functions and properties on CData objects created from this type.)
   if (instanceFns && !JS_DefineFunctions(cx, dataProto, instanceFns))
     return false;
 
   if (instanceProps && !JS_DefineProperties(cx, dataProto, instanceProps))
@@ -720,17 +710,17 @@ InitInt64Class(JSContext* cx,
 }
 
 static JSBool
 AttachProtos(JSContext* cx, JSObject* proto, JSObject** protos)
 {
   // For a given 'proto' of [[Class]] "CTypeProto", attach each of the 'protos'
   // to the appropriate CTypeProtoSlot. (SLOT_UINT64PROTO is the last slot
   // of [[Class]] "CTypeProto".)
-  for (PRUint32 i = 0; i <= SLOT_UINT64PROTO; ++i) {
+  for (JSUint32 i = 0; i <= SLOT_UINT64PROTO; ++i) {
     if (!JS_SetReservedSlot(cx, proto, i, OBJECT_TO_JSVAL(protos[i])))
       return false;
   }
 
   return true;
 }
 
 JSBool
@@ -795,35 +785,35 @@ InitTypeClasses(JSContext* cx, JSObject*
   //     * __proto__ === 'p', the prototype object from above
   //     * 'constructor' property === 't'
   JSObject* protos[CTYPEPROTO_SLOTS];
   if (!InitTypeConstructor(cx, parent, CTypeProto, CDataProto,
          sPointerFunction, sPointerProps, sPointerInstanceFunctions,
          sPointerInstanceProps, protos[SLOT_POINTERPROTO],
          protos[SLOT_POINTERDATAPROTO]))
     return false;
-  JSAutoTempValueRooter proot(cx, protos[SLOT_POINTERDATAPROTO]);
+  js::AutoValueRooter proot(cx, protos[SLOT_POINTERDATAPROTO]);
 
   if (!InitTypeConstructor(cx, parent, CTypeProto, CDataProto,
          sArrayFunction, sArrayProps, sArrayInstanceFunctions, sArrayInstanceProps,
          protos[SLOT_ARRAYPROTO], protos[SLOT_ARRAYDATAPROTO]))
     return false;
-  JSAutoTempValueRooter aroot(cx, protos[SLOT_ARRAYDATAPROTO]);
+  js::AutoValueRooter aroot(cx, protos[SLOT_ARRAYDATAPROTO]);
 
   if (!InitTypeConstructor(cx, parent, CTypeProto, CDataProto,
          sStructFunction, sStructProps, sStructInstanceFunctions, NULL,
          protos[SLOT_STRUCTPROTO], protos[SLOT_STRUCTDATAPROTO]))
     return false;
-  JSAutoTempValueRooter sroot(cx, protos[SLOT_STRUCTDATAPROTO]);
+  js::AutoValueRooter sroot(cx, protos[SLOT_STRUCTDATAPROTO]);
 
   if (!InitTypeConstructor(cx, parent, CTypeProto, CDataProto,
          sFunctionFunction, sFunctionProps, NULL, NULL,
          protos[SLOT_FUNCTIONPROTO], protos[SLOT_FUNCTIONDATAPROTO]))
     return false;
-  JSAutoTempValueRooter froot(cx, protos[SLOT_FUNCTIONDATAPROTO]);
+  js::AutoValueRooter froot(cx, protos[SLOT_FUNCTIONDATAPROTO]);
 
   protos[SLOT_CDATAPROTO] = CDataProto;
 
   // Create and attach the ctypes.{Int64,UInt64} constructors.
   // Each of these has, respectively:
   //   * [[Class]] "Function"
   //   * __proto__ === Function.prototype
   //   * A constructor that creates a ctypes.{Int64,UInt64} object, respectively.
@@ -892,53 +882,79 @@ InitTypeClasses(JSContext* cx, JSObject*
     return false;
   if (!JS_DefineProperty(cx, parent, "voidptr_t", OBJECT_TO_JSVAL(typeObj),
          NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT))
     return false;
 
   return true;
 }
 
+JS_BEGIN_EXTERN_C
+
+JS_PUBLIC_API(JSBool)
+JS_InitCTypesClass(JSContext* cx, JSObject* global)
+{
+  // attach ctypes property to global object
+  JSObject* ctypes = JS_NewObject(cx, NULL, NULL, NULL);
+  if (!ctypes)
+    return false;
+
+  if (!JS_DefineProperty(cx, global, "ctypes", OBJECT_TO_JSVAL(ctypes),
+         NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT))
+    return false;
+
+  if (!InitTypeClasses(cx, ctypes))
+    return false;
+
+  // attach API functions
+  if (!JS_DefineFunctions(cx, ctypes, sModuleFunctions))
+    return false;
+
+  // Seal the ctypes object, to prevent modification.
+  return JS_SealObject(cx, ctypes, JS_FALSE);
+}
+
+JS_END_EXTERN_C
+
 /*******************************************************************************
 ** Type conversion functions
 *******************************************************************************/
 
 // Enforce some sanity checks on type widths.
 // Where the architecture is 64-bit, make sure it's LP64 or LLP64. (ctypes.int
 // autoconverts to a primitive JS number; to support ILP64 architectures, it
 // would need to autoconvert to an Int64 object instead. Therefore we enforce
 // this invariant here.)
-PR_STATIC_ASSERT(sizeof(bool) == 1 || sizeof(bool) == 4);
-PR_STATIC_ASSERT(sizeof(char) == 1);
-PR_STATIC_ASSERT(sizeof(short) == 2);
-PR_STATIC_ASSERT(sizeof(int) == 4);
-PR_STATIC_ASSERT(sizeof(unsigned) == 4);
-PR_STATIC_ASSERT(sizeof(long) == 4 || sizeof(long) == 8);
-PR_STATIC_ASSERT(sizeof(long long) == 8);
-PR_STATIC_ASSERT(sizeof(size_t) == sizeof(uintptr_t));
-PR_STATIC_ASSERT(sizeof(float) == 4);
-PR_STATIC_ASSERT(sizeof(jschar) == sizeof(PRUnichar));
+JS_STATIC_ASSERT(sizeof(bool) == 1 || sizeof(bool) == 4);
+JS_STATIC_ASSERT(sizeof(char) == 1);
+JS_STATIC_ASSERT(sizeof(short) == 2);
+JS_STATIC_ASSERT(sizeof(int) == 4);
+JS_STATIC_ASSERT(sizeof(unsigned) == 4);
+JS_STATIC_ASSERT(sizeof(long) == 4 || sizeof(long) == 8);
+JS_STATIC_ASSERT(sizeof(long long) == 8);
+JS_STATIC_ASSERT(sizeof(size_t) == sizeof(uintptr_t));
+JS_STATIC_ASSERT(sizeof(float) == 4);
 
 template<class IntegerType>
 static JS_ALWAYS_INLINE IntegerType
 Convert(jsdouble d)
 {
   return IntegerType(d);
 }
 
 #ifdef _MSC_VER
 // MSVC can't perform double to unsigned __int64 conversion when the
 // double is greater than 2^63 - 1. Help it along a little.
 template<>
-JS_ALWAYS_INLINE PRUint64
-Convert<PRUint64>(jsdouble d)
+JS_ALWAYS_INLINE JSUint64
+Convert<JSUint64>(jsdouble d)
 {
   return d > 0x7fffffffffffffffui64 ?
-         PRUint64(d - 0x8000000000000000ui64) + 0x8000000000000000ui64 :
-         PRUint64(d);
+         JSUint64(d - 0x8000000000000000ui64) + 0x8000000000000000ui64 :
+         JSUint64(d);
 }
 #endif
 
 template<class Type> static JS_ALWAYS_INLINE bool IsUnsigned() { return (Type(0) - Type(1)) > Type(0); }
 
 template<class FloatType> static JS_ALWAYS_INLINE bool IsDoublePrecision();
 template<> JS_ALWAYS_INLINE bool IsDoublePrecision<float> () { return false; }
 template<> JS_ALWAYS_INLINE bool IsDoublePrecision<double>() { return true; }
@@ -1043,33 +1059,33 @@ jsvalToInteger(JSContext* cx, jsval val,
       case TYPE_array:
       case TYPE_struct:
         // Not a compatible number type.
         return false;
       }
     }
 
     if (Int64::IsInt64(cx, obj)) {
-      PRInt64 i = Int64Base::GetInt(cx, obj);
+      JSInt64 i = Int64Base::GetInt(cx, obj);
       *result = IntegerType(i);
 
       // Make sure the integer fits in IntegerType.
       if (IsUnsigned<IntegerType>() && i < 0)
         return false;
-      return PRInt64(*result) == i;
+      return JSInt64(*result) == i;
     }
 
     if (UInt64::IsUInt64(cx, obj)) {
-      PRUint64 i = Int64Base::GetInt(cx, obj);
+      JSUint64 i = Int64Base::GetInt(cx, obj);
       *result = IntegerType(i);
 
       // Make sure the integer fits in IntegerType.
       if (!IsUnsigned<IntegerType>() && *result < 0)
         return false;
-      return PRUint64(*result) == i;
+      return JSUint64(*result) == i;
     }
 
     return false; 
   }
   if (JSVAL_IS_BOOLEAN(val)) {
     // Implicitly promote boolean values to 0 or 1, like C.
     *result = JSVAL_TO_BOOLEAN(val);
     JS_ASSERT(*result == 0 || *result == 1);
@@ -1179,33 +1195,33 @@ jsvalToBigInteger(JSContext* cx,
     // to the JS array element operator, which will automatically call
     // toString() on the object for us.)
     return StringToInteger(cx, JSVAL_TO_STRING(val), result);
   }
   if (!JSVAL_IS_PRIMITIVE(val)) {
     // Allow conversion from an Int64 or UInt64 object directly.
     JSObject* obj = JSVAL_TO_OBJECT(val);
     if (UInt64::IsUInt64(cx, obj)) {
-      PRUint64 i = Int64Base::GetInt(cx, obj);
+      JSUint64 i = Int64Base::GetInt(cx, obj);
       *result = IntegerType(i);
 
       // Make sure the integer fits in IntegerType.
       if (!IsUnsigned<IntegerType>() && *result < 0)
         return false;
-      return PRUint64(*result) == i;
+      return JSUint64(*result) == i;
     }
 
     if (Int64::IsInt64(cx, obj)) {
-      PRInt64 i = Int64Base::GetInt(cx, obj);
+      JSInt64 i = Int64Base::GetInt(cx, obj);
       *result = IntegerType(i);
 
       // Make sure the integer fits in IntegerType.
       if (IsUnsigned<IntegerType>() && i < 0)
         return false;
-      return PRInt64(*result) == i;
+      return JSInt64(*result) == i;
     }
   }
   return false;
 }
 
 // Implicitly convert val to a size value, where the size value is represented
 // by size_t but must also fit in a jsdouble.
 static bool
@@ -1241,22 +1257,22 @@ jsvalToIntegerExplicit(JSContext* cx, js
     jsdouble d = *JSVAL_TO_DOUBLE(val);
     *result = FloatIsFinite(d) ? IntegerType(d) : 0;
     return true;
   }
   if (!JSVAL_IS_PRIMITIVE(val)) {
     // Convert Int64 and UInt64 values by C-style cast.
     JSObject* obj = JSVAL_TO_OBJECT(val);
     if (Int64::IsInt64(cx, obj)) {
-      PRInt64 i = Int64Base::GetInt(cx, obj);
+      JSInt64 i = Int64Base::GetInt(cx, obj);
       *result = IntegerType(i);
       return true;
     }
     if (UInt64::IsUInt64(cx, obj)) {
-      PRUint64 i = Int64Base::GetInt(cx, obj);
+      JSUint64 i = Int64Base::GetInt(cx, obj);
       *result = IntegerType(i);
       return true;
     }
   }
   return false;
 }
 
 // Forcefully convert val to a pointer value when explicitly requested.
@@ -1285,62 +1301,63 @@ jsvalToPtrExplicit(JSContext* cx, jsval 
     // Don't silently lose bits here -- check that val really is an
     // integer value, and has the right sign.
     *result = Convert<uintptr_t>(d);
     return jsdouble(*result) == d;
   }
   if (!JSVAL_IS_PRIMITIVE(val)) {
     JSObject* obj = JSVAL_TO_OBJECT(val);
     if (Int64::IsInt64(cx, obj)) {
-      PRInt64 i = Int64Base::GetInt(cx, obj);
+      JSInt64 i = Int64Base::GetInt(cx, obj);
       intptr_t p = intptr_t(i);
 
       // Make sure the integer fits in the alotted precision.
-      if (PRInt64(p) != i)
+      if (JSInt64(p) != i)
         return false;
       *result = uintptr_t(p);
       return true;
     }
 
     if (UInt64::IsUInt64(cx, obj)) {
-      PRUint64 i = Int64Base::GetInt(cx, obj);
+      JSUint64 i = Int64Base::GetInt(cx, obj);
 
       // Make sure the integer fits in the alotted precision.
       *result = uintptr_t(i);
-      return PRUint64(*result) == i;
+      return JSUint64(*result) == i;
     }
   }
   return false;
 }
 
 template<class IntegerType>
-nsAutoString
-IntegerToString(IntegerType i, jsuint radix)
+void
+IntegerToString(IntegerType i, jsuint radix, AutoString& result)
 {
   // The buffer must be big enough for all the bits of IntegerType to fit,
   // in base-2, including '-'.
-  PRUnichar buffer[sizeof(IntegerType) * 8 + 1];
-  PRUnichar* cp = buffer + sizeof(buffer) / sizeof(PRUnichar);
+  jschar buffer[sizeof(IntegerType) * 8 + 1];
+  jschar* end = buffer + sizeof(buffer) / sizeof(jschar);
+  jschar* cp = end;
 
   // Build the string in reverse. We use multiplication and subtraction
   // instead of modulus because that's much faster.
   bool isNegative = !IsUnsigned<IntegerType>() && i < 0;
   size_t sign = isNegative ? -1 : 1;
   do {
     IntegerType ii = i / IntegerType(radix);
     size_t index = sign * size_t(i - ii * IntegerType(radix));
     *--cp = "0123456789abcdefghijklmnopqrstuvwxyz"[index];
     i = ii;
   } while (i != 0);
 
   if (isNegative)
     *--cp = '-';
 
   JS_ASSERT(cp >= buffer);
-  return nsAutoString(cp, buffer + sizeof(buffer) / sizeof(PRUnichar) - cp);
+  result.append(cp, end);
 }
 
 template<class IntegerType>
 static bool
 StringToInteger(JSContext* cx, JSString* string, IntegerType* result)
 {
   const jschar* cp = JS_GetStringChars(string);
   const jschar* end = cp + JS_GetStringLength(string);
@@ -1382,31 +1399,16 @@ StringToInteger(JSContext* cx, JSString*
     if (i / base != ii) // overflow
       return false;
   }
 
   *result = i;
   return true;
 }
 
-static bool
-IsUTF16(const jschar* string, size_t length)
-{
-  PRBool error;
-  const PRUnichar* buffer = reinterpret_cast<const PRUnichar*>(string);
-  const PRUnichar* end = buffer + length;
-  while (buffer != end) {
-    UTF16CharEnumerator::NextChar(&buffer, end, &error);
-    if (error)
-      return false;
-  }
-
-  return true;
-}
-
 template<class CharType>
 static size_t
 strnlen(const CharType* begin, size_t max)
 {
   for (const CharType* s = begin; s != begin + max; ++s)
     if (*s == 0)
       return s - begin;
 
@@ -1453,24 +1455,24 @@ ConvertToJS(JSContext* cx,
       *result = INT_TO_JSVAL(jsint(value));                                    \
     else if (!JS_NewNumberValue(cx, jsdouble(value), result))                  \
       return false;                                                            \
     break;                                                                     \
   }
 #define DEFINE_WRAPPED_INT_TYPE(name, type, ffiType)                           \
   case TYPE_##name: {                                                          \
     /* Return an Int64 or UInt64 object - do not convert to a JS number. */    \
-    PRUint64 value;                                                            \
+    JSUint64 value;                                                            \
     JSObject* proto;                                                           \
     if (IsUnsigned<type>()) {                                                  \
       value = *static_cast<type*>(data);                                       \
       /* Get ctypes.UInt64.prototype from ctypes.CType.prototype. */           \
       proto = CType::GetProtoFromType(cx, typeObj, SLOT_UINT64PROTO);          \
     } else {                                                                   \
-      value = PRInt64(*static_cast<type*>(data));                              \
+      value = JSInt64(*static_cast<type*>(data));                              \
       /* Get ctypes.Int64.prototype from ctypes.CType.prototype. */            \
       proto = CType::GetProtoFromType(cx, typeObj, SLOT_INT64PROTO);           \
     }                                                                          \
                                                                                \
     JSObject* obj = Int64Base::Construct(cx, proto, value, IsUnsigned<type>());\
     if (!obj)                                                                  \
       return false;                                                            \
     *result = OBJECT_TO_JSVAL(obj);                                            \
@@ -1652,31 +1654,32 @@ ImplicitConvert(JSContext* cx,
       const jschar* sourceChars = JS_GetStringChars(sourceString);
       size_t sourceLength = JS_GetStringLength(sourceString);
 
       switch (CType::GetTypeCode(cx, baseType)) {
       case TYPE_char:
       case TYPE_signed_char:
       case TYPE_unsigned_char: {
         // Convert from UTF-16 to UTF-8.
-        if (!IsUTF16(sourceChars, sourceLength))
-          return TypeError(cx, "UTF-16 string", val);
-
-        NS_ConvertUTF16toUTF8 converted(
-          reinterpret_cast<const PRUnichar*>(sourceChars), sourceLength);
+        size_t nbytes =
+          js_GetDeflatedUTF8StringLength(cx, sourceChars, sourceLength);
+        if (nbytes == (size_t) -1)
+          return false;
 
         char** charBuffer = static_cast<char**>(buffer);
-        *charBuffer = new char[converted.Length() + 1];
+        *charBuffer = new char[nbytes + 1];
         if (!*charBuffer) {
           JS_ReportAllocationOverflow(cx);
           return false;
         }
 
+        ASSERT_OK(js_DeflateStringToUTF8Buffer(cx, sourceChars, sourceLength,
+                    *charBuffer, &nbytes));
+        (*charBuffer)[nbytes] = 0;
         *freePointer = true;
-        memcpy(*charBuffer, converted.get(), converted.Length() + 1);
         break;
       }
       case TYPE_jschar: {
         // Copy the jschar string data. (We could provide direct access to the
         // JSString's buffer, but this approach is safer if the caller happens
         // to modify the string.)
         jschar** jscharBuffer = static_cast<jschar**>(buffer);
         *jscharBuffer = new jschar[sourceLength + 1];
@@ -1714,30 +1717,32 @@ ImplicitConvert(JSContext* cx,
       const jschar* sourceChars = JS_GetStringChars(sourceString);
       size_t sourceLength = JS_GetStringLength(sourceString);
 
       switch (CType::GetTypeCode(cx, baseType)) {
       case TYPE_char:
       case TYPE_signed_char:
       case TYPE_unsigned_char: {
         // Convert from UTF-16 to UTF-8.
-        if (!IsUTF16(sourceChars, sourceLength))
-          return TypeError(cx, "UTF-16 string", val);
-
-        NS_ConvertUTF16toUTF8 converted(
-          reinterpret_cast<const PRUnichar*>(sourceChars), sourceLength);
-
-        if (targetLength < converted.Length()) {
+        size_t nbytes =
+          js_GetDeflatedUTF8StringLength(cx, sourceChars, sourceLength);
+        if (nbytes == (size_t) -1)
+          return false;
+
+        if (targetLength < nbytes) {
           JS_ReportError(cx, "ArrayType has insufficient length");
           return false;
         }
 
-        memcpy(buffer, converted.get(), converted.Length());
-        if (targetLength > converted.Length())
-          static_cast<char*>(buffer)[converted.Length()] = 0;
+        char* charBuffer = static_cast<char*>(buffer);
+        ASSERT_OK(js_DeflateStringToUTF8Buffer(cx, sourceChars, sourceLength,
+                    charBuffer, &nbytes));
+
+        if (targetLength > nbytes)
+          charBuffer[nbytes] = 0;
 
         break;
       }
       case TYPE_jschar: {
         // Copy the string data, jschar for jschar, including the terminator
         // if there's space.
         if (targetLength < sourceLength) {
           JS_ReportError(cx, "ArrayType has insufficient length");
@@ -1763,104 +1768,103 @@ ImplicitConvert(JSContext* cx,
           targetLength != size_t(sourceLength)) {
         JS_ReportError(cx, "ArrayType length does not match source array length");
         return false;
       }
 
       // Convert into an intermediate, in case of failure.
       size_t elementSize = CType::GetSize(cx, baseType);
       size_t arraySize = elementSize * targetLength;
-      nsAutoArrayPtr<char> intermediate(new char[arraySize]);
+      AutoPtr<char>::Array intermediate(new char[arraySize]);
       if (!intermediate) {
         JS_ReportAllocationOverflow(cx);
         return false;
       }
 
       for (jsuint i = 0; i < sourceLength; ++i) {
-        JSAutoTempValueRooter item(cx);
+        js::AutoValueRooter item(cx);
         if (!JS_GetElement(cx, sourceArray, i, item.addr()))
           return false;
 
-        char* data = intermediate + elementSize * i;
+        char* data = intermediate.get() + elementSize * i;
         if (!ImplicitConvert(cx, item.value(), baseType, data, false, NULL))
           return false;
       }
 
-      memcpy(buffer, intermediate, arraySize);
+      memcpy(buffer, intermediate.get(), arraySize);
 
     } else {
       // Don't implicitly convert to string. Users can implicitly convert
       // with `String(x)` or `""+x`.
       return TypeError(cx, "array", val);
     }
     break;
   }
   case TYPE_struct: {
     if (!JSVAL_IS_PRIMITIVE(val) && !sourceData) {
-      nsTArray<FieldInfo>* fields = StructType::GetFieldInfo(cx, targetType);
-
       // Enumerate the properties of the object; if they match the struct
       // specification, convert the fields.
       JSObject* obj = JSVAL_TO_OBJECT(val);
       JSObject* iter = JS_NewPropertyIterator(cx, obj);
       if (!iter)
         return false;
-      JSAutoTempValueRooter iterroot(cx, iter);
+      js::AutoValueRooter iterroot(cx, iter);
 
       // Convert into an intermediate, in case of failure.
       size_t structSize = CType::GetSize(cx, targetType);
-      nsAutoArrayPtr<char> intermediate(new char[structSize]);
+      AutoPtr<char>::Array intermediate(new char[structSize]);
       if (!intermediate) {
         JS_ReportAllocationOverflow(cx);
         return false;
       }
 
       jsid id;
-      jsuint i = 0;
+      size_t i = 0;
       while (1) {
         if (!JS_NextProperty(cx, iter, &id))
           return false;
         if (JSVAL_IS_VOID(id))
           break;
 
-        JSAutoTempValueRooter fieldVal(cx);
+        js::AutoValueRooter fieldVal(cx);
         if (!JS_IdToValue(cx, id, fieldVal.addr()))
           return false;
         if (!JSVAL_IS_STRING(fieldVal.value())) {
           JS_ReportError(cx, "property name is not a string");
           return false;
         }
 
         FieldInfo* field = StructType::LookupField(cx, targetType,
           fieldVal.value());
         if (!field)
           return false;
 
         JSString* nameStr = JSVAL_TO_STRING(fieldVal.value());
         const jschar* name = JS_GetStringChars(nameStr);
         size_t namelen = JS_GetStringLength(nameStr);
 
-        JSAutoTempValueRooter prop(cx);
+        js::AutoValueRooter prop(cx);
         if (!JS_GetUCProperty(cx, obj, name, namelen, prop.addr()))
           return false;
 
         // Convert the field via ImplicitConvert().
-        char* fieldData = intermediate + field->mOffset;
+        char* fieldData = intermediate.get() + field->mOffset;
         if (!ImplicitConvert(cx, prop.value(), field->mType, fieldData, false, NULL))
           return false;
 
         ++i;
       }
 
-      if (i != fields->Length()) {
+      Array<FieldInfo>* fields = StructType::GetFieldInfo(cx, targetType);
+      if (i != fields->length()) {
         JS_ReportError(cx, "missing fields");
         return false;
       }
 
-      memcpy(buffer, intermediate, structSize);
+      memcpy(buffer, intermediate.get(), structSize);
       break;
     }
 
     return TypeError(cx, "struct", val);
   }
   case TYPE_void_t:
     JS_NOT_REACHED("invalid type");
     return false;
@@ -1877,17 +1881,17 @@ ExplicitConvert(JSContext* cx, jsval val
 {
   // If ImplicitConvert succeeds, use that result.
   if (ImplicitConvert(cx, val, targetType, buffer, false, NULL))
     return true;
 
   // If ImplicitConvert failed, and there is no pending exception, then assume
   // hard failure (out of memory, or some other similarly serious condition).
   // We store any pending exception in case we need to re-throw it.
-  JSAutoTempValueRooter ex(cx);
+  js::AutoValueRooter ex(cx);
   if (!JS_GetPendingException(cx, ex.addr()))
     return false;
 
   // Otherwise, assume soft failure. Clear the pending exception so that we
   // can throw a different one as required.
   JS_ClearPendingException(cx);
 
   TypeCode type = CType::GetTypeCode(cx, targetType);
@@ -1947,385 +1951,397 @@ ExplicitConvert(JSContext* cx, jsval val
   }
   return true;
 }
 
 // Given a CType 'typeObj', generate a string describing the C type declaration
 // corresponding to 'typeObj'. For instance, the CType constructed from
 // 'ctypes.int32_t.ptr.array(4).ptr.ptr' will result in the type string
 // 'int32_t*(**)[4]'.
-static nsAutoString
+static JSString*
 BuildTypeName(JSContext* cx, JSObject* typeObj)
 {
+  AutoString result;
+
   // Walk the hierarchy of types, outermost to innermost, building up the type
   // string. This consists of the base type, which goes on the left.
   // Derived type modifiers (* and []) build from the inside outward, with
   // pointers on the left and arrays on the right. An excellent description
   // of the rules for building C type declarations can be found at:
   // http://unixwiz.net/techtips/reading-cdecl.html
-  nsAutoString result;
   JSObject* currentType = typeObj;
   JSObject* nextType;
   TypeCode prevGrouping = CType::GetTypeCode(cx, currentType), currentGrouping;
   while (1) {
     currentGrouping = CType::GetTypeCode(cx, currentType);
     switch (currentGrouping) {
     case TYPE_pointer: {
       nextType = PointerType::GetBaseType(cx, currentType);
       if (!nextType) {
         // Opaque pointer type. Use the type's name as the base type.
         break;
       }
 
       // Pointer types go on the left.
-      result.Insert('*', 0);
+      PrependString(result, "*");
 
       currentType = nextType;
       prevGrouping = currentGrouping;
       continue;
     }
     case TYPE_array: {
       if (prevGrouping == TYPE_pointer) {
         // Outer type is pointer, inner type is array. Grouping is required.
-        result.Insert('(', 0);
-        result.Append(')');
-      }
+        PrependString(result, "(");
+        AppendString(result, ")");
+      } 
 
       // Array types go on the right.
-      result.Append('[');
+      AppendString(result, "[");
       size_t length;
-      if (ArrayType::GetSafeLength(cx, currentType, &length)) {
-        result.Append(IntegerToString(length, 10));
-      }
-      result.Append(']');
+      if (ArrayType::GetSafeLength(cx, currentType, &length))
+        IntegerToString(length, 10, result);
+
+      AppendString(result, "]");
 
       currentType = ArrayType::GetBaseType(cx, currentType);
       prevGrouping = currentGrouping;
       continue;
     }
     case TYPE_function: {
       FunctionInfo* fninfo = FunctionType::GetFunctionInfo(cx, currentType);
 
       // Function pointer goes on the left.
-      result.Insert('*', 0);
+      PrependString(result, "*");
 
       // Add in the calling convention, if it's not cdecl.
       if (GetABICode(cx, fninfo->mABI) == ABI_STDCALL)
-        result.Insert(NS_LITERAL_STRING("__stdcall "), 0);
+        PrependString(result, "__stdcall ");
 
       // Wrap the entire expression so far with parens.
-      result.Insert('(', 0);
-      result.Append(')');
+      PrependString(result, "(");
+      AppendString(result, ")");
 
       // Argument list goes on the right.
-      result.Append('(');
-      for (PRUint32 i = 0; i < fninfo->mArgTypes.Length(); ++i) {
+      AppendString(result, "(");
+      for (size_t i = 0; i < fninfo->mArgTypes.length(); ++i) {
         JSString* argName = CType::GetName(cx, fninfo->mArgTypes[i]);
-        result.Append(GetString(argName));
-        if (i != fninfo->mArgTypes.Length() - 1 ||
+        AppendString(result, argName);
+        if (i != fninfo->mArgTypes.length() - 1 ||
             fninfo->mIsVariadic)
-          result.Append(NS_LITERAL_STRING(", "));
+          AppendString(result, ", ");
       }
       if (fninfo->mIsVariadic)
-        result.Append(NS_LITERAL_STRING("..."));
-      result.Append(')');
+        AppendString(result, "...");
+      AppendString(result, ")");
 
       // Set 'currentType' to the return type, and let the loop process it.
       currentType = fninfo->mReturnType;
       prevGrouping = currentGrouping;
       continue;
     }
     default:
       // Either a basic or struct type. Use the type's name as the base type.
       break;
     }
     break;
   }
 
   // Stick the base type and derived type parts together.
   JSString* baseName = CType::GetName(cx, currentType);
-  result.Insert(GetString(baseName), 0);
-  return result;
+  PrependString(result, baseName);
+  return NewUCString(cx, result);
 }
 
 // Given a CType 'typeObj', generate a string 'result' such that 'eval(result)'
 // would construct the same CType. If 'makeShort' is true, assume that any
 // StructType 't' is bound to an in-scope variable of name 't.name', and use
 // that variable in place of generating a string to construct the type 't'.
 // (This means the type comparison function CType::TypesEqual will return true
 // when comparing the input and output of BuildTypeSource, since struct
 // equality is determined by strict JSObject pointer equality.)
-static nsAutoString
-BuildTypeSource(JSContext* cx, JSObject* typeObj, bool makeShort)
+static void
+BuildTypeSource(JSContext* cx,
+                JSObject* typeObj, 
+                bool makeShort, 
+                AutoString& result)
 {
   // Walk the types, building up the toSource() string.
-  nsAutoString result;
   switch (CType::GetTypeCode(cx, typeObj)) {
   case TYPE_void_t:
 #define DEFINE_TYPE(name, type, ffiType)  \
   case TYPE_##name:
 #include "typedefs.h"
   {
-    result.Append(NS_LITERAL_STRING("ctypes."));
+    AppendString(result, "ctypes.");
     JSString* nameStr = CType::GetName(cx, typeObj);
-    result.Append(GetString(nameStr));
+    AppendString(result, nameStr);
     break;
   }
   case TYPE_pointer: {
     JSObject* baseType = PointerType::GetBaseType(cx, typeObj);
     if (!baseType) {
       // Opaque pointer type. Use the type's name.
-      result.Append(NS_LITERAL_STRING("ctypes.PointerType(\""));
+      AppendString(result, "ctypes.PointerType(\"");
       JSString* baseName = CType::GetName(cx, typeObj);
-      result.Append(GetString(baseName));
-      result.Append(NS_LITERAL_STRING("\")"));
+      AppendString(result, baseName);
+      AppendString(result, "\")");
       break;
     }
 
     // Specialcase ctypes.voidptr_t.
     if (CType::GetTypeCode(cx, baseType) == TYPE_void_t) {
-      result.Append(NS_LITERAL_STRING("ctypes.voidptr_t"));
+      AppendString(result, "ctypes.voidptr_t");
       break;
     }
 
     // Recursively build the source string, and append '.ptr'.
-    result.Append(BuildTypeSource(cx, baseType, makeShort));
-    result.Append(NS_LITERAL_STRING(".ptr"));
+    BuildTypeSource(cx, baseType, makeShort, result);
+    AppendString(result, ".ptr");
     break;
   }
   case TYPE_function: {
     FunctionInfo* fninfo = FunctionType::GetFunctionInfo(cx, typeObj);
 
-    result.Append(NS_LITERAL_STRING("ctypes.FunctionType("));
+    AppendString(result, "ctypes.FunctionType(");
 
     switch (GetABICode(cx, fninfo->mABI)) {
     case ABI_DEFAULT:
-      result.Append(NS_LITERAL_STRING("ctypes.default_abi, "));
+      AppendString(result, "ctypes.default_abi, ");
       break;
     case ABI_STDCALL:
-      result.Append(NS_LITERAL_STRING("ctypes.stdcall_abi, "));
+      AppendString(result, "ctypes.stdcall_abi, ");
       break;
     case INVALID_ABI:
       JS_NOT_REACHED("invalid abi");
       break;
     }
 
     // Recursively build the source string describing the function return and
     // argument types.
-    result.Append(BuildTypeSource(cx, fninfo->mReturnType, true));
-
-    if (fninfo->mArgTypes.Length() > 0) {
-      result.Append(NS_LITERAL_STRING(", ["));
-      for (PRUint32 i = 0; i < fninfo->mArgTypes.Length(); ++i) {
-        result.Append(BuildTypeSource(cx, fninfo->mArgTypes[i], true));
-        if (i != fninfo->mArgTypes.Length() - 1 ||
+    BuildTypeSource(cx, fninfo->mReturnType, true, result);
+
+    if (fninfo->mArgTypes.length() > 0) {
+      AppendString(result, ", [");
+      for (size_t i = 0; i < fninfo->mArgTypes.length(); ++i) {
+        BuildTypeSource(cx, fninfo->mArgTypes[i], true, result);
+        if (i != fninfo->mArgTypes.length() - 1 ||
             fninfo->mIsVariadic)
-          result.Append(NS_LITERAL_STRING(", "));
+          AppendString(result, ", ");
       }
       if (fninfo->mIsVariadic)
-        result.Append(NS_LITERAL_STRING("\"...\""));
-      result.Append(']');
+        AppendString(result, "\"...\"");
+      AppendString(result, "]");
     }
 
-    result.Append(')');
+    AppendString(result, ")");
     break;
   }
   case TYPE_array: {
     // Recursively build the source string, and append '.array(n)',
     // where n is the array length, or the empty string if the array length
     // is undefined.
     JSObject* baseType = ArrayType::GetBaseType(cx, typeObj);
-    result.Append(BuildTypeSource(cx, baseType, makeShort));
-    result.Append(NS_LITERAL_STRING(".array("));
+    BuildTypeSource(cx, baseType, makeShort, result);
+    AppendString(result, ".array(");
 
     size_t length;
     if (ArrayType::GetSafeLength(cx, typeObj, &length))
-      result.Append(IntegerToString(length, 10));
-
-    result.Append(')');
+      IntegerToString(length, 10, result);
+
+    AppendString(result, ")");
     break;
   }
   case TYPE_struct: {
     JSString* name = CType::GetName(cx, typeObj);
 
     if (makeShort) {
       // Shorten the type declaration by assuming that StructType 't' is bound
       // to an in-scope variable of name 't.name'.
-      result.Append(GetString(name));
+      AppendString(result, name);
       break;
     }
 
     // Write the full struct declaration.
-    result.Append(NS_LITERAL_STRING("ctypes.StructType(\""));
-    result.Append(GetString(name));
-    result.Append(NS_LITERAL_STRING("\", ["));
-
-    nsTArray<FieldInfo>* fields = StructType::GetFieldInfo(cx, typeObj);
-    for (PRUint32 i = 0; i < fields->Length(); ++i) {
-      const FieldInfo& field = fields->ElementAt(i);
-      result.Append(NS_LITERAL_STRING("{ \""));
-      result.Append(field.mName);
-      result.Append(NS_LITERAL_STRING("\": "));
-      result.Append(BuildTypeSource(cx, field.mType, true));
-      result.Append(NS_LITERAL_STRING(" }"));
-      if (i != fields->Length() - 1)
-        result.Append(NS_LITERAL_STRING(", "));
+    AppendString(result, "ctypes.StructType(\"");
+    AppendString(result, name);
+    AppendString(result, "\", [");
+
+    Array<FieldInfo>* fields = StructType::GetFieldInfo(cx, typeObj);
+    for (size_t i = 0; i < fields->length(); ++i) {
+      FieldInfo* field = fields->begin() + i;
+      AppendString(result, "{ \"");
+      AppendString(result, field->mName);
+      AppendString(result, "\": ");
+      BuildTypeSource(cx, field->mType, true, result);
+      AppendString(result, " }");
+      if (i != fields->length() - 1)
+        AppendString(result, ", ");
     }
 
-    result.Append(NS_LITERAL_STRING("])"));
+    AppendString(result, "])");
     break;
   }
   }
-
-  return result;
 }
 
 // Given a CData object of CType 'typeObj' with binary value 'data', generate a
 // string 'result' such that 'eval(result)' would construct a CData object with
 // the same CType and containing the same binary value. This assumes that any
 // StructType 't' is bound to an in-scope variable of name 't.name'. (This means
 // the type comparison function CType::TypesEqual will return true when
 // comparing the types, since struct equality is determined by strict JSObject
 // pointer equality.) Further, if 'isImplicit' is true, ensure that the
 // resulting string can ImplicitConvert successfully if passed to another data
 // constructor. (This is important when called recursively, since fields of
 // structs and arrays are converted with ImplicitConvert.)
-static nsAutoString
-BuildDataSource(JSContext* cx, JSObject* typeObj, void* data, bool isImplicit)
+static JSBool
+BuildDataSource(JSContext* cx,
+                JSObject* typeObj, 
+                void* data, 
+                bool isImplicit, 
+                AutoString& result)
 {
-  nsAutoString result;
   TypeCode type = CType::GetTypeCode(cx, typeObj);
   switch (type) {
   case TYPE_bool:
-    result.Append(*static_cast<bool*>(data) ?
-                  NS_LITERAL_STRING("true") :
-                  NS_LITERAL_STRING("false"));
+    if (*static_cast<bool*>(data))
+      AppendString(result, "true");
+    else
+      AppendString(result, "false");
     break;
 #define DEFINE_INT_TYPE(name, type, ffiType)                                   \
   case TYPE_##name:                                                            \
     /* Serialize as a primitive decimal integer. */                            \
-    result.Append(IntegerToString(*static_cast<type*>(data), 10));             \
+    IntegerToString(*static_cast<type*>(data), 10, result);                    \
     break;
 #define DEFINE_WRAPPED_INT_TYPE(name, type, ffiType)                           \
   case TYPE_##name:                                                            \
     /* Serialize as a wrapped decimal integer. */                              \
     if (IsUnsigned<type>())                                                    \
-      result.Append(NS_LITERAL_STRING("ctypes.UInt64(\""));                    \
+      AppendString(result, "ctypes.UInt64(\"");                                \
     else                                                                       \
-      result.Append(NS_LITERAL_STRING("ctypes.Int64(\""));                     \
+      AppendString(result, "ctypes.Int64(\"");                                 \
                                                                                \
-    result.Append(IntegerToString(*static_cast<type*>(data), 10));             \
-    result.Append(NS_LITERAL_STRING("\")"));                                   \
+    IntegerToString(*static_cast<type*>(data), 10, result);                    \
+    AppendString(result, "\")");                                               \
     break;
 #define DEFINE_FLOAT_TYPE(name, type, ffiType)                                 \
   case TYPE_##name: {                                                          \
     /* Serialize as a primitive double. */                                     \
     double fp = *static_cast<type*>(data);                                     \
     char buf[DTOSTR_STANDARD_BUFFER_SIZE];                                     \
-    char* str = JS_dtostr(buf, sizeof(buf), DTOSTR_STANDARD, 0, fp);           \
-    JS_ASSERT(str);                                                            \
-    if (!str)                                                                  \
-      break;                                                                   \
+    char* str = js_dtostr(JS_THREAD_DATA(cx)->dtoaState, buf, sizeof(buf),     \
+                          DTOSTR_STANDARD, 0, fp);                             \
+    if (!str) {                                                                \
+      JS_ReportOutOfMemory(cx);                                                \
+      return false;                                                            \
+    }                                                                          \
                                                                                \
-    result.AppendASCII(str);                                                   \
+    result.append(str, strlen(str));                                           \
     break;                                                                     \
   }
 #define DEFINE_CHAR_TYPE(name, type, ffiType)                                  \
   case TYPE_##name:                                                            \
     /* Serialize as an integer. */                                             \
-    result.Append(IntegerToString(*static_cast<type*>(data), 10));             \
+    IntegerToString(*static_cast<type*>(data), 10, result);                    \
     break;
 #include "typedefs.h"
   case TYPE_jschar: {
-    /* Serialize as a 1-character JS string. */
+    // Serialize as a 1-character JS string.
     JSString* str = JS_NewUCStringCopyN(cx, static_cast<jschar*>(data), 1);
     if (!str)
-      break;
-
+      return false;
+
+    // Escape characters, and quote as necessary.
     JSString* src = JS_ValueToSource(cx, STRING_TO_JSVAL(str));
     if (!src)
-      break;
-
-    result.Append(GetString(src));
+      return false;
+
+    AppendString(result, src);
     break;
   }
   case TYPE_pointer:
   case TYPE_function: {
     if (isImplicit) {
       // The result must be able to ImplicitConvert successfully.
       // Wrap in a type constructor, then serialize for ExplicitConvert.
-      result.Append(BuildTypeSource(cx, typeObj, true));
-      result.Append('(');
+      BuildTypeSource(cx, typeObj, true, result);
+      AppendString(result, "(");
     }
 
     // Serialize the pointer value as a wrapped hexadecimal integer.
     uintptr_t ptr = *static_cast<uintptr_t*>(data);
-    result.Append(NS_LITERAL_STRING("ctypes.UInt64(\"0x"));
-    result.Append(IntegerToString(ptr, 16));
-    result.Append(NS_LITERAL_STRING("\")"));
+    AppendString(result, "ctypes.UInt64(\"0x");
+    IntegerToString(ptr, 16, result);
+    AppendString(result, "\")");
 
     if (isImplicit)
-      result.Append(')');
+      AppendString(result, ")");
 
     break;
   }
   case TYPE_array: {
     // Serialize each element of the array recursively. Each element must
     // be able to ImplicitConvert successfully.
     JSObject* baseType = ArrayType::GetBaseType(cx, typeObj);
-    result.Append('[');
+    AppendString(result, "[");
 
     size_t length = ArrayType::GetLength(cx, typeObj);
     size_t elementSize = CType::GetSize(cx, baseType);
     for (size_t i = 0; i < length; ++i) {
       char* element = static_cast<char*>(data) + elementSize * i;
-      result.Append(BuildDataSource(cx, baseType, element, true));
+      if (!BuildDataSource(cx, baseType, element, true, result))
+        return false;
+
       if (i + 1 < length)
-        result.Append(NS_LITERAL_STRING(", "));
+        AppendString(result, ", ");
     }
-    result.Append(']');
+    AppendString(result, "]");
     break;
   }
   case TYPE_struct: {
     if (isImplicit) {
       // The result must be able to ImplicitConvert successfully.
       // Serialize the data as an object with properties, rather than
       // a sequence of arguments to the StructType constructor.
-      result.Append('{');
+      AppendString(result, "{");
     }
 
     // Serialize each field of the struct recursively. Each field must
     // be able to ImplicitConvert successfully.
-    nsTArray<FieldInfo>* fields = StructType::GetFieldInfo(cx, typeObj);
-    for (size_t i = 0; i < fields->Length(); ++i) {
-      const FieldInfo& field = fields->ElementAt(i);
-      char* fieldData = static_cast<char*>(data) + field.mOffset;
+    Array<FieldInfo>* fields = StructType::GetFieldInfo(cx, typeObj);
+    for (size_t i = 0; i < fields->length(); ++i) {
+      FieldInfo* field = fields->begin() + i;
+      char* fieldData = static_cast<char*>(data) + field->mOffset;
 
       if (isImplicit) {
-        result.Append('"');
-        result.Append(field.mName);
-        result.Append(NS_LITERAL_STRING("\": "));
+        AppendString(result, "\"");
+        AppendString(result, field->mName);
+        AppendString(result, "\": ");
       }
 
-      result.Append(BuildDataSource(cx, field.mType, fieldData, true));
-      if (i + 1 != fields->Length())
-        result.Append(NS_LITERAL_STRING(", "));
+      if (!BuildDataSource(cx, field->mType, fieldData, true, result))
+        return false;
+
+      if (i + 1 != fields->length())
+        AppendString(result, ", ");
     }
 
     if (isImplicit)
-      result.Append('}');
+      AppendString(result, "}");
 
     break;
   }
   case TYPE_void_t:
     JS_NOT_REACHED("invalid type");
     break;
   }
 
-  return result;
+  return true;
 }
 
 /*******************************************************************************
 ** JSAPI callback function implementations
 *******************************************************************************/
 
 JSBool
 ConstructAbstract(JSContext* cx,
@@ -2433,31 +2449,31 @@ CType::Create(JSContext* cx,
   //       'typeProto'. (For instance, this could be ctypes.CData.prototype
   //       for simple types, or something representing structs for StructTypes.)
   //     * 'constructor' property === 't'
   //     * Additional properties specified by 'ps', as appropriate for the
   //       specific type instance 't'.
   JSObject* typeObj = JS_NewObject(cx, &sCTypeClass, typeProto, parent);
   if (!typeObj)
     return NULL;
-  JSAutoTempValueRooter root(cx, typeObj);
+  js::AutoValueRooter root(cx, typeObj);
 
   // Set up the reserved slots.
   if (!JS_SetReservedSlot(cx, typeObj, SLOT_TYPECODE, INT_TO_JSVAL(type)) ||
       !JS_SetReservedSlot(cx, typeObj, SLOT_FFITYPE, PRIVATE_TO_JSVAL(ffiType)) ||
       (name && !JS_SetReservedSlot(cx, typeObj, SLOT_NAME, STRING_TO_JSVAL(name))) ||
       !JS_SetReservedSlot(cx, typeObj, SLOT_SIZE, size) ||
       !JS_SetReservedSlot(cx, typeObj, SLOT_ALIGN, align))
     return NULL;
 
   // Set up the 'prototype' and 'prototype.constructor' properties.
   JSObject* prototype = JS_NewObject(cx, &sCDataProtoClass, dataProto, parent);
   if (!prototype)
     return NULL;
-  JSAutoTempValueRooter protoroot(cx, prototype);
+  js::AutoValueRooter protoroot(cx, prototype);
 
   if (!JS_DefineProperty(cx, prototype, "constructor", OBJECT_TO_JSVAL(typeObj),
          NULL, NULL, JSPROP_READONLY | JSPROP_PERMANENT))
     return NULL;
 
   // If required, define properties on the 'prototype' object. (These will
   // become properties on CData objects created from this CType.)
   if (ps) {
@@ -2496,17 +2512,17 @@ CType::DefineBuiltin(JSContext* cx,
                      TypeCode type,
                      jsval size,
                      jsval align,
                      ffi_type* ffiType)
 {
   JSString* nameStr = JS_NewStringCopyZ(cx, name);
   if (!nameStr)
     return NULL;
-  JSAutoTempValueRooter nameRoot(cx, nameStr);
+  js::AutoValueRooter nameRoot(cx, nameStr);
 
   // Create a new CType object with the common properties and slots.
   JSObject* typeObj = Create(cx, typeProto, dataProto, type, nameStr, size,
                         align, ffiType, NULL);
   if (!typeObj)
     return NULL;
 
   // Define the CType as a 'propName' property on 'parent'.
@@ -2532,18 +2548,20 @@ CType::Finalize(JSContext* cx, JSObject*
     ASSERT_OK(JS_GetReservedSlot(cx, obj, SLOT_FNINFO, &slot));
     if (!JSVAL_IS_VOID(slot))
       delete static_cast<FunctionInfo*>(JSVAL_TO_PRIVATE(slot));
     break;
   }
   case TYPE_struct:
     // Free the FieldInfo array.
     ASSERT_OK(JS_GetReservedSlot(cx, obj, SLOT_FIELDINFO, &slot));
-    if (!JSVAL_IS_VOID(slot))
-      delete static_cast<nsTArray<FieldInfo>*>(JSVAL_TO_PRIVATE(slot));
+    if (!JSVAL_IS_VOID(slot)) {
+      void* info = JSVAL_TO_PRIVATE(slot);
+      delete static_cast<js::ctypes::Array<FieldInfo>*>(info);
+    }
 
     // Fall through.
   case TYPE_array: {
     // Free the ffi_type info.
     jsval slot;
     ASSERT_OK(JS_GetReservedSlot(cx, obj, SLOT_FFITYPE, &slot));
     if (!JSVAL_IS_VOID(slot) && JSVAL_TO_PRIVATE(slot)) {
       ffi_type* ffiType = static_cast<ffi_type*>(JSVAL_TO_PRIVATE(slot));
@@ -2593,17 +2611,17 @@ CType::Trace(JSTracer* trc, JSObject* ob
       return;
 
     FunctionInfo* fninfo = static_cast<FunctionInfo*>(JSVAL_TO_PRIVATE(slot));
     JS_ASSERT(fninfo);
 
     // Identify our objects to the tracer.
     JS_CALL_TRACER(trc, fninfo->mABI, JSTRACE_OBJECT, "abi");
     JS_CALL_TRACER(trc, fninfo->mReturnType, JSTRACE_OBJECT, "returnType");
-    for (PRUint32 i = 0; i < fninfo->mArgTypes.Length(); ++i)
+    for (size_t i = 0; i < fninfo->mArgTypes.length(); ++i)
       JS_CALL_TRACER(trc, fninfo->mArgTypes[i], JSTRACE_OBJECT, "argType");
 
     break;
   }
   default:
     // Nothing to do here.
     break;
   }
@@ -2663,23 +2681,23 @@ CType::TypesEqual(JSContext* cx, JSObjec
 
     // Compare abi, return type, and argument types.
     if (f1->mABI != f2->mABI)
       return false;
 
     if (!TypesEqual(cx, f1->mReturnType, f2->mReturnType))
       return false;
 
-    if (f1->mArgTypes.Length() != f2->mArgTypes.Length())
+    if (f1->mArgTypes.length() != f2->mArgTypes.length())
       return false;
 
     if (f1->mIsVariadic != f2->mIsVariadic)
       return false;
 
-    for (PRUint32 i = 0; i < f1->mArgTypes.Length(); ++i) {
+    for (size_t i = 0; i < f1->mArgTypes.length(); ++i) {
       if (!TypesEqual(cx, f1->mArgTypes[i], f2->mArgTypes[i]))
         return false;
     }
 
     return true;
   }
   case TYPE_array: {
     // Compare length, then base types.
@@ -2918,19 +2936,19 @@ CType::ToString(JSContext* cx, uintN arg
   JSObject* obj = JS_THIS_OBJECT(cx, vp);
   JS_ASSERT(obj);
 
   if (!CType::IsCType(cx, obj)) {
     JS_ReportError(cx, "not a CType");
     return JS_FALSE;
   }
 
-  nsAutoString type(NS_LITERAL_STRING("type "));
-  JSString* right = GetName(cx, obj);
-  type.Append(GetString(right));
+  AutoString type;
+  AppendString(type, "type ");
+  AppendString(type, GetName(cx, obj));
 
   JSString* result = NewUCString(cx, type);
   if (!result)
     return JS_FALSE;
   
   JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(result));
   return JS_TRUE;
 }
@@ -2941,17 +2959,18 @@ CType::ToSource(JSContext* cx, uintN arg
   JSObject* obj = JS_THIS_OBJECT(cx, vp);
   JS_ASSERT(obj);
 
   if (!CType::IsCType(cx, obj)) {
     JS_ReportError(cx, "not a CType");
     return JS_FALSE;
   }
 
-  nsAutoString source = BuildTypeSource(cx, obj, false);
+  AutoString source;
+  BuildTypeSource(cx, obj, false, source);
   JSString* result = NewUCString(cx, source);
   if (!result)
     return JS_FALSE;
   
   JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(result));
   return JS_TRUE;
 }
 
@@ -3049,26 +3068,25 @@ PointerType::CreateInternal(JSContext* c
 
   // Create a new CType object with the common properties and slots.
   JSObject* typeObj = CType::Create(cx, typeProto, dataProto, TYPE_pointer,
                         name, INT_TO_JSVAL(sizeof(void*)),
                         INT_TO_JSVAL(ffi_type_pointer.alignment),
                         &ffi_type_pointer, NULL);
   if (!typeObj)
     return NULL;
-  JSAutoTempValueRooter root(cx, typeObj);
+  js::AutoValueRooter root(cx, typeObj);
 
   // Set the target type. (This will be 'null' for an opaque pointer type.)
   if (!JS_SetReservedSlot(cx, typeObj, SLOT_TARGET_T, OBJECT_TO_JSVAL(baseType)))
     return NULL;
 
   if (baseType) {
     // Determine the name of the PointerType, since it wasn't supplied.
-    nsAutoString typeName = BuildTypeName(cx, typeObj);
-    JSString* nameStr = NewUCString(cx, typeName);
+    JSString* nameStr = BuildTypeName(cx, typeObj);
     if (!nameStr ||
         !JS_SetReservedSlot(cx, typeObj, SLOT_NAME, STRING_TO_JSVAL(nameStr)))
       return NULL;
 
     // Finally, cache our newly-created PointerType on our pointed-to CType.
     if (!JS_SetReservedSlot(cx, baseType, SLOT_PTR, OBJECT_TO_JSVAL(typeObj)))
       return NULL;
   }
@@ -3342,29 +3360,28 @@ ArrayType::CreateInternal(JSContext* cx,
     ffiType->elements[length] = NULL;
   }
 
   // Create a new CType object with the common properties and slots.
   JSObject* typeObj = CType::Create(cx, typeProto, dataProto, TYPE_array, NULL,
                         sizeVal, INT_TO_JSVAL(align), ffiType, NULL);
   if (!typeObj)
     return NULL;
-  JSAutoTempValueRooter root(cx, typeObj);
+  js::AutoValueRooter root(cx, typeObj);
 
   // Set the element type.
   if (!JS_SetReservedSlot(cx, typeObj, SLOT_ELEMENT_T, OBJECT_TO_JSVAL(baseType)))
     return NULL;
 
   // Set the length.
   if (!JS_SetReservedSlot(cx, typeObj, SLOT_LENGTH, lengthVal))
     return NULL;
 
   // Determine the name of the ArrayType.
-  nsAutoString typeName = BuildTypeName(cx, typeObj);
-  JSString* name = NewUCString(cx, typeName);
+  JSString* name = BuildTypeName(cx, typeObj);
   if (!name ||
       !JS_SetReservedSlot(cx, typeObj, SLOT_NAME, STRING_TO_JSVAL(name)))
     return NULL;
 
   return typeObj;
 }
 
 JSBool
@@ -3403,17 +3420,17 @@ ArrayType::ConstructData(JSContext* cx,
     if (jsvalToSize(cx, argv[0], false, &length)) {
       // Have a length, rather than an object to initialize from.
       convertObject = false;
 
     } else if (!JSVAL_IS_PRIMITIVE(argv[0])) {
       // We were given an object with a .length property.
       // This could be a JS array, or a CData array.
       JSObject* arg = JSVAL_TO_OBJECT(argv[0]);
-      JSAutoTempValueRooter lengthVal(cx);
+      js::AutoValueRooter lengthVal(cx);
       if (!JS_GetProperty(cx, arg, "length", lengthVal.addr()) ||
           !jsvalToSize(cx, lengthVal.value(), false, &length)) {
         JS_ReportError(cx, "argument must be an array object or length");
         return JS_FALSE;
       }
 
     } else if (JSVAL_IS_STRING(argv[0])) {
       // We were given a string. Size the array to the appropriate length,
@@ -3421,24 +3438,22 @@ ArrayType::ConstructData(JSContext* cx,
       JSString* sourceString = JSVAL_TO_STRING(argv[0]);
       const jschar* sourceChars = JS_GetStringChars(sourceString);
       size_t sourceLength = JS_GetStringLength(sourceString);
 
       switch (CType::GetTypeCode(cx, baseType)) {
       case TYPE_char:
       case TYPE_signed_char:
       case TYPE_unsigned_char: {
-        // Convert from UTF-16 to UTF-8 to determine the length. :(
-        if (!IsUTF16(sourceChars, sourceLength))
-          return TypeError(cx, "UTF-16 string", argv[0]);
-
-        NS_ConvertUTF16toUTF8 converted(
-          reinterpret_cast<const PRUnichar*>(sourceChars), sourceLength);
-
-        length = converted.Length() + 1;
+        // Determine the UTF-8 length.
+        length = js_GetDeflatedUTF8StringLength(cx, sourceChars, sourceLength);
+        if (length == (size_t) -1)
+          return false;
+
+        ++length;
         break;
       }
       case TYPE_jschar:
         length = sourceLength + 1;
         break;
       default:
         return TypeError(cx, "array", argv[0]);
       }
@@ -3450,17 +3465,17 @@ ArrayType::ConstructData(JSContext* cx,
 
     // Construct a new ArrayType of defined length, for the new CData object.
     obj = CreateInternal(cx, baseType, length, true);
     if (!obj)
       return JS_FALSE;
   }
 
   // Root the CType object, in case we created one above.
-  JSAutoTempValueRooter root(cx, obj);
+  js::AutoValueRooter root(cx, obj);
 
   JSObject* result = CData::Create(cx, obj, NULL, NULL, true);
   if (!result)
     return JS_FALSE;
 
   *rval = OBJECT_TO_JSVAL(result);
 
   if (convertObject) {
@@ -3647,17 +3662,17 @@ ArrayType::AddressOfElement(JSContext* c
     JS_ReportError(cx, "addressOfElement takes one argument");
     return JS_FALSE;
   }
 
   JSObject* baseType = GetBaseType(cx, typeObj);
   JSObject* pointerType = PointerType::CreateInternal(cx, NULL, baseType, NULL);
   if (!pointerType)
     return JS_FALSE;
-  JSAutoTempValueRooter root(cx, pointerType);
+  js::AutoValueRooter root(cx, pointerType);
 
   // Create a PointerType CData object containing null.
   JSObject* result = CData::Create(cx, pointerType, NULL, NULL, true);
   if (!result)
     return JS_FALSE;
 
   JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(result));
 
@@ -3690,44 +3705,45 @@ ExtractStructField(JSContext* cx, jsval 
     JS_ReportError(cx, "struct field descriptors require a valid name and type");
     return false;
   }
 
   JSObject* obj = JSVAL_TO_OBJECT(val);
   JSObject* iter = JS_NewPropertyIterator(cx, obj);
   if (!iter)
     return false;
-  JSAutoTempValueRooter iterroot(cx, iter);
+  js::AutoValueRooter iterroot(cx, iter);
 
   jsid id;
   if (!JS_NextProperty(cx, iter, &id))
     return false;
 
-  JSAutoTempValueRooter nameVal(cx);
+  js::AutoValueRooter nameVal(cx);
   if (!JS_IdToValue(cx, id, nameVal.addr()))
     return false;
   if (!JSVAL_IS_STRING(nameVal.value())) {
     JS_ReportError(cx, "struct field descriptors require a valid name and type");
     return false;
   }
 
   // make sure we have one, and only one, property
   if (!JS_NextProperty(cx, iter, &id))
     return false;
   if (!JSVAL_IS_VOID(id)) {
     JS_ReportError(cx, "struct field descriptors must contain one property");
     return false;
   }
 
   JSString* name = JSVAL_TO_STRING(nameVal.value());
+  field->mName.clear();
+  AppendString(field->mName, name);
+
+  js::AutoValueRooter propVal(cx);
   const jschar* nameChars = JS_GetStringChars(name);
   size_t namelen = JS_GetStringLength(name);
-  field->mName.Assign(reinterpret_cast<const PRUnichar*>(nameChars), namelen);
-
-  JSAutoTempValueRooter propVal(cx);
   if (!JS_GetUCProperty(cx, obj, nameChars, namelen, propVal.addr()))
     return false;
 
   if (JSVAL_IS_PRIMITIVE(propVal.value()) ||
       !CType::IsCType(cx, JSVAL_TO_OBJECT(propVal.value()))) {
     JS_ReportError(cx, "struct field descriptors require a valid name and type");
     return false;
   }
@@ -3746,27 +3762,27 @@ ExtractStructField(JSContext* cx, jsval 
 }
 
 // For a struct field with 'name' and 'type', add an element to field
 // descriptor array 'arrayObj' of the form { name : type }.
 static JSBool
 AddFieldToArray(JSContext* cx,
                 JSObject* arrayObj,
                 jsval* element,
-                const nsString& name,
+                const String& name,
                 JSObject* typeObj)
 {
   JSObject* fieldObj = JS_NewObject(cx, NULL, NULL, arrayObj);
   if (!fieldObj)
     return false;
 
   *element = OBJECT_TO_JSVAL(fieldObj);
 
   if (!JS_DefineUCProperty(cx, fieldObj,
-         reinterpret_cast<const jschar*>(name.get()), name.Length(),
+         name.begin(), name.length(),
          OBJECT_TO_JSVAL(typeObj), NULL, NULL,
          JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT))
     return false;
 
   return JS_SealObject(cx, fieldObj, JS_FALSE);
 }
 
 JSBool
@@ -3796,75 +3812,77 @@ StructType::Create(JSContext* cx, uintN 
   ASSERT_OK(JS_GetArrayLength(cx, fieldsObj, &len));
 
   // Prepare a new array for the .fields property of the StructType.
   jsval* fieldsVec;
   JSObject* fieldsProp =
     js_NewArrayObjectWithCapacity(cx, len, &fieldsVec);
   if (!fieldsProp)
     return JS_FALSE;
-  JSAutoTempValueRooter root(cx, fieldsProp);
+  js::AutoValueRooter root(cx, fieldsProp);
   JS_ASSERT(len == 0 || fieldsVec);
 
-  nsAutoPtr<ffi_type> ffiType(new ffi_type);
+  AutoPtr<ffi_type> ffiType(new ffi_type);
   if (!ffiType) {
     JS_ReportOutOfMemory(cx);
     return JS_FALSE;
   }
   ffiType->type = FFI_TYPE_STRUCT;
 
   // Create an array of FieldInfo objects to stash on the type object, and an
   // array of PropertySpecs to reflect the struct fields as properties
   // on CData objects created from this type.
-  nsAutoPtr< nsTArray<FieldInfo> > fields(new nsTArray<FieldInfo>());
-  nsAutoTArray<PropertySpec, 16> instanceProps;
+  AutoPtr< Array<FieldInfo> > fields(new Array<FieldInfo>);
+  Array<PropertySpec> instanceProps;
   if (!fields ||
-      !fields->SetCapacity(len) ||
-      !instanceProps.SetCapacity(len + 1)) {
+      !fields->resize(len) ||
+      !instanceProps.resize(len + 1)) {
     JS_ReportOutOfMemory(cx);
     return JS_FALSE;
   }
-  nsAutoArrayPtr<ffi_type*> elements;
+
+  AutoPtr<ffi_type*>::Array elements;
 
   // Process the field types and fill in the ffi_type fields.
   size_t structSize = 0, structAlign = 0;
   if (len != 0) {
     elements = new ffi_type*[len + 1];
     if (!elements) {
       JS_ReportOutOfMemory(cx);
       return JS_FALSE;
     }
     elements[len] = NULL;
 
     for (jsuint i = 0; i < len; ++i) {
-      JSAutoTempValueRooter item(cx);
+      js::AutoValueRooter item(cx);
       if (!JS_GetElement(cx, fieldsObj, i, item.addr()))
         return JS_FALSE;
 
-      FieldInfo* info = fields->AppendElement();
+      FieldInfo* info = fields->begin() + i;
       if (!ExtractStructField(cx, item.value(), info))
         return JS_FALSE;
 
       // Make sure each field name is unique.
-      for (PRUint32 j = 0; j < fields->Length() - 1; ++j) {
-        if (fields->ElementAt(j).mName == info->mName) {
+      for (size_t j = 0; j < i; ++j) {
+        FieldInfo* field = fields->begin() + j;
+        if (StringsEqual(field->mName, info->mName)) {
           JS_ReportError(cx, "struct fields must have unique names");
           return JS_FALSE;
         }
       }
 
       // Duplicate the object for the fields property.
       if (!AddFieldToArray(cx, fieldsProp, &fieldsVec[i],
              info->mName, info->mType))
         return JS_FALSE;
 
       // Fill in the PropertySpec for the field.
-      PropertySpec* instanceProp = instanceProps.AppendElement();
-      instanceProp->name = reinterpret_cast<const jschar*>(info->mName.get());
-      instanceProp->namelen = info->mName.Length();
+      PropertySpec* instanceProp = instanceProps.begin() + i;
+      instanceProp->name = info->mName.begin();
+      instanceProp->namelen = info->mName.length();
       instanceProp->flags = JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_PERMANENT;
       instanceProp->getter = StructType::FieldGetter;
       instanceProp->setter = StructType::FieldSetter;
 
       elements[i] = CType::GetFFIType(cx, info->mType);
 
       size_t fieldSize = CType::GetSize(cx, info->mType);
       size_t fieldAlign = CType::GetAlignment(cx, info->mType);
@@ -3902,56 +3920,56 @@ StructType::Create(JSContext* cx, uintN 
     if (!elements) {
       JS_ReportOutOfMemory(cx);
       return JS_FALSE;
     }
     elements[0] = &ffi_type_uint8;
     elements[1] = NULL;
   }
 
-  ffiType->elements = elements;
+  ffiType->elements = elements.get();
 
 #ifdef DEBUG
   // Perform a sanity check: the result of our struct size and alignment
   // calculations should match libffi's. We force it to do this calculation
   // by calling ffi_prep_cif.
   ffi_cif cif;
   ffiType->size = 0;
   ffiType->alignment = 0;
-  ffi_status status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, ffiType, NULL);
+  ffi_status status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, ffiType.get(), NULL);
   JS_ASSERT(status == FFI_OK);
   JS_ASSERT(structSize == ffiType->size);
   JS_ASSERT(structAlign == ffiType->alignment);
 #else
   // Fill in the ffi_type's size and align fields. This makes libffi treat the
   // type as initialized; it will not recompute the values. (We assume
   // everything agrees; if it doesn't, we really want to know about it, which
   // is the purpose of the above debug-only check.)
   ffiType->size = structSize;
   ffiType->alignment = structAlign;
 #endif
 
   // Terminate the PropertySpec array.
-  instanceProps.AppendElement()->name = NULL;
+  instanceProps[len].name = NULL;
 
   jsval sizeVal;
   if (!SizeTojsval(cx, structSize, &sizeVal))
     return JS_FALSE;
 
   // Get ctypes.StructType.prototype and the common prototype for CData objects
   // of this type, from the ctypes.StructType constructor.
   JSObject* callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
   JSObject* typeProto = CType::GetProtoFromCtor(cx, callee, SLOT_STRUCTPROTO);
   JSObject* dataProto = CType::GetProtoFromCtor(cx, callee, SLOT_STRUCTDATAPROTO);
 
   // Create a new CType object with the common properties and slots.
   JSObject* typeObj = CType::Create(cx, typeProto, dataProto, TYPE_struct,
                         JSVAL_TO_STRING(name), sizeVal,
-                        INT_TO_JSVAL(structAlign), ffiType,
-                        instanceProps.Elements());
+                        INT_TO_JSVAL(structAlign), ffiType.get(),
+                        instanceProps.begin());
   if (!typeObj)
     return JS_FALSE;
   ffiType.forget();
   elements.forget();
 
   JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(typeObj));
 
   // Seal and attach the fields array. (The fields array also prevents the
@@ -3986,95 +4004,97 @@ StructType::ConstructData(JSContext* cx,
     return JS_FALSE;
 
   *rval = OBJECT_TO_JSVAL(result);
 
   if (argc == 0)
     return JS_TRUE;
 
   char* buffer = static_cast<char*>(CData::GetData(cx, result));
-  nsTArray<FieldInfo>* fields = GetFieldInfo(cx, obj);
+  Array<FieldInfo>* fields = GetFieldInfo(cx, obj);
 
   if (argc == 1) {
     // There are two possible interpretations of the argument:
     // 1) It may be an object '{ ... }' with properties representing the
     //    struct fields intended to ExplicitConvert wholesale to our StructType.
     // 2) If the struct contains one field, the arg may be intended to
     //    ImplicitConvert directly to that arg's CType.
     // Thankfully, the conditions for these two possibilities to succeed
     // are mutually exclusive, so we can pick the right one.
 
     // Try option 1) first.
     if (ExplicitConvert(cx, argv[0], obj, buffer))
       return JS_TRUE;
 
-    if (fields->Length() != 1)
+    if (fields->length() != 1)
       return JS_FALSE;
 
     // If ExplicitConvert failed, and there is no pending exception, then assume
     // hard failure (out of memory, or some other similarly serious condition).
     if (!JS_IsExceptionPending(cx))
       return JS_FALSE;
 
     // Otherwise, assume soft failure, and clear the pending exception so that we
     // can throw a different one as required.
     JS_ClearPendingException(cx);
 
     // Fall through to try option 2).
   }
 
   // We have a type constructor of the form 'ctypes.StructType(a, b, c, ...)'.
   // ImplicitConvert each field.
-  if (argc == fields->Length()) {
-    for (PRUint32 i = 0; i < fields->Length(); ++i) {
-      FieldInfo& field = fields->ElementAt(i);
-      if (!ImplicitConvert(cx, argv[i], field.mType, buffer + field.mOffset,
+  if (argc == fields->length()) {
+    for (size_t i = 0; i < fields->length(); ++i) {
+      FieldInfo* field = fields->begin() + i;
+      if (!ImplicitConvert(cx, argv[i], field->mType, buffer + field->mOffset,
              false, NULL))
         return JS_FALSE;
     }
 
     return JS_TRUE;
   }
 
   JS_ReportError(cx, "constructor takes 0, 1, or %u arguments",
-    fields->Length());
+    fields->length());
   return JS_FALSE;
 }
 
-nsTArray<FieldInfo>*
+Array<FieldInfo>*
 StructType::GetFieldInfo(JSContext* cx, JSObject* obj)
 {
   JS_ASSERT(CType::IsCType(cx, obj));
   JS_ASSERT(CType::GetTypeCode(cx, obj) == TYPE_struct);
 
   jsval slot;
   ASSERT_OK(JS_GetReservedSlot(cx, obj, SLOT_FIELDINFO, &slot));
   JS_ASSERT(!JSVAL_IS_VOID(slot) && JSVAL_TO_PRIVATE(slot));
 
-  return static_cast<nsTArray<FieldInfo>*>(JSVAL_TO_PRIVATE(slot));
+  return static_cast<Array<FieldInfo>*>(JSVAL_TO_PRIVATE(slot));
 }
 
 FieldInfo*
 StructType::LookupField(JSContext* cx, JSObject* obj, jsval idval)
 {
   JS_ASSERT(CType::IsCType(cx, obj));
   JS_ASSERT(CType::GetTypeCode(cx, obj) == TYPE_struct);
 
-  nsTArray<FieldInfo>* fields = GetFieldInfo(cx, obj);
-
-  JSString* nameStr = JSVAL_TO_STRING(idval);
-  const nsDependentString name(GetString(nameStr));
-
-  for (PRUint32 i = 0; i < fields->Length(); ++i) {
-    if (fields->ElementAt(i).mName.Equals(name))
-      return &fields->ElementAt(i);
-  }
-
-  JS_ReportError(cx, "%s does not name a field",
-    NS_LossyConvertUTF16toASCII(name).get());
+  Array<FieldInfo>* fields = GetFieldInfo(cx, obj);
+
+  JSString* name = JSVAL_TO_STRING(idval);
+  for (size_t i = 0; i < fields->length(); ++i) {
+    FieldInfo* field = fields->begin() + i;
+    if (StringsEqual(field->mName, name))
+      return field;
+  }
+
+  const char* bytes = JS_GetStringBytesZ(cx, name);
+  if (!bytes)
+    return NULL;
+
+  JS_ReportError(cx, "%s does not name a field", bytes);
   return NULL;
 }
 
 JSBool
 StructType::FieldsArrayGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
 {
   if (!CType::IsCType(cx, obj) || CType::GetTypeCode(cx, obj) != TYPE_struct) {
     JS_ReportError(cx, "not a StructType");
@@ -4156,17 +4176,17 @@ StructType::AddressOfField(JSContext* cx
   FieldInfo* field = LookupField(cx, typeObj, JS_ARGV(cx, vp)[0]);
   if (!field)
     return JS_FALSE;
 
   JSObject* baseType = field->mType;
   JSObject* pointerType = PointerType::CreateInternal(cx, NULL, baseType, NULL);
   if (!pointerType)
     return JS_FALSE;
-  JSAutoTempValueRooter root(cx, pointerType);
+  js::AutoValueRooter root(cx, pointerType);
 
   // Create a PointerType CData object containing null.
   JSObject* result = CData::Create(cx, pointerType, NULL, NULL, true);
   if (!result)
     return JS_FALSE;
 
   JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(result));
 
@@ -4306,19 +4326,19 @@ PrepareCIF(JSContext* cx,
   if (!GetABI(cx, OBJECT_TO_JSVAL(fninfo->mABI), &abi)) {
     JS_ReportError(cx, "Invalid ABI specification");
     return false;
   }
 
   ffi_status status =
     ffi_prep_cif(&fninfo->mCIF,
                  abi,
-                 fninfo->mFFITypes.Length(),
+                 fninfo->mFFITypes.length(),
                  CType::GetFFIType(cx, fninfo->mReturnType),
-                 fninfo->mFFITypes.Elements());
+                 fninfo->mFFITypes.begin());
 
   switch (status) {
   case FFI_OK:
     return true;
   case FFI_BAD_ABI:
     JS_ReportError(cx, "Invalid ABI specification");
     return false;
   case FFI_BAD_TYPEDEF:
@@ -4332,39 +4352,39 @@ PrepareCIF(JSContext* cx,
 
 static FunctionInfo*
 NewFunctionInfo(JSContext* cx,
                 jsval abiType,
                 jsval returnType,
                 jsval* argTypes,
                 uintN argLength)
 {
-  nsAutoPtr<FunctionInfo> fninfo(new FunctionInfo());
+  AutoPtr<FunctionInfo> fninfo(new FunctionInfo());
   if (!fninfo) {
     JS_ReportOutOfMemory(cx);
     return NULL;
   }
 
   fninfo->mABI = JSVAL_TO_OBJECT(abiType);
 
   // prepare the result type
   fninfo->mReturnType = PrepareReturnType(cx, returnType);
   if (!fninfo->mReturnType)
     return NULL;
 
   // prepare the argument types
-  if (!fninfo->mArgTypes.SetCapacity(argLength) ||
-      !fninfo->mFFITypes.SetCapacity(argLength)) {
+  if (!fninfo->mArgTypes.reserve(argLength) ||
+      !fninfo->mFFITypes.reserve(argLength)) {
     JS_ReportOutOfMemory(cx);
     return NULL;
   }
 
   fninfo->mIsVariadic = false;
 
-  for (PRUint32 i = 0; i < argLength; ++i) {
+  for (JSUint32 i = 0; i < argLength; ++i) {
     if (IsEllipsis(argTypes[i])) {
       fninfo->mIsVariadic = true;
       if (i < 1) {
         JS_ReportError(cx, "\"...\" may not be the first and only parameter "
                        "type of a variadic function declaration");
         return NULL;
       }
       if (i < argLength - 1) {
@@ -4379,90 +4399,90 @@ NewFunctionInfo(JSContext* cx,
       }
       break;
     }
 
     JSObject* argType = PrepareType(cx, argTypes[i]);
     if (!argType)
       return NULL;
 
-    fninfo->mArgTypes.AppendElement(argType);
-    fninfo->mFFITypes.AppendElement(CType::GetFFIType(cx, argType));
+    fninfo->mArgTypes.append(argType);
+    fninfo->mFFITypes.append(CType::GetFFIType(cx, argType));
   }
 
   if (fninfo->mIsVariadic)
     // wait to PrepareCIF until function is called
     return fninfo.forget();
 
-  if (!PrepareCIF(cx, fninfo))
+  if (!PrepareCIF(cx, fninfo.get()))
     return NULL;
 
   return fninfo.forget();
 }
 
 JSBool
 FunctionType::Create(JSContext* cx, uintN argc, jsval* vp)
 {
   // Construct and return a new FunctionType object.
   if (argc < 2 || argc > 3) {
     JS_ReportError(cx, "FunctionType takes two or three arguments");
     return JS_FALSE;
   }
 
   jsval* argv = JS_ARGV(cx, vp);
-  nsAutoTArray<jsval, 16> argTypes;
+  Array<jsval, 16> argTypes;
   JSObject* arrayObj = NULL;
 
   if (argc == 3) {
     // Prepare an array of jsvals for the arguments.
     if (JSVAL_IS_PRIMITIVE(argv[2]) ||
         !JS_IsArrayObject(cx, JSVAL_TO_OBJECT(argv[2]))) {
       JS_ReportError(cx, "third argument must be an array");
       return JS_FALSE;
     }
 
     arrayObj = JSVAL_TO_OBJECT(argv[2]);
     jsuint len;
     ASSERT_OK(JS_GetArrayLength(cx, arrayObj, &len));
 
-    if (!argTypes.SetLength(len)) {
+    if (!argTypes.resize(len)) {
       JS_ReportOutOfMemory(cx);
       return JS_FALSE;
     }
 
     for (jsuint i = 0; i < len; ++i)
       argTypes[i] = JSVAL_VOID;
   }
 
   // Pull out the argument types from the array, if any.
-  JS_ASSERT(!argTypes.Length() || arrayObj);
-  JSAutoTempValueRooter items(cx, argTypes.Length(), argTypes.Elements());
-  for (jsuint i = 0; i < argTypes.Length(); ++i) {
+  JS_ASSERT(!argTypes.length() || arrayObj);
+  js::AutoArrayRooter items(cx, argTypes.length(), argTypes.begin());
+  for (jsuint i = 0; i < argTypes.length(); ++i) {
     if (!JS_GetElement(cx, arrayObj, i, &argTypes[i]))
       return JS_FALSE;
   }
 
   JSObject* result = CreateInternal(cx, argv[0], argv[1],
-      argTypes.Elements(), argTypes.Length());
+      argTypes.begin(), argTypes.length());
   if (!result)
     return JS_FALSE;
 
   JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(result));
   return JS_TRUE;
 }
 
 JSObject*
 FunctionType::CreateInternal(JSContext* cx,
                              jsval abi,
                              jsval rtype,
                              jsval* argtypes,
                              jsuint arglen)
 {
   // Determine and check the types, and prepare the function CIF.
-  nsAutoPtr<FunctionInfo> fninfo(NewFunctionInfo(cx, abi, rtype, argtypes, arglen));
+  AutoPtr<FunctionInfo> fninfo(NewFunctionInfo(cx, abi, rtype, argtypes, arglen));
   if (!fninfo)
     return NULL;
 
   // Get ctypes.FunctionType.prototype and the common prototype for CData objects
   // of this type, from ctypes.CType.prototype.
   JSObject* typeProto = CType::GetProtoFromType(cx, fninfo->mReturnType,
                                                 SLOT_FUNCTIONPROTO);
   JSObject* dataProto = CType::GetProtoFromType(cx, fninfo->mReturnType,
@@ -4470,27 +4490,26 @@ FunctionType::CreateInternal(JSContext* 
 
   // Create a new CType object with the common properties and slots.
   JSObject* typeObj = CType::Create(cx, typeProto, dataProto, TYPE_function,
                         NULL, INT_TO_JSVAL(sizeof(void*)),
                         INT_TO_JSVAL(ffi_type_pointer.alignment),
                         &ffi_type_pointer, NULL);
   if (!typeObj)
     return NULL;
-  JSAutoTempValueRooter root(cx, typeObj);
+  js::AutoValueRooter root(cx, typeObj);
 
   // Stash the FunctionInfo in a reserved slot.
   if (!JS_SetReservedSlot(cx, typeObj, SLOT_FNINFO,
          PRIVATE_TO_JSVAL(fninfo.get())))
     return NULL;
   fninfo.forget();
 
   // Determine the name of the FunctionType.
-  nsAutoString typeName = BuildTypeName(cx, typeObj);
-  JSString* name = NewUCString(cx, typeName);
+  JSString* name = BuildTypeName(cx, typeObj);
   if (!name ||
       !JS_SetReservedSlot(cx, typeObj, SLOT_NAME, STRING_TO_JSVAL(name)))
     return NULL;
 
   return typeObj;
 }
 
 JSBool
@@ -4535,17 +4554,17 @@ FunctionType::ConstructData(JSContext* c
           return JS_FALSE;
         }
       }
 
       JSObject* fnObj = JSVAL_TO_OBJECT(arg);
       JSObject* closureObj = CClosure::Create(cx, obj, fnObj, thisObj, data);
       if (!closureObj)
         return JS_FALSE;
-      JSAutoTempValueRooter root(cx, closureObj);
+      js::AutoValueRooter root(cx, closureObj);
 
       // Set the closure object as the referent of the new CData object.
       if (!JS_SetReservedSlot(cx, result, SLOT_REFERENT,
              OBJECT_TO_JSVAL(closureObj)))
         return JS_FALSE;
 
       // Seal the CData object, to prevent modification of the function pointer.
       // This permanently associates this object with the closure, and avoids
@@ -4561,40 +4580,42 @@ FunctionType::ConstructData(JSContext* c
       return ExplicitConvert(cx, arg, obj, data);
     }
   }
 
   JS_ReportError(cx, "constructor takes 0, 1, or 2 arguments");
   return JS_FALSE;
 }
 
-typedef nsAutoTArray<AutoValue, 16> AutoValueAutoArray;
+typedef Array<AutoValue, 16> AutoValueAutoArray;
 
 static JSBool
 ConvertArgument(JSContext* cx,
                 jsval arg,
                 JSObject* type,
-                AutoValueAutoArray* values,
+                AutoValue* value,
                 AutoValueAutoArray* strings)
 {
-  AutoValue* value = values->AppendElement();
-
   if (!value->SizeToType(cx, type)) {
     JS_ReportAllocationOverflow(cx);
     return false;
   }
 
   bool freePointer = false;
   if (!ImplicitConvert(cx, arg, type, value->mData, true, &freePointer))
     return false;
 
   if (freePointer) {
     // ImplicitConvert converted a string for us, which we have to free.
     // Keep track of it.
-    strings->AppendElement()->mData = *static_cast<char**>(value->mData);
+    if (!strings->growBy(1)) {
+      JS_ReportOutOfMemory(cx);
+      return false;
+    }
+    strings->back().mData = *static_cast<char**>(value->mData);
   }
 
   return true;
 }
 
 JSBool
 FunctionType::Call(JSContext* cx,
                    JSObject* obj,
@@ -4611,17 +4632,17 @@ FunctionType::Call(JSContext* cx,
 
   JSObject* typeObj = CData::GetCType(cx, obj);
   if (CType::GetTypeCode(cx, typeObj) != TYPE_function) {
     JS_ReportError(cx, "not a FunctionType");
     return false;
   }
 
   FunctionInfo* fninfo = GetFunctionInfo(cx, typeObj);
-  PRUint32 argcFixed = fninfo->mArgTypes.Length();
+  JSUint32 argcFixed = fninfo->mArgTypes.length();
 
   if ((!fninfo->mIsVariadic && argc != argcFixed) ||
       (fninfo->mIsVariadic && argc < argcFixed)) {
     JS_ReportError(cx, "Number of arguments does not match declaration");
     return false;
   }
 
   // Check if we have a Library object. If we do, make sure it's open.
@@ -4633,46 +4654,52 @@ FunctionType::Call(JSContext* cx,
       JS_ReportError(cx, "library is not open");
       return false;
     }
   }
 
   // prepare the values for each argument
   AutoValueAutoArray values;
   AutoValueAutoArray strings;
-
-  for (PRUint32 i = 0; i < argcFixed; ++i)
-    if (!ConvertArgument(cx, argv[i], fninfo->mArgTypes[i], &values, &strings))
+  if (!values.resize(argc)) {
+    JS_ReportOutOfMemory(cx);
+    return false;
+  }
+
+  for (jsuint i = 0; i < argcFixed; ++i)
+    if (!ConvertArgument(cx, argv[i], fninfo->mArgTypes[i], &values[i], &strings))
       return false;
 
   if (fninfo->mIsVariadic) {
-    fninfo->mFFITypes.SetLength(argcFixed);
-    ASSERT_OK(fninfo->mFFITypes.SetCapacity(argc));
+    if (!fninfo->mFFITypes.resize(argc)) {
+      JS_ReportOutOfMemory(cx);
+      return false;
+    }
 
     JSObject* obj;  // Could reuse obj instead of declaring a second
     JSObject* type; // JSObject*, but readability would suffer.
 
-    for (PRUint32 i = argcFixed; i < argc; ++i) {
+    for (JSUint32 i = argcFixed; i < argc; ++i) {
       if (JSVAL_IS_PRIMITIVE(argv[i]) ||
           !CData::IsCData(cx, obj = JSVAL_TO_OBJECT(argv[i]))) {
         // Since we know nothing about the CTypes of the ... arguments,
         // they absolutely must be CData objects already.
         JS_ReportError(cx, "argument %d of type %s is not a CData object",
                        i, JS_GetTypeName(cx, JS_TypeOfValue(cx, argv[i])));
         return false;
       }
       if (!(type = CData::GetCType(cx, obj)) ||
           !(type = PrepareType(cx, OBJECT_TO_JSVAL(type))) ||
           // Relying on ImplicitConvert only for the limited purpose of
           // converting one CType to another (e.g., T[] to T*).
-          !ConvertArgument(cx, argv[i], type, &values, &strings)) {
+          !ConvertArgument(cx, argv[i], type, &values[i], &strings)) {
         // These functions report their own errors.
         return false;
       }
-      fninfo->mFFITypes.AppendElement(CType::GetFFIType(cx, type));
+      fninfo->mFFITypes[i] = CType::GetFFIType(cx, type);
     }
     if (!PrepareCIF(cx, fninfo))
       return false;
   }
 
   // initialize a pointer to an appropriate location, for storing the result
   AutoValue returnValue;
   if (CType::GetTypeCode(cx, fninfo->mReturnType) != TYPE_void_t &&
@@ -4683,17 +4710,17 @@ FunctionType::Call(JSContext* cx,
 
   uintptr_t fn = *reinterpret_cast<uintptr_t*>(CData::GetData(cx, obj));
 
   // 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(cx);
 
   ffi_call(&fninfo->mCIF, FFI_FN(fn), returnValue.mData,
-    reinterpret_cast<void**>(values.Elements()));
+    reinterpret_cast<void**>(values.begin()));
 
   JS_ResumeRequest(cx, rc);
 
   // prepare a JS object from the result
   return ConvertToJS(cx, fninfo->mReturnType, NULL, returnValue.mData,
                      false, true, rval);
 }
 
@@ -4727,28 +4754,28 @@ FunctionType::ArgTypesGetter(JSContext* 
     return JS_FALSE;
 
   // Check if we have a cached argTypes array.
   ASSERT_OK(JS_GetReservedSlot(cx, obj, SLOT_ARGS_T, vp));
   if (!JSVAL_IS_VOID(*vp))
     return JS_TRUE;
 
   FunctionInfo* fninfo = GetFunctionInfo(cx, obj);
-  PRUint32 len = fninfo->mArgTypes.Length();
+  size_t len = fninfo->mArgTypes.length();
 
   // Prepare a new array.
   jsval* vec;
   JSObject* argTypes =
     js_NewArrayObjectWithCapacity(cx, len, &vec);
   if (!argTypes)
     return JS_FALSE;
-  JSAutoTempValueRooter argsroot(cx, argTypes);
+  js::AutoValueRooter argsroot(cx, argTypes);
   JS_ASSERT(len == 0 || vec);
 
-  for (PRUint32 i = 0; i < len; ++i)
+  for (size_t i = 0; i < len; ++i)
     vec[i] = OBJECT_TO_JSVAL(fninfo->mArgTypes[i]);
 
   // Seal and cache it.
   if (!JS_SealObject(cx, argTypes, JS_FALSE) ||
       !JS_SetReservedSlot(cx, obj, SLOT_ARGS_T, OBJECT_TO_JSVAL(argTypes)))
     return JS_FALSE;
 
   *vp = OBJECT_TO_JSVAL(argTypes);
@@ -4796,23 +4823,23 @@ CClosure::Create(JSContext* cx,
                  JSObject* typeObj,
                  JSObject* fnObj,
                  JSObject* thisObj,
                  PRFuncPtr* fnptr)
 {
   JSObject* result = JS_NewObject(cx, &sCClosureClass, NULL, NULL);
   if (!result)
     return NULL;
-  JSAutoTempValueRooter root(cx, result);
+  js::AutoValueRooter root(cx, result);
 
   // Get the FunctionInfo from the FunctionType.
   FunctionInfo* fninfo = FunctionType::GetFunctionInfo(cx, typeObj);
   JS_ASSERT(!fninfo->mIsVariadic);
 
-  nsAutoPtr<ClosureInfo> cinfo(new ClosureInfo());
+  AutoPtr<ClosureInfo> cinfo(new ClosureInfo());
   if (!cinfo) {
     JS_ReportOutOfMemory(cx);
     return NULL;
   }
 
   // Get the prototype of the FunctionType object, of class CTypeProto,
   // which stores our JSContext for use with the closure.
   JSObject* proto = JS_GetPrototype(cx, typeObj);
@@ -4842,31 +4869,28 @@ CClosure::Create(JSContext* cx,
       return NULL;
     }
   }
 
   cinfo->closureObj = result;
   cinfo->typeObj = typeObj;
   cinfo->thisObj = thisObj;
   cinfo->jsfnObj = fnObj;
-#ifdef DEBUG
-  cinfo->thread = PR_GetCurrentThread();
-#endif
 
   // Create an ffi_closure object and initialize it.
   void* code;
   cinfo->closure =
     static_cast<ffi_closure*>(ffi_closure_alloc(sizeof(ffi_closure), &code));
   if (!cinfo->closure || !code) {
     JS_ReportError(cx, "couldn't create closure - libffi error");
     return NULL;
   }
 
   ffi_status status = ffi_prep_closure_loc(cinfo->closure, &fninfo->mCIF,
-    CClosure::ClosureStub, cinfo, code);
+    CClosure::ClosureStub, cinfo.get(), code);
   if (status != FFI_OK) {
     ffi_closure_free(cinfo->closure);
     JS_ReportError(cx, "couldn't create closure - libffi error");
     return NULL;
   }
 
   // Stash the ClosureInfo struct on our new object.
   if (!JS_SetReservedSlot(cx, result, SLOT_CLOSUREINFO,
@@ -4930,55 +4954,54 @@ CClosure::ClosureStub(ffi_cif* cif, void
 
   // Retrieve the essentials from our closure object.
   ClosureInfo* cinfo = static_cast<ClosureInfo*>(userData);
   JSContext* cx = cinfo->cx;
   JSObject* typeObj = cinfo->typeObj;
   JSObject* thisObj = cinfo->thisObj;
   JSObject* jsfnObj = cinfo->jsfnObj;
 
-#ifdef DEBUG
+#ifdef JS_THREADSAFE
   // Assert that we're on the thread we were created from.
-  PRThread* thread = PR_GetCurrentThread();
-  JS_ASSERT(thread == cinfo->thread);
+  JS_ASSERT(CURRENT_THREAD_IS_ME(cx->thread));
 #endif
 
   JSAutoRequest ar(cx);
 
   // Assert that our CIFs agree.
   FunctionInfo* fninfo = FunctionType::GetFunctionInfo(cx, typeObj);
   JS_ASSERT(cif == &fninfo->mCIF);
 
   // Get a death grip on 'closureObj'.
-  JSAutoTempValueRooter root(cx, cinfo->closureObj);
+  js::AutoValueRooter root(cx, cinfo->closureObj);
 
   // Set up an array for converted arguments.
-  nsAutoTArray<jsval, 16> argv;
-  if (!argv.SetLength(cif->nargs)) {
+  Array<jsval, 16> argv;
+  if (!argv.resize(cif->nargs)) {
     JS_ReportOutOfMemory(cx);
     return;
   }
 
-  for (PRUint32 i = 0; i < cif->nargs; ++i)
+  for (JSUint32 i = 0; i < cif->nargs; ++i)
     argv[i] = JSVAL_VOID;
 
-  JSAutoTempValueRooter roots(cx, argv.Length(), argv.Elements());
-  for (PRUint32 i = 0; i < cif->nargs; ++i) {
+  js::AutoArrayRooter roots(cx, argv.length(), argv.begin());
+  for (JSUint32 i = 0; i < cif->nargs; ++i) {
     // Convert each argument, and have any CData objects created depend on
     // the existing buffers.
     if (!ConvertToJS(cx, fninfo->mArgTypes[i], NULL, args[i], false, false,
            &argv[i]))
       return;
   }
 
   // Call the JS function. 'thisObj' may be NULL, in which case the JS engine
   // will find an appropriate object to use.
   jsval rval;
   if (!JS_CallFunctionValue(cx, thisObj, OBJECT_TO_JSVAL(jsfnObj), cif->nargs,
-       argv.Elements(), &rval))
+       argv.begin(), &rval))
     return;
 
   // Convert the result. Note that we pass 'isArgument = false', such that
   // ImplicitConvert will *not* autoconvert a JS string into a pointer-to-char
   // type, which would require an allocation that we can't track. The JS
   // function must perform this conversion itself and return a PointerType
   // CData; thusly, the burden of freeing the data is left to the user.
   ImplicitConvert(cx, rval, fninfo->mReturnType, result, false, NULL);
@@ -5031,17 +5054,17 @@ CData::Create(JSContext* cx,
 
   JSObject* proto = JSVAL_TO_OBJECT(slot);
   JSObject* parent = JS_GetParent(cx, typeObj);
   JS_ASSERT(parent);
 
   JSObject* dataObj = JS_NewObject(cx, &sCDataClass, proto, parent);
   if (!dataObj)
     return NULL;
-  JSAutoTempValueRooter root(cx, dataObj);
+  js::AutoValueRooter root(cx, dataObj);
 
   // set the CData's associated type
   if (!JS_SetReservedSlot(cx, dataObj, SLOT_CTYPE, OBJECT_TO_JSVAL(typeObj)))
     return NULL;
 
   // Stash the referent object, if any, for GC safety.
   if (refObj &&
       !JS_SetReservedSlot(cx, dataObj, SLOT_REFERENT, OBJECT_TO_JSVAL(refObj)))
@@ -5182,17 +5205,17 @@ CData::Address(JSContext* cx, uintN argc
     JS_ReportError(cx, "not a CData");
     return JS_FALSE;
   }
 
   JSObject* typeObj = CData::GetCType(cx, obj);
   JSObject* pointerType = PointerType::CreateInternal(cx, NULL, typeObj, NULL);
   if (!pointerType)
     return JS_FALSE;
-  JSAutoTempValueRooter root(cx, pointerType);
+  js::AutoValueRooter root(cx, pointerType);
 
   // Create a PointerType CData object containing null.
   JSObject* result = CData::Create(cx, pointerType, NULL, NULL, true);
   if (!result)
     return JS_FALSE;
 
   JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(result));
 
@@ -5298,23 +5321,30 @@ CData::ReadString(JSContext* cx, uintN a
   switch (CType::GetTypeCode(cx, baseType)) {
   case TYPE_int8_t:
   case TYPE_uint8_t:
   case TYPE_char:
   case TYPE_signed_char:
   case TYPE_unsigned_char: {
     char* bytes = static_cast<char*>(data);
     size_t length = strnlen(bytes, maxLength);
-    nsDependentCSubstring string(bytes, bytes + length);
-    if (!IsUTF8(string)) {
-      JS_ReportError(cx, "not a UTF-8 string");
+
+    // Determine the length.
+    size_t dstlen;
+    if (!js_InflateUTF8StringToBuffer(cx, bytes, length, NULL, &dstlen))
       return JS_FALSE;
-    }
-
-    result = NewUCString(cx, NS_ConvertUTF8toUTF16(string));
+
+    jschar* dst =
+      static_cast<jschar*>(JS_malloc(cx, (dstlen + 1) * sizeof(jschar)));
+    if (!dst)
+      return JS_FALSE;
+
+    ASSERT_OK(js_InflateUTF8StringToBuffer(cx, bytes, length, dst, &dstlen));
+
+    result = JS_NewUCString(cx, dst, dstlen);
     break;
   }
   case TYPE_int16_t:
   case TYPE_uint16_t:
   case TYPE_short:
   case TYPE_unsigned_short:
   case TYPE_jschar: {
     jschar* chars = static_cast<jschar*>(data);
@@ -5353,47 +5383,50 @@ CData::ToSource(JSContext* cx, uintN arg
   void* data = CData::GetData(cx, obj);
 
   // Walk the types, building up the toSource() string.
   // First, we build up the type expression:
   // 't.ptr' for pointers;
   // 't.array([n])' for arrays;
   // 'n' for structs, where n = t.name, the struct's name. (We assume this is
   // bound to a variable in the current scope.)
-  nsAutoString source = BuildTypeSource(cx, typeObj, true);
-  source.Append('(');
-  source.Append(BuildDataSource(cx, typeObj, data, false));
-  source.Append(')');
+  AutoString source;
+  BuildTypeSource(cx, typeObj, true, source);
+  AppendString(source, "(");
+  if (!BuildDataSource(cx, typeObj, data, false, source))
+    return JS_FALSE;
+
+  AppendString(source, ")");
 
   JSString* result = NewUCString(cx, source);
   if (!result)
     return JS_FALSE;
 
   JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(result));
   return JS_TRUE;
 }
 
 /*******************************************************************************
 ** Int64 and UInt64 implementation
 *******************************************************************************/
 
 JSObject*
 Int64Base::Construct(JSContext* cx,
                      JSObject* proto,
-                     PRUint64 data,
+                     JSUint64 data,
                      bool isUnsigned)
 {
   JSClass* clasp = isUnsigned ? &sUInt64Class : &sInt64Class;
   JSObject* result = JS_NewObject(cx, clasp, proto, JS_GetParent(cx, proto));
   if (!result)
     return NULL;
-  JSAutoTempValueRooter root(cx, result);
+  js::AutoValueRooter root(cx, result);
 
   // attach the Int64's data
-  PRUint64* buffer = new PRUint64(data);
+  JSUint64* buffer = new JSUint64(data);
   if (!buffer) {
     JS_ReportOutOfMemory(cx);
     return NULL;
   }
 
   if (!JS_SetReservedSlot(cx, result, SLOT_INT64, PRIVATE_TO_JSVAL(buffer))) {
     delete buffer;
     return NULL;
@@ -5407,26 +5440,26 @@ Int64Base::Construct(JSContext* cx,
 
 void
 Int64Base::Finalize(JSContext* cx, JSObject* obj)
 {
   jsval slot;
   if (!JS_GetReservedSlot(cx, obj, SLOT_INT64, &slot) || JSVAL_IS_VOID(slot))
     return;
 
-  delete static_cast<PRUint64*>(JSVAL_TO_PRIVATE(slot));
+  delete static_cast<JSUint64*>(JSVAL_TO_PRIVATE(slot));
 }
 
-PRUint64
+JSUint64
 Int64Base::GetInt(JSContext* cx, JSObject* obj) {
   JS_ASSERT(Int64::IsInt64(cx, obj) || UInt64::IsUInt64(cx, obj));
 
   jsval slot;
   ASSERT_OK(JS_GetReservedSlot(cx, obj, SLOT_INT64, &slot));
-  return *static_cast<PRUint64*>(JSVAL_TO_PRIVATE(slot));
+  return *static_cast<JSUint64*>(JSVAL_TO_PRIVATE(slot));
 }
 
 JSBool
 Int64Base::ToString(JSContext* cx,
                     JSObject* obj,
                     uintN argc,
                     jsval *vp,
                     bool isUnsigned)
@@ -5442,21 +5475,21 @@ Int64Base::ToString(JSContext* cx,
     if (JSVAL_IS_INT(arg))
       radix = JSVAL_TO_INT(arg);
     if (!JSVAL_IS_INT(arg) || radix < 2 || radix > 36) {
       JS_ReportError(cx, "radix argument must be an integer between 2 and 36");
       return JS_FALSE;
     }
   }
 
-  nsAutoString intString;
+  AutoString intString;
   if (isUnsigned) {
-    intString = IntegerToString(GetInt(cx, obj), radix);
+    IntegerToString(GetInt(cx, obj), radix, intString);
   } else {
-    intString = IntegerToString(static_cast<PRInt64>(GetInt(cx, obj)), radix);
+    IntegerToString(static_cast<JSInt64>(GetInt(cx, obj)), radix, intString);
   }
 
   JSString *result = NewUCString(cx, intString);
   if (!result)
     return JS_FALSE;
 
   JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(result));
   return JS_TRUE;
@@ -5470,25 +5503,25 @@ Int64Base::ToSource(JSContext* cx,
                     bool isUnsigned)
 {
   if (argc != 0) {
     JS_ReportError(cx, "toSource takes zero arguments");
     return JS_FALSE;
   }
 
   // Return a decimal string suitable for constructing the number.
-  nsAutoString source;
+  AutoString source;
   if (isUnsigned) {
-    source.Append(NS_LITERAL_STRING("ctypes.UInt64(\""));
-    source.Append(IntegerToString(GetInt(cx, obj), 10));
+    AppendString(source, "ctypes.UInt64(\"");
+    IntegerToString(GetInt(cx, obj), 10, source);
   } else {
-    source.Append(NS_LITERAL_STRING("ctypes.Int64(\""));
-    source.Append(IntegerToString(static_cast<PRInt64>(GetInt(cx, obj)), 10));
-  }
-  source.Append(NS_LITERAL_STRING("\")"));
+    AppendString(source, "ctypes.Int64(\"");
+    IntegerToString(static_cast<JSInt64>(GetInt(cx, obj)), 10, source);
+  }
+  AppendString(source, "\")");
 
   JSString *result = NewUCString(cx, source);
   if (!result)
     return JS_FALSE;
 
   JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(result));
   return JS_TRUE;
 }
@@ -5501,17 +5534,17 @@ Int64::Construct(JSContext* cx,
                  jsval* rval)
 {
   // Construct and return a new Int64 object.
   if (argc != 1) {
     JS_ReportError(cx, "Int64 takes one argument");
     return JS_FALSE;
   }
 
-  PRInt64 i;
+  JSInt64 i;
   if (!jsvalToBigInteger(cx, argv[0], true, &i))
     return TypeError(cx, "int64", argv[0]);
 
   // Get ctypes.Int64.prototype from the 'prototype' property of the ctor.
   jsval slot;
   ASSERT_OK(JS_GetProperty(cx, JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv)),
     "prototype", &slot));
   JSObject* proto = JSVAL_TO_OBJECT(slot);
@@ -5566,46 +5599,46 @@ Int64::Compare(JSContext* cx, uintN argc
       !Int64::IsInt64(cx, JSVAL_TO_OBJECT(argv[1]))) {
     JS_ReportError(cx, "compare takes two Int64 arguments");
     return JS_FALSE;
   }
 
   JSObject* obj1 = JSVAL_TO_OBJECT(argv[0]);
   JSObject* obj2 = JSVAL_TO_OBJECT(argv[1]);
 
-  PRInt64 i1 = Int64Base::GetInt(cx, obj1);
-  PRInt64 i2 = Int64Base::GetInt(cx, obj2);
+  JSInt64 i1 = Int64Base::GetInt(cx, obj1);
+  JSInt64 i2 = Int64Base::GetInt(cx, obj2);
 
   if (i1 == i2)
     JS_SET_RVAL(cx, vp, INT_TO_JSVAL(0));
   else if (i1 < i2)
     JS_SET_RVAL(cx, vp, INT_TO_JSVAL(-1));
   else
     JS_SET_RVAL(cx, vp, INT_TO_JSVAL(1));
 
   return JS_TRUE;
 }
 
-#define LO_MASK ((PRUint64(1) << 32) - 1)
+#define LO_MASK ((JSUint64(1) << 32) - 1)
 #define INT64_LO(i) ((i) & LO_MASK)
 #define INT64_HI(i) ((i) >> 32)
 
 JSBool
 Int64::Lo(JSContext* cx, uintN argc, jsval* vp)
 {
   jsval* argv = JS_ARGV(cx, vp);
   if (argc != 1 || JSVAL_IS_PRIMITIVE(argv[0]) ||
       !Int64::IsInt64(cx, JSVAL_TO_OBJECT(argv[0]))) {
     JS_ReportError(cx, "lo takes one Int64 argument");
     return JS_FALSE;
   }
 
   JSObject* obj = JSVAL_TO_OBJECT(argv[0]);
-  PRInt64 u = Int64Base::GetInt(cx, obj);
-  jsdouble d = PRUint32(INT64_LO(u));
+  JSInt64 u = Int64Base::GetInt(cx, obj);
+  jsdouble d = JSUint32(INT64_LO(u));
 
   jsval result;
   if (!JS_NewNumberValue(cx, d, &result))
     return JS_FALSE;
 
   JS_SET_RVAL(cx, vp, result);
   return JS_TRUE;
 }
@@ -5616,18 +5649,18 @@ Int64::Hi(JSContext* cx, uintN argc, jsv
   jsval* argv = JS_ARGV(cx, vp);
   if (argc != 1 || JSVAL_IS_PRIMITIVE(argv[0]) ||
       !Int64::IsInt64(cx, JSVAL_TO_OBJECT(argv[0]))) {
     JS_ReportError(cx, "hi takes one Int64 argument");
     return JS_FALSE;
   }
 
   JSObject* obj = JSVAL_TO_OBJECT(argv[0]);
-  PRInt64 u = Int64Base::GetInt(cx, obj);
-  jsdouble d = PRInt32(INT64_HI(u));
+  JSInt64 u = Int64Base::GetInt(cx, obj);
+  jsdouble d = JSInt32(INT64_HI(u));
 
   jsval result;
   if (!JS_NewNumberValue(cx, d, &result))
     return JS_FALSE;
 
   JS_SET_RVAL(cx, vp, result);
   return JS_TRUE;
 }
@@ -5636,24 +5669,24 @@ JSBool
 Int64::Join(JSContext* cx, uintN argc, jsval* vp)
 {
   if (argc != 2) {
     JS_ReportError(cx, "join takes two arguments");
     return JS_FALSE;
   }
 
   jsval* argv = JS_ARGV(cx, vp);
-  PRInt32 hi;
-  PRUint32 lo;
+  JSInt32 hi;
+  JSUint32 lo;
   if (!jsvalToInteger(cx, argv[0], &hi))
     return TypeError(cx, "int32", argv[0]);
   if (!jsvalToInteger(cx, argv[1], &lo))
     return TypeError(cx, "uint32", argv[1]);
 
-  PRInt64 i = (PRInt64(hi) << 32) + PRInt64(lo);
+  JSInt64 i = (JSInt64(hi) << 32) + JSInt64(lo);
 
   // Get Int64.prototype from the function's reserved slot.
   JSObject* callee = JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv));
 
   jsval slot;
   ASSERT_OK(JS_GetReservedSlot(cx, callee, SLOT_FN_INT64PROTO, &slot));
   JSObject* proto = JSVAL_TO_OBJECT(slot);
   JS_ASSERT(JS_GET_CLASS(cx, proto) == &sInt64ProtoClass);
@@ -5674,17 +5707,17 @@ UInt64::Construct(JSContext* cx,
                   jsval* rval)
 {
   // Construct and return a new UInt64 object.
   if (argc != 1) {
     JS_ReportError(cx, "UInt64 takes one argument");
     return JS_FALSE;
   }
 
-  PRUint64 u;
+  JSUint64 u;
   if (!jsvalToBigInteger(cx, argv[0], true, &u))
     return TypeError(cx, "uint64", argv[0]);
 
   // Get ctypes.UInt64.prototype from the 'prototype' property of the ctor.
   jsval slot;
   ASSERT_OK(JS_GetProperty(cx, JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv)),
     "prototype", &slot));
   JSObject* proto = JSVAL_TO_OBJECT(slot);
@@ -5739,18 +5772,18 @@ UInt64::Compare(JSContext* cx, uintN arg
       !UInt64::IsUInt64(cx, JSVAL_TO_OBJECT(argv[1]))) {
     JS_ReportError(cx, "compare takes two UInt64 arguments");
     return JS_FALSE;
   }
 
   JSObject* obj1 = JSVAL_TO_OBJECT(argv[0]);
   JSObject* obj2 = JSVAL_TO_OBJECT(argv[1]);
 
-  PRUint64 u1 = Int64Base::GetInt(cx, obj1);
-  PRUint64 u2 = Int64Base::GetInt(cx, obj2);
+  JSUint64 u1 = Int64Base::GetInt(cx, obj1);
+  JSUint64 u2 = Int64Base::GetInt(cx, obj2);
 
   if (u1 == u2)
     JS_SET_RVAL(cx, vp, INT_TO_JSVAL(0));
   else if (u1 < u2)
     JS_SET_RVAL(cx, vp, INT_TO_JSVAL(-1));
   else
     JS_SET_RVAL(cx, vp, INT_TO_JSVAL(1));
 
@@ -5763,18 +5796,18 @@ UInt64::Lo(JSContext* cx, uintN argc, js
   jsval* argv = JS_ARGV(cx, vp);
   if (argc != 1 || JSVAL_IS_PRIMITIVE(argv[0]) ||
       !UInt64::IsUInt64(cx, JSVAL_TO_OBJECT(argv[0]))) {
     JS_ReportError(cx, "lo takes one UInt64 argument");
     return JS_FALSE;
   }
 
   JSObject* obj = JSVAL_TO_OBJECT(argv[0]);
-  PRUint64 u = Int64Base::GetInt(cx, obj);
-  jsdouble d = PRUint32(INT64_LO(u));
+  JSUint64 u = Int64Base::GetInt(cx, obj);
+  jsdouble d = JSUint32(INT64_LO(u));
 
   jsval result;
   if (!JS_NewNumberValue(cx, d, &result))
     return JS_FALSE;
 
   JS_SET_RVAL(cx, vp, result);
   return JS_TRUE;
 }
@@ -5785,18 +5818,18 @@ UInt64::Hi(JSContext* cx, uintN argc, js
   jsval* argv = JS_ARGV(cx, vp);
   if (argc != 1 || JSVAL_IS_PRIMITIVE(argv[0]) ||
       !UInt64::IsUInt64(cx, JSVAL_TO_OBJECT(argv[0]))) {
     JS_ReportError(cx, "hi takes one UInt64 argument");
     return JS_FALSE;
   }
 
   JSObject* obj = JSVAL_TO_OBJECT(argv[0]);
-  PRUint64 u = Int64Base::GetInt(cx, obj);
-  jsdouble d = PRUint32(INT64_HI(u));
+  JSUint64 u = Int64Base::GetInt(cx, obj);
+  jsdouble d = JSUint32(INT64_HI(u));
 
   jsval result;
   if (!JS_NewNumberValue(cx, d, &result))
     return JS_FALSE;
 
   JS_SET_RVAL(cx, vp, result);
   return JS_TRUE;
 }
@@ -5805,24 +5838,24 @@ JSBool
 UInt64::Join(JSContext* cx, uintN argc, jsval* vp)
 {
   if (argc != 2) {
     JS_ReportError(cx, "join takes two arguments");
     return JS_FALSE;
   }
 
   jsval* argv = JS_ARGV(cx, vp);
-  PRUint32 hi;
-  PRUint32 lo;
+  JSUint32 hi;
+  JSUint32 lo;
   if (!jsvalToInteger(cx, argv[0], &hi))
     return TypeError(cx, "uint32_t", argv[0]);
   if (!jsvalToInteger(cx, argv[1], &lo))
     return TypeError(cx, "uint32_t", argv[1]);
 
-  PRUint64 u = (PRUint64(hi) << 32) + PRUint64(lo);
+  JSUint64 u = (JSUint64(hi) << 32) + JSUint64(lo);
 
   // Get UInt64.prototype from the function's reserved slot.
   JSObject* callee = JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv));
 
   jsval slot;
   ASSERT_OK(JS_GetReservedSlot(cx, callee, SLOT_FN_INT64PROTO, &slot));
   JSObject* proto = JSVAL_TO_OBJECT(slot);
   JS_ASSERT(JS_GET_CLASS(cx, proto) == &sUInt64ProtoClass);
rename from js/ctypes/CTypes.h
rename to js/src/ctypes/CTypes.h
--- a/js/ctypes/CTypes.h
+++ b/js/src/ctypes/CTypes.h
@@ -34,26 +34,179 @@
  * 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 CTYPES_H
 #define CTYPES_H
 
+#include "jscntxt.h"
 #include "jsapi.h"
-#include "nsString.h"
-#include "nsTArray.h"
 #include "prlink.h"
 #include "ffi.h"
 
-namespace mozilla {
+namespace js {
 namespace ctypes {
 
 /*******************************************************************************
+** Utility classes
+*******************************************************************************/
+
+template<class T>
+class OperatorDelete
+{
+public:
+  static void destroy(T* ptr) { delete ptr; }
+};
+
+template<class T>
+class OperatorArrayDelete
+{
+public:
+  static void destroy(T* ptr) { delete[] ptr; }
+};
+
+// Class that takes ownership of a pointer T*, and calls operator delete or
+// operator delete[] upon destruction.
+template<class T, class DeleteTraits = OperatorDelete<T> >
+class AutoPtr {
+private:
+  typedef AutoPtr<T, DeleteTraits> self_type;
+
+public:
+  // An AutoPtr variant that calls operator delete[] instead.
+  typedef AutoPtr<T, OperatorArrayDelete<T> > Array;
+
+  AutoPtr() : mPtr(NULL) { }
+  explicit AutoPtr(T* ptr) : mPtr(ptr) { }
+  ~AutoPtr() { DeleteTraits::destroy(mPtr); }
+
+  T*   operator->()         { return mPtr; }
+  bool operator!()          { return mPtr == NULL; }
+  T&   operator[](size_t i) { return *(mPtr + i); }
+  // Note: we cannot safely provide an 'operator T*()', since this would allow
+  // the compiler to perform implicit conversion from one AutoPtr to another
+  // via the constructor AutoPtr(T*).
+
+  T*   get()         { return mPtr; }
+  void set(T* other) { JS_ASSERT(mPtr == NULL); mPtr = other; }
+  T*   forget()      { T* result = mPtr; mPtr = NULL; return result; }
+
+  self_type& operator=(T* rhs) { mPtr = rhs; return *this; }
+
+private:
+  // Do not allow copy construction or assignment from another AutoPtr.
+  template<class U> AutoPtr(AutoPtr<T, U>&);
+  template<class U> self_type& operator=(AutoPtr<T, U>& rhs);
+
+  T* mPtr;
+};
+
+// Container class for Vector, using SystemAllocPolicy.
+template<class T, size_t N = 0>
+class Array : public Vector<T, N, SystemAllocPolicy>
+{
+};
+
+// String and AutoString classes, based on Vector.
+typedef Vector<jschar,  0, SystemAllocPolicy> String;
+typedef Vector<jschar, 64, SystemAllocPolicy> AutoString;
+
+// Convenience functions to append, insert, and compare Strings.
+template <class T, size_t N, class AP, size_t ArrayLength>
+void
+AppendString(Vector<T, N, AP> &v, const char (&array)[ArrayLength])
+{
+  // Don't include the trailing '\0'.
+  size_t alen = ArrayLength - 1;
+  size_t vlen = v.length();
+  if (!v.resize(vlen + alen))
+    return;
+
+  for (size_t i = 0; i < alen; ++i)
+    v[i + vlen] = array[i];
+}
+
+template <class T, size_t N, size_t M, class AP>
+void
+AppendString(Vector<T, N, AP> &v, Vector<T, M, AP> &w)
+{
+  v.append(w.begin(), w.length());
+}
+
+template <size_t N, class AP>
+void
+AppendString(Vector<jschar, N, AP> &v, JSString* str)
+{
+  JS_ASSERT(str);
+  const jschar* chars = JS_GetStringChars(str);
+  size_t length = JS_GetStringLength(str);
+  v.append(chars, length);
+}
+
+template <class T, size_t N, class AP, size_t ArrayLength>
+void
+PrependString(Vector<T, N, AP> &v, const char (&array)[ArrayLength])
+{
+  // Don't include the trailing '\0'.
+  size_t alen = ArrayLength - 1;
+  size_t vlen = v.length();
+  if (!v.resize(vlen + alen))
+    return;
+
+  // Move vector data forward. This is safe since we've already resized.
+  memmove(v.begin() + alen, v.begin(), vlen * sizeof(T));
+
+  // Copy data to insert.
+  for (size_t i = 0; i < alen; ++i)
+    v[i] = array[i];
+}
+
+template <size_t N, class AP>
+void
+PrependString(Vector<jschar, N, AP> &v, JSString* str)
+{
+  JS_ASSERT(str);
+  size_t vlen = v.length();
+  size_t alen = JS_GetStringLength(str);
+  if (!v.resize(vlen + alen))
+    return;
+
+  // Move vector data forward. This is safe since we've already resized.
+  memmove(v.begin() + alen, v.begin(), vlen * sizeof(jschar));
+
+  // Copy data to insert.
+  memcpy(v.begin(), JS_GetStringChars(str), alen * sizeof(jschar));
+}
+
+template <class T, size_t N, size_t M, class AP>
+bool
+StringsEqual(Vector<T, N, AP> &v, Vector<T, M, AP> &w)
+{
+  if (v.length() != w.length())
+    return false;
+
+  return memcmp(v.begin(), w.begin(), v.length() * sizeof(T)) == 0;
+}
+
+template <size_t N, class AP>
+bool
+StringsEqual(Vector<jschar, N, AP> &v, JSString* str)
+{
+  JS_ASSERT(str);
+  size_t length = JS_GetStringLength(str);
+  if (v.length() != length)
+    return false;
+
+  const jschar* chars = JS_GetStringChars(str);
+  return memcmp(v.begin(), chars, length * sizeof(jschar)) == 0;
+}
+
+/*******************************************************************************
 ** Function and struct API definitions
 *******************************************************************************/
 
 // for JS error reporting
 enum ErrorNum {
 #define MSG_DEF(name, number, count, exception, format) \
   name = number,
 #include "ctypes.msg"
@@ -84,17 +237,24 @@ enum TypeCode {
   TYPE_pointer,
   TYPE_function,
   TYPE_array,
   TYPE_struct
 };
 
 struct FieldInfo
 {
-  nsString  mName;
+  // We need to provide a copy constructor because of Vector.
+  FieldInfo() {}
+  FieldInfo(const FieldInfo& other)
+  {
+    JS_NOT_REACHED("shouldn't be copy constructing FieldInfo");
+  }
+
+  String    mName;
   JSObject* mType;
   size_t    mOffset;
 };
 
 // Just like JSPropertySpec, but with a Unicode name.
 struct PropertySpec
 {
   const jschar* name;
@@ -117,40 +277,37 @@ struct FunctionInfo
   // and OBJECT_TO_JSVAL. Stored as a JSObject* for ease of tracing.
   JSObject* mABI;                
 
   // The CType of the value returned by the function.
   JSObject* mReturnType;
 
   // A fixed array of known parameter types, excluding any variadic
   // parameters (if mIsVariadic).
-  nsTArray<JSObject*> mArgTypes; 
+  Array<JSObject*> mArgTypes; 
 
   // A variable array of ffi_type*s corresponding to both known parameter
   // types and dynamic (variadic) parameter types. Longer than mArgTypes
   // only if mIsVariadic.
-  nsTArray<ffi_type*> mFFITypes;
+  Array<ffi_type*> mFFITypes;
 
   // Flag indicating whether the function behaves like a C function with
   // ... as the final formal parameter.
   bool mIsVariadic;
 };
 
 // Parameters necessary for invoking a JS function from a C closure.
 struct ClosureInfo
 {
   JSContext* cx;         // JSContext to use
   JSObject* closureObj;  // CClosure object
   JSObject* typeObj;     // FunctionType describing the C function
   JSObject* thisObj;     // 'this' object to use for the JS function call
   JSObject* jsfnObj;     // JS function
   ffi_closure* closure;  // The C closure itself
-#ifdef DEBUG
-  PRThread* thread;      // The thread the closure was created on
-#endif
 };
 
 JSBool InitTypeClasses(JSContext* cx, JSObject* parent);
 
 JSBool ConvertToJS(JSContext* cx, JSObject* typeObj, JSObject* dataObj,
   void* data, bool wantPrimitive, bool ownResult, jsval* result);
 
 JSBool ImplicitConvert(JSContext* cx, jsval val, JSObject* targetType,
@@ -270,17 +427,17 @@ namespace ArrayType {
     bool lengthDefined);
 
   JSObject* GetBaseType(JSContext* cx, JSObject* obj);
   size_t GetLength(JSContext* cx, JSObject* obj);
   bool GetSafeLength(JSContext* cx, JSObject* obj, size_t* result);
 }
 
 namespace StructType {
-  nsTArray<FieldInfo>* GetFieldInfo(JSContext* cx, JSObject* obj);
+  Array<FieldInfo>* GetFieldInfo(JSContext* cx, JSObject* obj);
   FieldInfo* LookupField(JSContext* cx, JSObject* obj, jsval idval);
 }
 
 namespace FunctionType {
   JSObject* CreateInternal(JSContext* cx, jsval abi, jsval rtype,
     jsval* argtypes, jsuint arglen);
 
   JSObject* ConstructWithObject(JSContext* cx, JSObject* typeObj,
rename from js/ctypes/Library.cpp
rename to js/src/ctypes/Library.cpp
--- a/js/ctypes/Library.cpp
+++ b/js/src/ctypes/Library.cpp
@@ -36,22 +36,19 @@
  * 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 "jscntxt.h"
 #include "Library.h"
 #include "CTypes.h"
-#include "nsServiceManagerUtils.h"
-#include "nsIXPConnect.h"
-#include "nsILocalFile.h"
-#include "nsNativeCharsetUtils.h"
+#include "prlink.h"
 
-namespace mozilla {
+namespace js {
 namespace ctypes {
 
 /*******************************************************************************
 ** JSAPI function prototypes
 *******************************************************************************/
 
 namespace Library
 {
@@ -83,76 +80,57 @@ static JSFunctionSpec sLibraryFunctions[
 };
 
 JSObject*
 Library::Create(JSContext* cx, jsval aPath)
 {
   JSObject* libraryObj = JS_NewObject(cx, &sLibraryClass, NULL, NULL);
   if (!libraryObj)
     return NULL;
-  JSAutoTempValueRooter root(cx, libraryObj);
+  js::AutoValueRooter root(cx, libraryObj);
 
   // initialize the library
   if (!JS_SetReservedSlot(cx, libraryObj, SLOT_LIBRARY, PRIVATE_TO_JSVAL(NULL)))
     return NULL;
 
   // attach API functions
   if (!JS_DefineFunctions(cx, libraryObj, sLibraryFunctions))
     return NULL;
 
-  nsresult rv;
-  PRLibrary* library;
-
-  // get the path argument. we accept either an nsILocalFile or a string path.
-  // determine which we have...
-  if (JSVAL_IS_STRING(aPath)) {
-    const PRUnichar* path = reinterpret_cast<const PRUnichar*>(
-      JS_GetStringCharsZ(cx, JSVAL_TO_STRING(aPath)));
-    if (!path)
-      return NULL;
+  if (!JSVAL_IS_STRING(aPath)) {
+    JS_ReportError(cx, "open takes a string argument");
+    return NULL;
+  }
 
-    // We don't use nsILocalFile, because it doesn't use the system search
-    // rules when resolving library path.
-    PRLibSpec libSpec;
+  PRLibSpec libSpec;
 #ifdef XP_WIN
-    // On Windows, converting to native charset may corrupt path string.
-    // So, we have to use Unicode path directly.
-    libSpec.value.pathname_u = path;
-    libSpec.type = PR_LibSpec_PathnameU;
+  // On Windows, converting to native charset may corrupt path string.
+  // So, we have to use Unicode path directly.
+  const PRUnichar* path = reinterpret_cast<const PRUnichar*>(
+    JS_GetStringCharsZ(cx, JSVAL_TO_STRING(aPath)));
+  if (!path)
+    return NULL;
+
+  libSpec.value.pathname_u = path;
+  libSpec.type = PR_LibSpec_PathnameU;
 #else
-    nsCAutoString nativePath;
-    NS_CopyUnicodeToNative(nsDependentString(path), nativePath);
-    libSpec.value.pathname = nativePath.get();
-    libSpec.type = PR_LibSpec_Pathname;
+  // Assume the JS string is not UTF-16, but is in the platform's native
+  // charset. (This basically means ASCII.) It would be nice to have a
+  // UTF-16 -> native charset implementation available. :(
+  const char* path = JS_GetStringBytesZ(cx, JSVAL_TO_STRING(aPath));
+  if (!path)
+    return NULL;
+
+  libSpec.value.pathname = path;
+  libSpec.type = PR_LibSpec_Pathname;
 #endif
-    library = PR_LoadLibraryWithFlags(libSpec, 0);
-    if (!library) {
-      JS_ReportError(cx, "couldn't open library");
-      return NULL;
-    }
 
-  } else if (!JSVAL_IS_PRIMITIVE(aPath)) {
-    nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
-
-    nsISupports* file = xpc->GetNativeOfWrapper(cx, JSVAL_TO_OBJECT(aPath));
-    nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(file);
-    if (!localFile) {
-      JS_ReportError(cx, "open takes a string or nsILocalFile argument");
-      return NULL;
-    }
-
-    rv = localFile->Load(&library);
-    if (NS_FAILED(rv)) {
-      JS_ReportError(cx, "couldn't open library");
-      return NULL;
-    }
-
-  } else {
-    // don't convert the argument
-    JS_ReportError(cx, "open takes a string or nsIFile argument");
+  PRLibrary* library = PR_LoadLibraryWithFlags(libSpec, 0);
+  if (!library) {
+    JS_ReportError(cx, "couldn't open library");
     return NULL;
   }
 
   // stash the library
   if (!JS_SetReservedSlot(cx, libraryObj, SLOT_LIBRARY,
          PRIVATE_TO_JSVAL(library)))
     return NULL;
 
@@ -259,17 +237,17 @@ Library::Declare(JSContext* cx, uintN ar
     return JS_FALSE;
   }
 
   // Create a FunctionType representing the function.
   JSObject* typeObj = FunctionType::CreateInternal(cx,
                         argv[1], argv[2], &argv[3], argc - 3);
   if (!typeObj)
     return JS_FALSE;
-  JSAutoTempValueRooter root(cx, typeObj);
+  js::AutoValueRooter root(cx, typeObj);
 
   JSObject* fn = CData::Create(cx, typeObj, obj, &func, true);
   if (!fn)
     return JS_FALSE;
 
   JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(fn));
 
   // Seal the CData object, to prevent modification of the function pointer.
rename from js/ctypes/Library.h
rename to js/src/ctypes/Library.h
--- a/js/ctypes/Library.h
+++ b/js/src/ctypes/Library.h
@@ -35,19 +35,21 @@
  * 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 "jsapi.h"
+
 struct PRLibrary;
 
-namespace mozilla {
+namespace js {
 namespace ctypes {
 
 enum LibrarySlot {
   SLOT_LIBRARY = 0,
   LIBRARY_SLOTS
 };
 
 namespace Library
rename from js/ctypes/ctypes.msg
rename to js/src/ctypes/ctypes.msg
rename from js/ctypes/libffi.patch
rename to js/src/ctypes/libffi.patch
rename from js/ctypes/libffi/ChangeLog
rename to js/src/ctypes/libffi/ChangeLog
rename from js/ctypes/libffi/ChangeLog.libffi
rename to js/src/ctypes/libffi/ChangeLog.libffi
rename from js/ctypes/libffi/ChangeLog.libgcj
rename to js/src/ctypes/libffi/ChangeLog.libgcj
rename from js/ctypes/libffi/ChangeLog.v1
rename to js/src/ctypes/libffi/ChangeLog.v1
rename from js/ctypes/libffi/LICENSE
rename to js/src/ctypes/libffi/LICENSE
rename from js/ctypes/libffi/Makefile.am
rename to js/src/ctypes/libffi/Makefile.am
rename from js/ctypes/libffi/Makefile.in
rename to js/src/ctypes/libffi/Makefile.in
rename from js/ctypes/libffi/README
rename to js/src/ctypes/libffi/README
rename from js/ctypes/libffi/acinclude.m4
rename to js/src/ctypes/libffi/acinclude.m4
rename from js/ctypes/libffi/aclocal.m4
rename to js/src/ctypes/libffi/aclocal.m4
rename from js/ctypes/libffi/compile
rename to js/src/ctypes/libffi/compile
rename from js/ctypes/libffi/config.guess
rename to js/src/ctypes/libffi/config.guess
rename from js/ctypes/libffi/config.sub
rename to js/src/ctypes/libffi/config.sub
rename from js/ctypes/libffi/configure
rename to js/src/ctypes/libffi/configure
rename from js/ctypes/libffi/configure.ac
rename to js/src/ctypes/libffi/configure.ac
rename from js/ctypes/libffi/configure.host
rename to js/src/ctypes/libffi/configure.host
rename from js/ctypes/libffi/depcomp
rename to js/src/ctypes/libffi/depcomp
rename from js/ctypes/libffi/doc/libffi.info
rename to js/src/ctypes/libffi/doc/libffi.info
rename from js/ctypes/libffi/doc/libffi.texi
rename to js/src/ctypes/libffi/doc/libffi.texi
rename from js/ctypes/libffi/doc/stamp-vti
rename to js/src/ctypes/libffi/doc/stamp-vti
rename from js/ctypes/libffi/doc/version.texi
rename to js/src/ctypes/libffi/doc/version.texi
rename from js/ctypes/libffi/fficonfig.h.in
rename to js/src/ctypes/libffi/fficonfig.h.in
rename from js/ctypes/libffi/include/Makefile.am
rename to js/src/ctypes/libffi/include/Makefile.am
rename from js/ctypes/libffi/include/Makefile.in
rename to js/src/ctypes/libffi/include/Makefile.in
rename from js/ctypes/libffi/include/ffi.h.in
rename to js/src/ctypes/libffi/include/ffi.h.in
rename from js/ctypes/libffi/include/ffi_common.h
rename to js/src/ctypes/libffi/include/ffi_common.h
rename from js/ctypes/libffi/install-sh
rename to js/src/ctypes/libffi/install-sh
rename from js/ctypes/libffi/libffi.pc.in
rename to js/src/ctypes/libffi/libffi.pc.in
rename from js/ctypes/libffi/libtool-version
rename to js/src/ctypes/libffi/libtool-version
rename from js/ctypes/libffi/ltmain.sh
rename to js/src/ctypes/libffi/ltmain.sh
rename from js/ctypes/libffi/m4/libtool.m4
rename to js/src/ctypes/libffi/m4/libtool.m4
rename from js/ctypes/libffi/m4/ltoptions.m4
rename to js/src/ctypes/libffi/m4/ltoptions.m4
rename from js/ctypes/libffi/m4/ltsugar.m4
rename to js/src/ctypes/libffi/m4/ltsugar.m4
rename from js/ctypes/libffi/m4/ltversion.m4
rename to js/src/ctypes/libffi/m4/ltversion.m4
rename from js/ctypes/libffi/m4/lt~obsolete.m4
rename to js/src/ctypes/libffi/m4/lt~obsolete.m4
rename from js/ctypes/libffi/man/Makefile.am
rename to js/src/ctypes/libffi/man/Makefile.am
rename from js/ctypes/libffi/man/Makefile.in
rename to js/src/ctypes/libffi/man/Makefile.in
rename from js/ctypes/libffi/man/ffi.3
rename to js/src/ctypes/libffi/man/ffi.3
rename from js/ctypes/libffi/man/ffi_call.3
rename to js/src/ctypes/libffi/man/ffi_call.3
rename from js/ctypes/libffi/man/ffi_prep_cif.3
rename to js/src/ctypes/libffi/man/ffi_prep_cif.3
rename from js/ctypes/libffi/mdate-sh
rename to js/src/ctypes/libffi/mdate-sh
rename from js/ctypes/libffi/missing
rename to js/src/ctypes/libffi/missing
rename from js/ctypes/libffi/msvcc.sh
rename to js/src/ctypes/libffi/msvcc.sh
rename from js/ctypes/libffi/src/alpha/ffi.c
rename to js/src/ctypes/libffi/src/alpha/ffi.c
rename from js/ctypes/libffi/src/alpha/ffitarget.h
rename to js/src/ctypes/libffi/src/alpha/ffitarget.h
rename from js/ctypes/libffi/src/alpha/osf.S
rename to js/src/ctypes/libffi/src/alpha/osf.S
rename from js/ctypes/libffi/src/arm/ffi.c
rename to js/src/ctypes/libffi/src/arm/ffi.c
rename from js/ctypes/libffi/src/arm/ffitarget.h
rename to js/src/ctypes/libffi/src/arm/ffitarget.h
rename from js/ctypes/libffi/src/arm/sysv.S
rename to js/src/ctypes/libffi/src/arm/sysv.S
rename from js/ctypes/libffi/src/avr32/ffi.c
rename to js/src/ctypes/libffi/src/avr32/ffi.c
rename from js/ctypes/libffi/src/avr32/ffitarget.h
rename to js/src/ctypes/libffi/src/avr32/ffitarget.h
rename from js/ctypes/libffi/src/avr32/sysv.S
rename to js/src/ctypes/libffi/src/avr32/sysv.S
rename from js/ctypes/libffi/src/closures.c
rename to js/src/ctypes/libffi/src/closures.c
rename from js/ctypes/libffi/src/cris/ffi.c
rename to js/src/ctypes/libffi/src/cris/ffi.c
rename from js/ctypes/libffi/src/cris/ffitarget.h
rename to js/src/ctypes/libffi/src/cris/ffitarget.h
rename from js/ctypes/libffi/src/cris/sysv.S
rename to js/src/ctypes/libffi/src/cris/sysv.S
rename from js/ctypes/libffi/src/debug.c
rename to js/src/ctypes/libffi/src/debug.c
rename from js/ctypes/libffi/src/dlmalloc.c
rename to js/src/ctypes/libffi/src/dlmalloc.c
rename from js/ctypes/libffi/src/frv/eabi.S
rename to js/src/ctypes/libffi/src/frv/eabi.S
rename from js/ctypes/libffi/src/frv/ffi.c
rename to js/src/ctypes/libffi/src/frv/ffi.c
rename from js/ctypes/libffi/src/frv/ffitarget.h
rename to js/src/ctypes/libffi/src/frv/ffitarget.h
rename from js/ctypes/libffi/src/ia64/ffi.c
rename to js/src/ctypes/libffi/src/ia64/ffi.c
rename from js/ctypes/libffi/src/ia64/ffitarget.h
rename to js/src/ctypes/libffi/src/ia64/ffitarget.h
rename from js/ctypes/libffi/src/ia64/ia64_flags.h
rename to js/src/ctypes/libffi/src/ia64/ia64_flags.h
rename from js/ctypes/libffi/src/ia64/unix.S
rename to js/src/ctypes/libffi/src/ia64/unix.S
rename from js/ctypes/libffi/src/java_raw_api.c
rename to js/src/ctypes/libffi/src/java_raw_api.c
rename from js/ctypes/libffi/src/m32r/ffi.c
rename to js/src/ctypes/libffi/src/m32r/ffi.c
rename from js/ctypes/libffi/src/m32r/ffitarget.h
rename to js/src/ctypes/libffi/src/m32r/ffitarget.h
rename from js/ctypes/libffi/src/m32r/sysv.S
rename to js/src/ctypes/libffi/src/m32r/sysv.S
rename from js/ctypes/libffi/src/m68k/ffi.c
rename to js/src/ctypes/libffi/src/m68k/ffi.c
rename from js/ctypes/libffi/src/m68k/ffitarget.h
rename to js/src/ctypes/libffi/src/m68k/ffitarget.h
rename from js/ctypes/libffi/src/m68k/sysv.S
rename to js/src/ctypes/libffi/src/m68k/sysv.S
rename from js/ctypes/libffi/src/mips/ffi.c
rename to js/src/ctypes/libffi/src/mips/ffi.c
rename from js/ctypes/libffi/src/mips/ffitarget.h
rename to js/src/ctypes/libffi/src/mips/ffitarget.h
rename from js/ctypes/libffi/src/mips/n32.S
rename to js/src/ctypes/libffi/src/mips/n32.S
rename from js/ctypes/libffi/src/mips/o32.S
rename to js/src/ctypes/libffi/src/mips/o32.S
rename from js/ctypes/libffi/src/moxie/eabi.S
rename to js/src/ctypes/libffi/src/moxie/eabi.S
rename from js/ctypes/libffi/src/moxie/ffi.c
rename to js/src/ctypes/libffi/src/moxie/ffi.c
rename from js/ctypes/libffi/src/moxie/ffitarget.h
rename to js/src/ctypes/libffi/src/moxie/ffitarget.h
rename from js/ctypes/libffi/src/pa/ffi.c
rename to js/src/ctypes/libffi/src/pa/ffi.c
rename from js/ctypes/libffi/src/pa/ffitarget.h
rename to js/src/ctypes/libffi/src/pa/ffitarget.h
rename from js/ctypes/libffi/src/pa/hpux32.S
rename to js/src/ctypes/libffi/src/pa/hpux32.S
rename from js/ctypes/libffi/src/pa/linux.S
rename to js/src/ctypes/libffi/src/pa/linux.S
rename from js/ctypes/libffi/src/powerpc/aix.S
rename to js/src/ctypes/libffi/src/powerpc/aix.S
rename from js/ctypes/libffi/src/powerpc/aix_closure.S
rename to js/src/ctypes/libffi/src/powerpc/aix_closure.S
rename from js/ctypes/libffi/src/powerpc/asm.h
rename to js/src/ctypes/libffi/src/powerpc/asm.h
rename from js/ctypes/libffi/src/powerpc/darwin.S
rename to js/src/ctypes/libffi/src/powerpc/darwin.S
rename from js/ctypes/libffi/src/powerpc/darwin_closure.S
rename to js/src/ctypes/libffi/src/powerpc/darwin_closure.S
rename from js/ctypes/libffi/src/powerpc/ffi.c
rename to js/src/ctypes/libffi/src/powerpc/ffi.c
rename from js/ctypes/libffi/src/powerpc/ffi_darwin.c
rename to js/src/ctypes/libffi/src/powerpc/ffi_darwin.c
rename from js/ctypes/libffi/src/powerpc/ffitarget.h
rename to js/src/ctypes/libffi/src/powerpc/ffitarget.h
rename from js/ctypes/libffi/src/powerpc/linux64.S
rename to js/src/ctypes/libffi/src/powerpc/linux64.S
rename from js/ctypes/libffi/src/powerpc/linux64_closure.S
rename to js/src/ctypes/libffi/src/powerpc/linux64_closure.S
rename from js/ctypes/libffi/src/powerpc/ppc_closure.S
rename to js/src/ctypes/libffi/src/powerpc/ppc_closure.S
rename from js/ctypes/libffi/src/powerpc/sysv.S
rename to js/src/ctypes/libffi/src/powerpc/sysv.S
rename from js/ctypes/libffi/src/prep_cif.c
rename to js/src/ctypes/libffi/src/prep_cif.c
rename from js/ctypes/libffi/src/raw_api.c
rename to js/src/ctypes/libffi/src/raw_api.c
rename from js/ctypes/libffi/src/s390/ffi.c
rename to js/src/ctypes/libffi/src/s390/ffi.c
rename from js/ctypes/libffi/src/s390/ffitarget.h
rename to js/src/ctypes/libffi/src/s390/ffitarget.h
rename from js/ctypes/libffi/src/s390/sysv.S
rename to js/src/ctypes/libffi/src/s390/sysv.S
rename from js/ctypes/libffi/src/sh/ffi.c
rename to js/src/ctypes/libffi/src/sh/ffi.c
rename from js/ctypes/libffi/src/sh/ffitarget.h
rename to js/src/ctypes/libffi/src/sh/ffitarget.h
rename from js/ctypes/libffi/src/sh/sysv.S
rename to js/src/ctypes/libffi/src/sh/sysv.S
rename from js/ctypes/libffi/src/sh64/ffi.c
rename to js/src/ctypes/libffi/src/sh64/ffi.c
rename from js/ctypes/libffi/src/sh64/ffitarget.h
rename to js/src/ctypes/libffi/src/sh64/ffitarget.h
rename from js/ctypes/libffi/src/sh64/sysv.S
rename to js/src/ctypes/libffi/src/sh64/sysv.S
rename from js/ctypes/libffi/src/sparc/ffi.c
rename to js/src/ctypes/libffi/src/sparc/ffi.c
rename from js/ctypes/libffi/src/sparc/ffitarget.h
rename to js/src/ctypes/libffi/src/sparc/ffitarget.h
rename from js/ctypes/libffi/src/sparc/v8.S
rename to js/src/ctypes/libffi/src/sparc/v8.S
rename from js/ctypes/libffi/src/sparc/v9.S
rename to js/src/ctypes/libffi/src/sparc/v9.S
rename from js/ctypes/libffi/src/types.c
rename to js/src/ctypes/libffi/src/types.c
rename from js/ctypes/libffi/src/x86/darwin.S
rename to js/src/ctypes/libffi/src/x86/darwin.S
rename from js/ctypes/libffi/src/x86/darwin64.S
rename to js/src/ctypes/libffi/src/x86/darwin64.S
rename from js/ctypes/libffi/src/x86/ffi.c
rename to js/src/ctypes/libffi/src/x86/ffi.c
rename from js/ctypes/libffi/src/x86/ffi64.c
rename to js/src/ctypes/libffi/src/x86/ffi64.c
rename from js/ctypes/libffi/src/x86/ffitarget.h
rename to js/src/ctypes/libffi/src/x86/ffitarget.h
rename from js/ctypes/libffi/src/x86/freebsd.S
rename to js/src/ctypes/libffi/src/x86/freebsd.S
rename from js/ctypes/libffi/src/x86/sysv.S
rename to js/src/ctypes/libffi/src/x86/sysv.S
rename from js/ctypes/libffi/src/x86/unix64.S
rename to js/src/ctypes/libffi/src/x86/unix64.S
rename from js/ctypes/libffi/src/x86/win32.S
rename to js/src/ctypes/libffi/src/x86/win32.S
rename from js/ctypes/libffi/src/x86/win64.S
rename to js/src/ctypes/libffi/src/x86/win64.S
rename from js/ctypes/libffi/testsuite/Makefile.am
rename to js/src/ctypes/libffi/testsuite/Makefile.am
rename from js/ctypes/libffi/testsuite/Makefile.in
rename to js/src/ctypes/libffi/testsuite/Makefile.in
rename from js/ctypes/libffi/testsuite/config/default.exp
rename to js/src/ctypes/libffi/testsuite/config/default.exp
rename from js/ctypes/libffi/testsuite/lib/libffi-dg.exp
rename to js/src/ctypes/libffi/testsuite/lib/libffi-dg.exp
rename from js/ctypes/libffi/testsuite/lib/target-libpath.exp
rename to js/src/ctypes/libffi/testsuite/lib/target-libpath.exp
rename from js/ctypes/libffi/testsuite/lib/wrapper.exp
rename to js/src/ctypes/libffi/testsuite/lib/wrapper.exp
rename from js/ctypes/libffi/testsuite/libffi.call/call.exp
rename to js/src/ctypes/libffi/testsuite/libffi.call/call.exp
rename from js/ctypes/libffi/testsuite/libffi.call/closure_fn0.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/closure_fn0.c
rename from js/ctypes/libffi/testsuite/libffi.call/closure_fn1.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/closure_fn1.c
rename from js/ctypes/libffi/testsuite/libffi.call/closure_fn2.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/closure_fn2.c
rename from js/ctypes/libffi/testsuite/libffi.call/closure_fn3.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/closure_fn3.c
rename from js/ctypes/libffi/testsuite/libffi.call/closure_fn4.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/closure_fn4.c
rename from js/ctypes/libffi/testsuite/libffi.call/closure_fn5.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/closure_fn5.c
rename from js/ctypes/libffi/testsuite/libffi.call/closure_fn6.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/closure_fn6.c
rename from js/ctypes/libffi/testsuite/libffi.call/closure_loc_fn0.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/closure_loc_fn0.c
rename from js/ctypes/libffi/testsuite/libffi.call/closure_stdcall.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/closure_stdcall.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_12byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_12byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_16byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_16byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_18byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_18byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_19byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_19byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_1_1byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_1_1byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_20byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_20byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_20byte1.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_20byte1.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_24byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_24byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_2byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_2byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_3_1byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_3_1byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_3byte1.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_3byte1.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_3byte2.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_3byte2.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_4_1byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_4_1byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_4byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_4byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_5_1_byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_5_1_byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_5byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_5byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_64byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_64byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_6_1_byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_6_1_byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_6byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_6byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_7_1_byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_7_1_byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_7byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_7byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_8byte.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_8byte.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_9byte1.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_9byte1.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_9byte2.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_9byte2.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_align_double.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_align_double.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_align_float.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_align_float.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_align_longdouble.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_align_longdouble.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_align_longdouble_split.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_align_longdouble_split.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_align_pointer.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_align_pointer.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_align_sint16.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_align_sint16.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_align_sint32.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_align_sint32.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_align_sint64.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_align_sint64.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_align_uint16.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_align_uint16.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_align_uint32.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_align_uint32.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_align_uint64.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_align_uint64.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_dbls_struct.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_dbls_struct.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_double.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_double.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_double_va.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_double_va.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_float.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_float.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_longdouble.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_longdouble.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_longdouble_va.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_longdouble_va.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_multi_schar.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_multi_schar.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_multi_sshort.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_multi_sshort.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_multi_sshortchar.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_multi_sshortchar.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_multi_uchar.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_multi_uchar.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_multi_ushort.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_multi_ushort.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_multi_ushortchar.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_multi_ushortchar.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_pointer.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_pointer.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_pointer_stack.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_pointer_stack.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_schar.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_schar.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_sint.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_sint.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_sshort.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_sshort.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_uchar.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_uchar.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_uint.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_uint.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_ulonglong.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_ulonglong.c
rename from js/ctypes/libffi/testsuite/libffi.call/cls_ushort.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/cls_ushort.c
rename from js/ctypes/libffi/testsuite/libffi.call/err_bad_abi.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/err_bad_abi.c
rename from js/ctypes/libffi/testsuite/libffi.call/err_bad_typedef.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/err_bad_typedef.c
rename from js/ctypes/libffi/testsuite/libffi.call/ffitest.h
rename to js/src/ctypes/libffi/testsuite/libffi.call/ffitest.h
rename from js/ctypes/libffi/testsuite/libffi.call/float.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/float.c
rename from js/ctypes/libffi/testsuite/libffi.call/float1.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/float1.c
rename from js/ctypes/libffi/testsuite/libffi.call/float2.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/float2.c
rename from js/ctypes/libffi/testsuite/libffi.call/float3.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/float3.c
rename from js/ctypes/libffi/testsuite/libffi.call/float4.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/float4.c
rename from js/ctypes/libffi/testsuite/libffi.call/huge_struct.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/huge_struct.c
rename from js/ctypes/libffi/testsuite/libffi.call/many.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/many.c
rename from js/ctypes/libffi/testsuite/libffi.call/many_win32.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/many_win32.c
rename from js/ctypes/libffi/testsuite/libffi.call/negint.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/negint.c
rename from js/ctypes/libffi/testsuite/libffi.call/nested_struct.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/nested_struct.c
rename from js/ctypes/libffi/testsuite/libffi.call/nested_struct1.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/nested_struct1.c
rename from js/ctypes/libffi/testsuite/libffi.call/nested_struct10.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/nested_struct10.c
rename from js/ctypes/libffi/testsuite/libffi.call/nested_struct2.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/nested_struct2.c
rename from js/ctypes/libffi/testsuite/libffi.call/nested_struct3.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/nested_struct3.c
rename from js/ctypes/libffi/testsuite/libffi.call/nested_struct4.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/nested_struct4.c
rename from js/ctypes/libffi/testsuite/libffi.call/nested_struct5.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/nested_struct5.c
rename from js/ctypes/libffi/testsuite/libffi.call/nested_struct6.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/nested_struct6.c
rename from js/ctypes/libffi/testsuite/libffi.call/nested_struct7.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/nested_struct7.c
rename from js/ctypes/libffi/testsuite/libffi.call/nested_struct8.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/nested_struct8.c
rename from js/ctypes/libffi/testsuite/libffi.call/nested_struct9.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/nested_struct9.c
rename from js/ctypes/libffi/testsuite/libffi.call/problem1.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/problem1.c
rename from js/ctypes/libffi/testsuite/libffi.call/promotion.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/promotion.c
rename from js/ctypes/libffi/testsuite/libffi.call/pyobjc-tc.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/pyobjc-tc.c
rename from js/ctypes/libffi/testsuite/libffi.call/return_dbl.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/return_dbl.c
rename from js/ctypes/libffi/testsuite/libffi.call/return_dbl1.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/return_dbl1.c
rename from js/ctypes/libffi/testsuite/libffi.call/return_dbl2.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/return_dbl2.c
rename from js/ctypes/libffi/testsuite/libffi.call/return_fl.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/return_fl.c
rename from js/ctypes/libffi/testsuite/libffi.call/return_fl1.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/return_fl1.c
rename from js/ctypes/libffi/testsuite/libffi.call/return_fl2.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/return_fl2.c
rename from js/ctypes/libffi/testsuite/libffi.call/return_fl3.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/return_fl3.c
rename from js/ctypes/libffi/testsuite/libffi.call/return_ldl.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/return_ldl.c
rename from js/ctypes/libffi/testsuite/libffi.call/return_ll.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/return_ll.c
rename from js/ctypes/libffi/testsuite/libffi.call/return_ll1.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/return_ll1.c
rename from js/ctypes/libffi/testsuite/libffi.call/return_sc.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/return_sc.c
rename from js/ctypes/libffi/testsuite/libffi.call/return_sl.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/return_sl.c
rename from js/ctypes/libffi/testsuite/libffi.call/return_uc.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/return_uc.c
rename from js/ctypes/libffi/testsuite/libffi.call/return_ul.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/return_ul.c
rename from js/ctypes/libffi/testsuite/libffi.call/stret_large.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/stret_large.c
rename from js/ctypes/libffi/testsuite/libffi.call/stret_large2.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/stret_large2.c
rename from js/ctypes/libffi/testsuite/libffi.call/stret_medium.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/stret_medium.c
rename from js/ctypes/libffi/testsuite/libffi.call/stret_medium2.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/stret_medium2.c
rename from js/ctypes/libffi/testsuite/libffi.call/strlen.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/strlen.c
rename from js/ctypes/libffi/testsuite/libffi.call/strlen_win32.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/strlen_win32.c
rename from js/ctypes/libffi/testsuite/libffi.call/struct1.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/struct1.c
rename from js/ctypes/libffi/testsuite/libffi.call/struct2.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/struct2.c
rename from js/ctypes/libffi/testsuite/libffi.call/struct3.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/struct3.c
rename from js/ctypes/libffi/testsuite/libffi.call/struct4.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/struct4.c
rename from js/ctypes/libffi/testsuite/libffi.call/struct5.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/struct5.c
rename from js/ctypes/libffi/testsuite/libffi.call/struct6.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/struct6.c
rename from js/ctypes/libffi/testsuite/libffi.call/struct7.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/struct7.c
rename from js/ctypes/libffi/testsuite/libffi.call/struct8.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/struct8.c
rename from js/ctypes/libffi/testsuite/libffi.call/struct9.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/struct9.c
rename from js/ctypes/libffi/testsuite/libffi.call/testclosure.c
rename to js/src/ctypes/libffi/testsuite/libffi.call/testclosure.c
rename from js/ctypes/libffi/testsuite/libffi.special/ffitestcxx.h
rename to js/src/ctypes/libffi/testsuite/libffi.special/ffitestcxx.h
rename from js/ctypes/libffi/testsuite/libffi.special/special.exp
rename to js/src/ctypes/libffi/testsuite/libffi.special/special.exp
rename from js/ctypes/libffi/testsuite/libffi.special/unwindtest.cc
rename to js/src/ctypes/libffi/testsuite/libffi.special/unwindtest.cc
rename from js/ctypes/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc
rename to js/src/ctypes/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc
rename from js/ctypes/libffi/texinfo.tex
rename to js/src/ctypes/libffi/texinfo.tex
rename from js/ctypes/typedefs.h
rename to js/src/ctypes/typedefs.h
--- a/js/ctypes/typedefs.h
+++ b/js/src/ctypes/typedefs.h
@@ -97,28 +97,28 @@
 #define CTYPES_FFI_ULONG     (sizeof(long)      == 4 ? ffi_type_uint32 : ffi_type_uint64)
 #define CTYPES_FFI_SIZE_T    (sizeof(size_t)    == 4 ? ffi_type_uint32 : ffi_type_uint64)
 #define CTYPES_FFI_SSIZE_T   (sizeof(size_t)    == 4 ? ffi_type_sint32 : ffi_type_sint64)
 #define CTYPES_FFI_INTPTR_T  (sizeof(uintptr_t) == 4 ? ffi_type_sint32 : ffi_type_sint64)
 #define CTYPES_FFI_UINTPTR_T (sizeof(uintptr_t) == 4 ? ffi_type_uint32 : ffi_type_uint64)
 
 // The meat.
 DEFINE_BOOL_TYPE       (bool,               bool,               CTYPES_FFI_BOOL)
-DEFINE_INT_TYPE        (int8_t,             PRInt8,             ffi_type_sint8)
-DEFINE_INT_TYPE        (int16_t,            PRInt16,            ffi_type_sint16)
-DEFINE_INT_TYPE        (int32_t,            PRInt32,            ffi_type_sint32)
-DEFINE_INT_TYPE        (uint8_t,            PRUint8,            ffi_type_uint8)
-DEFINE_INT_TYPE        (uint16_t,           PRUint16,           ffi_type_uint16)
-DEFINE_INT_TYPE        (uint32_t,           PRUint32,           ffi_type_uint32)
+DEFINE_INT_TYPE        (int8_t,             JSInt8,             ffi_type_sint8)
+DEFINE_INT_TYPE        (int16_t,            JSInt16,            ffi_type_sint16)
+DEFINE_INT_TYPE        (int32_t,            JSInt32,            ffi_type_sint32)
+DEFINE_INT_TYPE        (uint8_t,            JSUint8,            ffi_type_uint8)
+DEFINE_INT_TYPE        (uint16_t,           JSUint16,           ffi_type_uint16)
+DEFINE_INT_TYPE        (uint32_t,           JSUint32,           ffi_type_uint32)
 DEFINE_INT_TYPE        (short,              short,              ffi_type_sint16)
 DEFINE_INT_TYPE        (unsigned_short,     unsigned short,     ffi_type_uint16)
 DEFINE_INT_TYPE        (int,                int,                ffi_type_sint32)
 DEFINE_INT_TYPE        (unsigned_int,       unsigned int,       ffi_type_uint32)
-DEFINE_WRAPPED_INT_TYPE(int64_t,            PRInt64,            ffi_type_sint64)
-DEFINE_WRAPPED_INT_TYPE(uint64_t,           PRUint64,           ffi_type_uint64)
+DEFINE_WRAPPED_INT_TYPE(int64_t,            JSInt64,            ffi_type_sint64)
+DEFINE_WRAPPED_INT_TYPE(uint64_t,           JSUint64,           ffi_type_uint64)
 DEFINE_WRAPPED_INT_TYPE(long,               long,               CTYPES_FFI_LONG)
 DEFINE_WRAPPED_INT_TYPE(unsigned_long,      unsigned long,      CTYPES_FFI_ULONG)
 DEFINE_WRAPPED_INT_TYPE(long_long,          long long,          ffi_type_sint64)
 DEFINE_WRAPPED_INT_TYPE(unsigned_long_long, unsigned long long, ffi_type_uint64)
 DEFINE_WRAPPED_INT_TYPE(size_t,             size_t,             CTYPES_FFI_SIZE_T)
 DEFINE_WRAPPED_INT_TYPE(ssize_t,            CTYPES_SSIZE_T,     CTYPES_FFI_SSIZE_T)
 DEFINE_WRAPPED_INT_TYPE(intptr_t,           intptr_t,           CTYPES_FFI_INTPTR_T)
 DEFINE_WRAPPED_INT_TYPE(uintptr_t,          uintptr_t,          CTYPES_FFI_UINTPTR_T)
--- a/js/src/dtoa.c
+++ b/js/src/dtoa.c
@@ -96,19 +96,20 @@
  *	define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
  *	FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
  * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
  *	if memory is available and otherwise does something you deem
  *	appropriate.  If MALLOC is undefined, malloc will be invoked
  *	directly -- and assumed always to succeed.  Similarly, if you
  *	want something other than the system's free() to be called to
  *	recycle memory acquired from MALLOC, #define FREE to be the
- *	name of the alternate routine.  (FREE or free is only called in
- *	pathological cases, e.g., in a dtoa call after a dtoa return in
- *	mode 3 with thousands of digits requested.)
+ *	name of the alternate routine.  (Unless you #define
+ *	NO_GLOBAL_STATE and call destroydtoa, FREE or free is only
+ *	called in pathological cases, e.g., in a dtoa call after a dtoa
+ *	return in mode 3 with thousands of digits requested.)
  * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making
  *	memory allocations from a private pool of memory when possible.
  *	When used, the private pool is PRIVATE_MEM bytes long:  2304 bytes,
  *	unless #defined to be a different length.  This default length
  *	suffices to get rid of MALLOC calls except for unusual cases,
  *	such as decimal-to-binary conversion of a very long string of
  *	digits.  The longest string dtoa can return is about 751 bytes
  *	long.  For conversions by strtod of strings of 800 digits and
@@ -159,16 +160,22 @@
  *	such that get_inexact() returns a nonzero value if the
  *	inexact bit is already set, and clear_inexact() sets the
  *	inexact bit to 0.  When SET_INEXACT is #defined, strtod
  *	also does extra computations to set the underflow and overflow
  *	flags when appropriate (i.e., when the result is tiny and
  *	inexact or when it is a numeric value rounded to +-infinity).
  * #define NO_ERRNO if strtod should not assign errno = ERANGE when
  *	the result overflows to +-Infinity or underflows to 0.
+ * #define NO_GLOBAL_STATE to avoid defining any non-const global or
+ *	static variables. Instead the necessary state is stored in an
+ *	opaque struct, DtoaState, a pointer to which must be passed to
+ *	every entry point. Two new functions are added to the API:
+ *		DtoaState *newdtoa(void);
+ *		void destroydtoa(DtoaState *);
  */
 
 #ifndef Long
 #define Long long
 #endif
 #ifndef ULong
 typedef unsigned Long ULong;
 #endif
@@ -190,22 +197,25 @@ typedef unsigned Long ULong;
 extern char *MALLOC();
 #else
 extern void *MALLOC(size_t);
 #endif
 #else
 #define MALLOC malloc
 #endif
 
+#ifndef FREE
+#define FREE free
+#endif
+
 #ifndef Omit_Private_Memory
 #ifndef PRIVATE_MEM
 #define PRIVATE_MEM 2304
 #endif
 #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
-static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
 #endif
 
 #undef IEEE_Arith
 #undef Avoid_Underflow
 #ifdef IEEE_MC68k
 #define IEEE_Arith
 #endif
 #ifdef IEEE_8087
@@ -474,92 +484,161 @@ extern double rnd_prod(double, double), 
 Bigint {
 	struct Bigint *next;
 	int k, maxwds, sign, wds;
 	ULong x[1];
 	};
 
  typedef struct Bigint Bigint;
 
- static Bigint *freelist[Kmax+1];
+#ifdef NO_GLOBAL_STATE
+#ifdef MULTIPLE_THREADS
+#error "cannot have both NO_GLOBAL_STATE and MULTIPLE_THREADS"
+#endif
+ struct
+DtoaState {
+#define DECLARE_GLOBAL_STATE  /* nothing */
+#else
+#define DECLARE_GLOBAL_STATE static
+#endif
+
+	DECLARE_GLOBAL_STATE Bigint *freelist[Kmax+1];
+	DECLARE_GLOBAL_STATE Bigint *p5s;
+#ifndef Omit_Private_Memory
+	DECLARE_GLOBAL_STATE double private_mem[PRIVATE_mem];
+	DECLARE_GLOBAL_STATE double *pmem_next
+#ifndef NO_GLOBAL_STATE
+	                                       = private_mem
+#endif
+	                                                    ;
+#endif
+#ifdef NO_GLOBAL_STATE
+	};
+ typedef struct DtoaState DtoaState;
+#ifdef KR_headers
+#define STATE_PARAM state,
+#define STATE_PARAM_DECL DtoaState *state;
+#else
+#define STATE_PARAM DtoaState *state,
+#endif
+#define PASS_STATE state,
+#define GET_STATE(field) (state->field)
+
+ static DtoaState *
+newdtoa(void)
+{
+	DtoaState *state = (DtoaState *) MALLOC(sizeof(DtoaState));
+	if (state) {
+		memset(state, 0, sizeof(DtoaState));
+		state->pmem_next = state->private_mem;
+		}
+	return state;
+}
+
+ static void
+destroydtoa
+#ifdef KR_headers
+	(state) STATE_PARAM_DECL
+#else
+	(DtoaState *state)
+#endif
+{
+	int i;
+	Bigint *v, *next;
+
+	for (i = 0; i <= Kmax; i++) {
+		for (v = GET_STATE(freelist)[i]; v; v = next) {
+			next = v->next;
+#ifndef Omit_Private_Memory
+			if ((double*)v < GET_STATE(private_mem) ||
+			    (double*)v >= GET_STATE(private_mem) + PRIVATE_mem)
+#endif
+				FREE((void*)v);
+			}
+		}
+	FREE((void *)state);
+}
+
+#else
+#define STATE_PARAM      /* nothing */
+#define STATE_PARAM_DECL /* nothing */
+#define PASS_STATE       /* nothing */
+#define GET_STATE(name) name
+#endif
 
  static Bigint *
 Balloc
 #ifdef KR_headers
-	(k) int k;
+	(STATE_PARAM k) STATE_PARAM_DECL int k;
 #else
-	(int k)
+	(STATE_PARAM int k)
 #endif
 {
 	int x;
 	Bigint *rv;
 #ifndef Omit_Private_Memory
 	size_t len;
 #endif
 
 	ACQUIRE_DTOA_LOCK(0);
 	/* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */
 	/* but this case seems very unlikely. */
-	if (k <= Kmax && (rv = freelist[k]))
-		freelist[k] = rv->next;
+	if (k <= Kmax && (rv = GET_STATE(freelist)[k]))
+		GET_STATE(freelist)[k] = rv->next;
 	else {
 		x = 1 << k;
 #ifdef Omit_Private_Memory
 		rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
 #else
 		len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
 			/sizeof(double);
-		if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) {
-			rv = (Bigint*)pmem_next;
-			pmem_next += len;
+		if (k <= Kmax && GET_STATE(pmem_next) - GET_STATE(private_mem) + len <= PRIVATE_mem) {
+			rv = (Bigint*)GET_STATE(pmem_next);
+			GET_STATE(pmem_next) += len;
 			}
 		else
 			rv = (Bigint*)MALLOC(len*sizeof(double));
 #endif
 		rv->k = k;
 		rv->maxwds = x;
 		}
 	FREE_DTOA_LOCK(0);
 	rv->sign = rv->wds = 0;
 	return rv;
 	}
 
  static void
 Bfree
 #ifdef KR_headers
-	(v) Bigint *v;
+	(STATE_PARAM v) STATE_PARAM_DECL Bigint *v;
 #else
-	(Bigint *v)
+	(STATE_PARAM Bigint *v)
 #endif
 {
 	if (v) {
 		if (v->k > Kmax)
-#ifdef FREE
 			FREE((void*)v);
-#else
-			free((void*)v);
-#endif
 		else {
 			ACQUIRE_DTOA_LOCK(0);
-			v->next = freelist[v->k];
-			freelist[v->k] = v;
+			v->next = GET_STATE(freelist)[v->k];
+			GET_STATE(freelist)[v->k] = v;
 			FREE_DTOA_LOCK(0);
 			}
 		}
 	}
 
 #define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
 y->wds*sizeof(Long) + 2*sizeof(int))
 
  static Bigint *
 multadd
 #ifdef KR_headers
-	(b, m, a) Bigint *b; int m, a;
+	(STATE_PARAM b, m, a) STATE_PARAM_DECL Bigint *b; int m, a;
 #else
-	(Bigint *b, int m, int a)	/* multiply by m and add a */
+	(STATE_PARAM Bigint *b, int m, int a)	/* multiply by m and add a */
 #endif
 {
 	int i, wds;
 #ifdef ULLong
 	ULong *x;
 	ULLong carry, y;
 #else
 	ULong carry, *x, y;
@@ -590,62 +669,62 @@ multadd
 		carry = y >> 16;
 		*x++ = y & 0xffff;
 #endif
 #endif
 		}
 		while(++i < wds);
 	if (carry) {
 		if (wds >= b->maxwds) {
-			b1 = Balloc(b->k+1);
+			b1 = Balloc(PASS_STATE b->k+1);
 			Bcopy(b1, b);
-			Bfree(b);
+			Bfree(PASS_STATE b);
 			b = b1;
 			}
 		b->x[wds++] = (ULong) carry;
 		b->wds = wds;
 		}
 	return b;
 	}
 
  static Bigint *
 s2b
 #ifdef KR_headers
-	(s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9;
+	(STATE_PARAM s, nd0, nd, y9) STATE_PARAM_DECL CONST char *s; int nd0, nd; ULong y9;
 #else
-	(CONST char *s, int nd0, int nd, ULong y9)
+	(STATE_PARAM CONST char *s, int nd0, int nd, ULong y9)
 #endif
 {
 	Bigint *b;
 	int i, k;
 	Long x, y;
 
 	x = (nd + 8) / 9;
 	for(k = 0, y = 1; x > y; y <<= 1, k++) ;
 #ifdef Pack_32
-	b = Balloc(k);
+	b = Balloc(PASS_STATE k);
 	b->x[0] = y9;
 	b->wds = 1;
 #else
-	b = Balloc(k+1);
+	b = Balloc(PASS_STATE k+1);
 	b->x[0] = y9 & 0xffff;
 	b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
 #endif
 
 	i = 9;
 	if (9 < nd0) {
 		s += 9;
-		do b = multadd(b, 10, *s++ - '0');
+		do b = multadd(PASS_STATE b, 10, *s++ - '0');
 			while(++i < nd0);
 		s++;
 		}
 	else
 		s += 10;
 	for(; i < nd; i++)
-		b = multadd(b, 10, *s++ - '0');
+		b = multadd(PASS_STATE b, 10, *s++ - '0');
 	return b;
 	}
 
  static int
 hi0bits
 #ifdef KR_headers
 	(x) register ULong x;
 #else
@@ -724,35 +803,35 @@ lo0bits
 		}
 	*y = x;
 	return k;
 	}
 
  static Bigint *
 i2b
 #ifdef KR_headers
-	(i) int i;
+	(STATE_PARAM i) STATE_PARAM_DECL int i;
 #else
-	(int i)
+	(STATE_PARAM int i)
 #endif
 {
 	Bigint *b;
 
-	b = Balloc(1);
+	b = Balloc(PASS_STATE 1);
 	b->x[0] = i;
 	b->wds = 1;
 	return b;
 	}
 
  static Bigint *
 mult
 #ifdef KR_headers
-	(a, b) Bigint *a, *b;
+	(STATE_PARAM a, b) STATE_PARAM_DECL Bigint *a, *b;
 #else
-	(Bigint *a, Bigint *b)
+	(STATE_PARAM Bigint *a, Bigint *b)
 #endif
 {
 	Bigint *c;
 	int k, wa, wb, wc;
 	ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
 	ULong y;
 #ifdef ULLong
 	ULLong carry, z;
@@ -769,17 +848,17 @@ mult
 		b = c;
 		}
 	k = a->k;
 	wa = a->wds;
 	wb = b->wds;
 	wc = wa + wb;
 	if (wc > a->maxwds)
 		k++;
-	c = Balloc(k);
+	c = Balloc(PASS_STATE k);
 	for(x = c->x, xa = x + wc; x < xa; x++)
 		*x = 0;
 	xa = a->x;
 	xae = xa + wa;
 	xb = b->x;
 	xbe = xb + wb;
 	xc0 = c->x;
 #ifdef ULLong
@@ -847,97 +926,95 @@ mult
 		}
 #endif
 #endif
 	for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
 	c->wds = wc;
 	return c;
 	}
 
- static Bigint *p5s;
-
  static Bigint *
 pow5mult
 #ifdef KR_headers
-	(b, k) Bigint *b; int k;
+	(STATE_PARAM b, k) STATE_PARAM_DECL Bigint *b; int k;
 #else
-	(Bigint *b, int k)
+	(STATE_PARAM Bigint *b, int k)
 #endif
 {
 	Bigint *b1, *p5, *p51;
 	int i;
-	static int p05[3] = { 5, 25, 125 };
+	static CONST int p05[3] = { 5, 25, 125 };
 
 	if ((i = k & 3))
-		b = multadd(b, p05[i-1], 0);
+		b = multadd(PASS_STATE b, p05[i-1], 0);
 
 	if (!(k >>= 2))
 		return b;
-	if (!(p5 = p5s)) {
+	if (!(p5 = GET_STATE(p5s))) {
 		/* first time */
 #ifdef MULTIPLE_THREADS
 		ACQUIRE_DTOA_LOCK(1);
 		if (!(p5 = p5s)) {
 			p5 = p5s = i2b(625);
 			p5->next = 0;
 			}
 		FREE_DTOA_LOCK(1);
 #else
-		p5 = p5s = i2b(625);
+		p5 = GET_STATE(p5s) = i2b(PASS_STATE 625);
 		p5->next = 0;
 #endif
 		}
 	for(;;) {
 		if (k & 1) {
-			b1 = mult(b, p5);
-			Bfree(b);
+			b1 = mult(PASS_STATE b, p5);
+			Bfree(PASS_STATE b);
 			b = b1;
 			}
 		if (!(k >>= 1))
 			break;
 		if (!(p51 = p5->next)) {
 #ifdef MULTIPLE_THREADS
 			ACQUIRE_DTOA_LOCK(1);
 			if (!(p51 = p5->next)) {
 				p51 = p5->next = mult(p5,p5);
 				p51->next = 0;
 				}
 			FREE_DTOA_LOCK(1);
 #else
-			p51 = p5->next = mult(p5,p5);
+			p51 = p5->next = mult(PASS_STATE p5,p5);
 			p51->next = 0;
 #endif
 			}
 		p5 = p51;
 		}
 	return b;
 	}
 
  static Bigint *
 lshift
 #ifdef KR_headers
-	(b, k) Bigint *b; int k;
+	(STATE_PARAM b, k) STATE_PARAM_DECL Bigint *b; int k;
 #else
-	(Bigint *b, int k)
+	(STATE_PARAM Bigint *b, int k)
 #endif
 {
 	int i, k1, n, n1;
 	Bigint *b1;
 	ULong *x, *x1, *xe, z;
 
 #ifdef Pack_32
 	n = k >> 5;
 #else
 	n = k >> 4;
 #endif
 	k1 = b->k;
 	n1 = n + b->wds + 1;
 	for(i = b->maxwds; n1 > i; i <<= 1)
 		k1++;
-	b1 = Balloc(k1);
+	b1 = Balloc(PASS_STATE k1);
 	x1 = b1->x;
 	for(i = 0; i < n; i++)
 		*x1++ = 0;
 	x = b->x;
 	xe = x + b->wds;
 #ifdef Pack_32
 	if (k &= 0x1f) {
 		k1 = 32 - k;
@@ -962,17 +1039,17 @@ lshift
 		if (*x1 = z)
 			++n1;
 		}
 #endif
 	else do
 		*x1++ = *x++;
 		while(x < xe);
 	b1->wds = n1 - 1;
-	Bfree(b);
+	Bfree(PASS_STATE b);
 	return b1;
 	}
 
  static int
 cmp
 #ifdef KR_headers
 	(a, b) Bigint *a, *b;
 #else
@@ -1003,49 +1080,49 @@ cmp
 			break;
 		}
 	return 0;
 	}
 
  static Bigint *
 diff
 #ifdef KR_headers
-	(a, b) Bigint *a, *b;
+	(STATE_PARAM a, b) STATE_PARAM_DECL Bigint *a, *b;
 #else
-	(Bigint *a, Bigint *b)
+	(STATE_PARAM Bigint *a, Bigint *b)
 #endif
 {
 	Bigint *c;
 	int i, wa, wb;
 	ULong *xa, *xae, *xb, *xbe, *xc;
 #ifdef ULLong
 	ULLong borrow, y;
 #else
 	ULong borrow, y;
 #ifdef Pack_32
 	ULong z;
 #endif
 #endif
 
 	i = cmp(a,b);
 	if (!i) {
-		c = Balloc(0);
+		c = Balloc(PASS_STATE 0);
 		c->wds = 1;
 		c->x[0] = 0;
 		return c;
 		}
 	if (i < 0) {
 		c = a;
 		a = b;
 		b = c;
 		i = 1;
 		}
 	else
 		i = 0;
-	c = Balloc(a->k);
+	c = Balloc(PASS_STATE a->k);
 	c->sign = i;
 	wa = a->wds;
 	xa = a->x;
 	xae = xa + wa;
 	wb = b->wds;
 	xb = b->x;
 	xbe = xb + wb;
 	xc = c->x;
@@ -1209,19 +1286,19 @@ b2d
 #undef d1
 #endif
 	return dval(d);
 	}
 
  static Bigint *
 d2b
 #ifdef KR_headers
-	(d, e, bits) U d; int *e, *bits;
+	(STATE_PARAM d, e, bits) STATE_PARAM_DECL U d; int *e, *bits;
 #else
-	(U d, int *e, int *bits)
+	(STATE_PARAM U d, int *e, int *bits)
 #endif
 {
 	Bigint *b;
 	int de, k;
 	ULong *x, y, z;
 #ifndef Sudden_Underflow
 	int i;
 #endif
@@ -1230,19 +1307,19 @@ d2b
 	d0 = word0(d) >> 16 | word0(d) << 16;
 	d1 = word1(d) >> 16 | word1(d) << 16;
 #else
 #define d0 word0(d)
 #define d1 word1(d)
 #endif
 
 #ifdef Pack_32
-	b = Balloc(1);
+	b = Balloc(PASS_STATE 1);
 #else
-	b = Balloc(2);
+	b = Balloc(PASS_STATE 2);
 #endif
 	x = b->x;
 
 	z = d0 & Frac_mask;
 	d0 &= 0x7fffffff;	/* clear sign bit, which we ignore */
 #ifdef Sudden_Underflow
 	de = (int)(d0 >> Exp_shift);
 #ifndef IBM
@@ -1524,19 +1601,19 @@ hexnan
 		}
 	}
 #endif /*No_Hex_NaN*/
 #endif /* INFNAN_CHECK */
 
  static double
 _strtod
 #ifdef KR_headers
-	(s00, se) CONST char *s00; char **se;
+	(STATE_PARAM s00, se) STATE_PARAM_DECL CONST char *s00; char **se;
 #else
-	(CONST char *s00, char **se)
+	(STATE_PARAM CONST char *s00, char **se)
 #endif
 {
 #ifdef Avoid_Underflow
 	int scale;
 #endif
 	int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
 		 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
 	CONST char *s, *s0, *s1;
@@ -1948,23 +2025,23 @@ hexnan
 #endif
 			}
 		}
 
 	/* Now the hard part -- adjusting rv to the correct value.*/
 
 	/* Put digits into bd: true value = bd * 10^e */
 
-	bd0 = s2b(s0, nd0, nd, y);
+	bd0 = s2b(PASS_STATE s0, nd0, nd, y);
 
 	for(;;) {
-		bd = Balloc(bd0->k);
+		bd = Balloc(PASS_STATE bd0->k);
 		Bcopy(bd, bd0);
-		bb = d2b(rv, &bbe, &bbbits);	/* rv = bb * 2^bbe */
-		bs = i2b(1);
+		bb = d2b(PASS_STATE rv, &bbe, &bbbits);	/* rv = bb * 2^bbe */
+		bs = i2b(PASS_STATE 1);
 
 		if (e >= 0) {
 			bb2 = bb5 = 0;
 			bd2 = bd5 = e;
 			}
 		else {
 			bb2 = bb5 = -e;
 			bd2 = bd5 = 0;
@@ -2010,30 +2087,30 @@ hexnan
 		if (i > bs2)
 			i = bs2;
 		if (i > 0) {
 			bb2 -= i;
 			bd2 -= i;
 			bs2 -= i;
 			}
 		if (bb5 > 0) {
-			bs = pow5mult(bs, bb5);
-			bb1 = mult(bs, bb);
-			Bfree(bb);
+			bs = pow5mult(PASS_STATE bs, bb5);
+			bb1 = mult(PASS_STATE bs, bb);
+			Bfree(PASS_STATE bb);
 			bb = bb1;
 			}
 		if (bb2 > 0)
-			bb = lshift(bb, bb2);
+			bb = lshift(PASS_STATE bb, bb2);
 		if (bd5 > 0)
-			bd = pow5mult(bd, bd5);
+			bd = pow5mult(PASS_STATE bd, bd5);
 		if (bd2 > 0)
-			bd = lshift(bd, bd2);
+			bd = lshift(PASS_STATE bd, bd2);
 		if (bs2 > 0)
-			bs = lshift(bs, bs2);
-		delta = diff(bb, bd);
+			bs = lshift(PASS_STATE bs, bs2);
+		delta = diff(PASS_STATE bb, bd);
 		dsign = delta->sign;
 		delta->sign = 0;
 		i = cmp(delta, bs);
 #ifdef Honor_FLT_ROUNDS
 		if (rounding != 1) {
 			if (i < 0) {
 				/* Error is less than an ulp */
 				if (!delta->x[0] && delta->wds <= 1) {
@@ -2055,17 +2132,17 @@ hexnan
 					 && !(word0(rv) & Frac_mask)) {
 						y = word0(rv) & Exp_mask;
 #ifdef Avoid_Underflow
 						if (!scale || y > 2*P*Exp_msk1)
 #else
 						if (y)
 #endif
 						  {
-						  delta = lshift(delta,Log2P);
+						  delta = lshift(PASS_STATE delta,Log2P);
 						  if (cmp(delta, bs) <= 0)
 							adj = -0.5;
 						  }
 						}
  apply_adj:
 #ifdef Avoid_Underflow
 					if (scale && (y = word0(rv) & Exp_mask)
 						<= 2*P*Exp_msk1)
@@ -2144,17 +2221,17 @@ hexnan
 				}
 			if (!delta->x[0] && delta->wds <= 1) {
 				/* exact result */
 #ifdef SET_INEXACT
 				inexact = 0;
 #endif
 				break;
 				}
-			delta = lshift(delta,Log2P);
+			delta = lshift(PASS_STATE delta,Log2P);
 			if (cmp(delta, bs) > 0)
 				goto drop_down;
 			break;
 			}
 		if (i == 0) {
 			/* exactly half-way between */
 			if (dsign) {
 				if ((word0(rv) & Bndry_mask1) == Bndry_mask1
@@ -2369,20 +2446,20 @@ hexnan
 				if (aadj < .4999999 || aadj > .5000001)
 					break;
 				}
 			else if (aadj < .4999999/FLT_RADIX)
 				break;
 			}
 #endif
  cont:
-		Bfree(bb);
-		Bfree(bd);
-		Bfree(bs);
-		Bfree(delta);
+		Bfree(PASS_STATE bb);
+		Bfree(PASS_STATE bd);
+		Bfree(PASS_STATE bs);
+		Bfree(PASS_STATE delta);
 		}
 #ifdef SET_INEXACT
 	if (inexact) {
 		if (!oldinexact) {
 			word0(rv0) = Exp_1 + (70 << Exp_shift);
 			word1(rv0) = 0;
 			dval(rv0) += 1.;
 			}
@@ -2405,21 +2482,21 @@ hexnan
 #ifdef SET_INEXACT
 	if (inexact && !(word0(rv) & Exp_mask)) {
 		/* set underflow bit */
 		dval(rv0) = 1e-300;
 		dval(rv0) *= dval(rv0);
 		}
 #endif
  retfree:
-	Bfree(bb);
-	Bfree(bd);
-	Bfree(bs);
-	Bfree(bd0);
-	Bfree(delta);
+	Bfree(PASS_STATE bb);
+	Bfree(PASS_STATE bd);
+	Bfree(PASS_STATE bs);
+	Bfree(PASS_STATE bd0);
+	Bfree(PASS_STATE delta);
  ret:
 	if (se)
 		*se = (char *)s;
 	return sign ? -dval(rv) : dval(rv);
 	}
 
  static int
 quorem
@@ -2534,76 +2611,77 @@ quorem
 			while(--bxe > bx && !*bxe)
 				--n;
 			b->wds = n;
 			}
 		}
 	return q;
 	}
 
-#ifndef MULTIPLE_THREADS
+#if !defined(MULTIPLE_THREADS) && !defined(NO_GLOBAL_STATE)
+#define USE_DTOA_RESULT 1
  static char *dtoa_result;
 #endif
 
  static char *
 #ifdef KR_headers
-rv_alloc(i) int i;
+rv_alloc(STATE_PARAM i) STATE_PARAM_DECL int i;
 #else
-rv_alloc(int i)
+rv_alloc(STATE_PARAM int i)
 #endif
 {
 	int j, k, *r;
 
 	j = sizeof(ULong);
 	for(k = 0;
 		sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= (unsigned) i;
 		j <<= 1)
 			k++;
-	r = (int*)Balloc(k);
+	r = (int*)Balloc(PASS_STATE k);
 	*r = k;
 	return
-#ifndef MULTIPLE_THREADS
+#ifdef USE_DTOA_RESULT
 	dtoa_result =
 #endif
 		(char *)(r+1);
 	}
 
  static char *
 #ifdef KR_headers
-nrv_alloc(s, rve, n) char *s, **rve; int n;
+nrv_alloc(STATE_PARAM s, rve, n) STATE_PARAM_DECL char *s, **rve; int n;
 #else
-nrv_alloc(CONST char *s, char **rve, int n)
+nrv_alloc(STATE_PARAM CONST char *s, char **rve, int n)
 #endif
 {
 	char *rv, *t;
 
-	t = rv = rv_alloc(n);
+	t = rv = rv_alloc(PASS_STATE n);
 	while((*t = *s++)) t++;
 	if (rve)
 		*rve = t;
 	return rv;
 	}
 
 /* freedtoa(s) must be used to free values s returned by dtoa
  * when MULTIPLE_THREADS is #defined.  It should be used in all cases,
  * but for consistency with earlier versions of dtoa, it is optional
  * when MULTIPLE_THREADS is not defined.
  */
 
  static void
 #ifdef KR_headers
-freedtoa(s) char *s;
+freedtoa(STATE_PARAM s) STATE_PARAM_DECL char *s;
 #else
-freedtoa(char *s)
+freedtoa(STATE_PARAM char *s)
 #endif
 {
 	Bigint *b = (Bigint *)((int *)s - 1);
 	b->maxwds = 1 << (b->k = *(int*)b);
-	Bfree(b);
-#ifndef MULTIPLE_THREADS
+	Bfree(PASS_STATE b);
+#ifdef USE_DTOA_RESULT
 	if (s == dtoa_result)
 		dtoa_result = 0;
 #endif
 	}
 
 /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
  *
  * Inspired by "How to Print Floating-Point Numbers Accurately" by
@@ -2636,20 +2714,20 @@ freedtoa(char *s)
  *	   "uniformly" distributed input, the probability is
  *	   something like 10^(k-15) that we must resort to the Long
  *	   calculation.
  */
 
  static char *
 dtoa
 #ifdef KR_headers
-	(d, mode, ndigits, decpt, sign, rve)
-	U d; int mode, ndigits, *decpt, *sign; char **rve;
+	(STATE_PARAM d, mode, ndigits, decpt, sign, rve)
+	STATE_PARAM_DECL U d; int mode, ndigits, *decpt, *sign; char **rve;
 #else
-	(U d, int mode, int ndigits, int *decpt, int *sign, char **rve)
+	(STATE_PARAM U d, int mode, int ndigits, int *decpt, int *sign, char **rve)
 #endif
 {
  /*	Arguments ndigits, decpt, sign are similar to those
 	of ecvt and fcvt; trailing zeros are suppressed from
 	the returned string.  If not null, *rve is set to point
 	to the end of the return value.  If d is +-Infinity or NaN,
 	then *decpt is set to 9999.
 
@@ -2700,19 +2778,19 @@ dtoa
 	int inexact, oldinexact;
 #endif
 
 #ifdef __GNUC__
 	ilim = ilim1 = 0;
 	mlo = NULL;
 #endif
 
-#ifndef MULTIPLE_THREADS
+#ifdef USE_DTOA_RESULT
 	if (dtoa_result) {
-		freedtoa(dtoa_result);
+		freedtoa(PASS_STATE dtoa_result);
 		dtoa_result = 0;
 		}
 #endif
 
 	if (word0(d) & Sign_bit) {
 		/* set sign for everything, including 0's and NaNs */
 		*sign = 1;
 		word0(d) &= ~Sign_bit;	/* clear sign bit */
@@ -2726,44 +2804,44 @@ dtoa
 #else
 	if (word0(d)  == 0x8000)
 #endif
 		{
 		/* Infinity or NaN */
 		*decpt = 9999;
 #ifdef IEEE_Arith
 		if (!word1(d) && !(word0(d) & 0xfffff))
-			return nrv_alloc("Infinity", rve, 8);
+			return nrv_alloc(PASS_STATE "Infinity", rve, 8);
 #endif
-		return nrv_alloc("NaN", rve, 3);
+		return nrv_alloc(PASS_STATE "NaN", rve, 3);
 		}
 #endif
 #ifdef IBM
 	dval(d) += 0; /* normalize */
 #endif
 	if (!dval(d)) {
 		*decpt = 1;
-		return nrv_alloc("0", rve, 1);
+		return nrv_alloc(PASS_STATE "0", rve, 1);
 		}
 
 #ifdef SET_INEXACT
 	try_quick = oldinexact = get_inexact();
 	inexact = 1;
 #endif
 #ifdef Honor_FLT_ROUNDS
 	if ((rounding = Flt_Rounds) >= 2) {
 		if (*sign)
 			rounding = rounding == 2 ? 0 : 2;
 		else
 			if (rounding != 2)
 				rounding = 0;
 		}
 #endif
 
-	b = d2b(d, &be, &bbits);
+	b = d2b(PASS_STATE d, &be, &bbits);
 #ifdef Sudden_Underflow
 	i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
 #else
 	if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) {
 #endif
 		dval(d2) = dval(d);
 		word0(d2) &= Frac_mask1;
 		word0(d2) |= Exp_11;
@@ -2879,17 +2957,17 @@ dtoa
 			/* no break */
 		case 5:
 			i = ndigits + k + 1;
 			ilim = i;
 			ilim1 = i - 1;
 			if (i <= 0)
 				i = 1;
 		}
-	s = s0 = rv_alloc(i);
+	s = s0 = rv_alloc(PASS_STATE i);
 
 #ifdef Honor_FLT_ROUNDS
 	if (mode > 1 && rounding != 1)
 		leftright = 0;
 #endif
 
 	if (ilim >= 0 && ilim <= Quick_max && try_quick) {
 
@@ -3056,41 +3134,41 @@ dtoa
 #endif
 #ifdef IBM
 			1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
 #else
 			1 + P - bbits;
 #endif
 		b2 += i;
 		s2 += i;
-		mhi = i2b(1);
+		mhi = i2b(PASS_STATE 1);
 		}
 	if (m2 > 0 && s2 > 0) {
 		i = m2 < s2 ? m2 : s2;
 		b2 -= i;
 		m2 -= i;
 		s2 -= i;
 		}
 	if (b5 > 0) {
 		if (leftright) {
 			if (m5 > 0) {
-				mhi = pow5mult(mhi, m5);
-				b1 = mult(mhi, b);
-				Bfree(b);
+				mhi = pow5mult(PASS_STATE mhi, m5);
+				b1 = mult(PASS_STATE mhi, b);
+				Bfree(PASS_STATE b);
 				b = b1;
 				}
 			if ((j = b5 - m5))
-				b = pow5mult(b, j);
+				b = pow5mult(PASS_STATE b, j);
 			}
 		else
-			b = pow5mult(b, b5);
+			b = pow5mult(PASS_STATE b, b5);
 		}
-	S = i2b(1);
+	S = i2b(PASS_STATE 1);
 	if (s5 > 0)
-		S = pow5mult(S, s5);
+		S = pow5mult(PASS_STATE S, s5);
 
 	/* Check for special case that d is a normalized power of 2. */
 
 	spec_case = 0;
 	if ((mode < 2 || leftright)
 #ifdef Honor_FLT_ROUNDS
 			&& rounding == 1
 #endif
@@ -3129,66 +3207,66 @@ dtoa
 		}
 	else if (i < 4) {
 		i += 28;
 		b2 += i;
 		m2 += i;
 		s2 += i;
 		}
 	if (b2 > 0)
-		b = lshift(b, b2);
+		b = lshift(PASS_STATE b, b2);
 	if (s2 > 0)
-		S = lshift(S, s2);
+		S = lshift(PASS_STATE S, s2);
 	if (k_check) {
 		if (cmp(b,S) < 0) {
 			k--;
-			b = multadd(b, 10, 0);	/* we botched the k estimate */
+			b = multadd(PASS_STATE b, 10, 0);	/* we botched the k estimate */
 			if (leftright)
-				mhi = multadd(mhi, 10, 0);
+				mhi = multadd(PASS_STATE mhi, 10, 0);
 			ilim = ilim1;
 			}
 		}
 	if (ilim <= 0 && (mode == 3 || mode == 5)) {
-		if (ilim < 0 || cmp(b,S = multadd(S,5,0)) < 0) {
+		if (ilim < 0 || cmp(b,S = multadd(PASS_STATE S,5,0)) < 0) {
 			/* no digits, fcvt style */
  no_digits:
 			/* MOZILLA CHANGE: Always return a non-empty string. */
 			*s++ = '0';
 			k = 0;
 			goto ret;
 			}
  one_digit:
 		*s++ = '1';
 		k++;
 		goto ret;
 		}
 	if (leftright) {
 		if (m2 > 0)
-			mhi = lshift(mhi, m2);
+			mhi = lshift(PASS_STATE mhi, m2);
 
 		/* Compute mlo -- check for special case
 		 * that d is a normalized power of 2.
 		 */
 
 		mlo = mhi;
 		if (spec_case) {
-			mhi = Balloc(mhi->k);
+			mhi = Balloc(PASS_STATE mhi->k);
 			Bcopy(mhi, mlo);
-			mhi = lshift(mhi, Log2P);
+			mhi = lshift(PASS_STATE mhi, Log2P);
 			}
 
 		for(i = 1;;i++) {
 			dig = quorem(b,S) + '0';
 			/* Do we yet have the shortest decimal string
 			 * that will round to d?
 			 */
 			j = cmp(b, mlo);
-			delta = diff(S, mhi);
+			delta = diff(PASS_STATE S, mhi);
 			j1 = delta->sign ? 1 : cmp(b, delta);
-			Bfree(delta);
+			Bfree(PASS_STATE delta);
 #ifndef ROUND_BIASED
 			if (j1 == 0 && mode != 1 && !(word1(d) & 1)
 #ifdef Honor_FLT_ROUNDS
 				&& rounding >= 1
 #endif
 								   ) {
 				if (dig == '9')
 					goto round_9_up;
@@ -3216,17 +3294,17 @@ dtoa
 #ifdef Honor_FLT_ROUNDS
 				if (mode > 1)
 				 switch(rounding) {
 				  case 0: goto accept_dig;
 				  case 2: goto keep_dig;
 				  }
 #endif /*Honor_FLT_ROUNDS*/
 				if (j1 > 0) {
-					b = lshift(b, 1);
+					b = lshift(PASS_STATE b, 1);
 					j1 = cmp(b, S);
 					if ((j1 > 0 || (j1 == 0 && dig & 1))
 					&& dig++ == '9')
 						goto round_9_up;
 					}
  accept_dig:
 				*s++ = dig;
 				goto ret;
@@ -3245,48 +3323,48 @@ dtoa
 				goto ret;
 				}
 #ifdef Honor_FLT_ROUNDS
  keep_dig:
 #endif
 			*s++ = dig;
 			if (i == ilim)
 				break;
-			b = multadd(b, 10, 0);
+			b = multadd(PASS_STATE b, 10, 0);
 			if (mlo == mhi)
-				mlo = mhi = multadd(mhi, 10, 0);
+				mlo = mhi = multadd(PASS_STATE mhi, 10, 0);
 			else {
-				mlo = multadd(mlo, 10, 0);
-				mhi = multadd(mhi, 10, 0);
+				mlo = multadd(PASS_STATE mlo, 10, 0);
+				mhi = multadd(PASS_STATE mhi, 10, 0);
 				}
 			}
 		}
 	else
 		for(i = 1;; i++) {
 			*s++ = dig = quorem(b,S) + '0';
 			if (!b->x[0] && b->wds <= 1) {
 #ifdef SET_INEXACT
 				inexact = 0;
 #endif
 				goto ret;
 				}
 			if (i >= ilim)
 				break;
-			b = multadd(b, 10, 0);
+			b = multadd(PASS_STATE b, 10, 0);
 			}
 
 	/* Round off last digit */
 
 #ifdef Honor_FLT_ROUNDS
 	switch(rounding) {
 	  case 0: goto trimzeros;
 	  case 2: goto roundoff;
 	  }
 #endif
-	b = lshift(b, 1);
+	b = lshift(PASS_STATE b, 1);
 	j = cmp(b, S);
 	if (j >= 0) {  /* ECMA compatible rounding needed by Spidermonkey */
  roundoff:
 		while(*--s == '9')
 			if (s == s0) {
 				k++;
 				*s++ = '1';
 				goto ret;
@@ -3296,35 +3374,35 @@ dtoa
 	else {
 #ifdef Honor_FLT_ROUNDS
  trimzeros:
 #endif
 		while(*--s == '0');
 		s++;
 		}
  ret:
-	Bfree(S);
+	Bfree(PASS_STATE S);
 	if (mhi) {
 		if (mlo && mlo != mhi)
-			Bfree(mlo);
-		Bfree(mhi);
+			Bfree(PASS_STATE mlo);
+		Bfree(PASS_STATE mhi);
 		}
  ret1:
 #ifdef SET_INEXACT
 	if (inexact) {
 		if (!oldinexact) {
 			word0(d) = Exp_1 + (70 << Exp_shift);
 			word1(d) = 0;
 			dval(d) += 1.;
 			}
 		}
 	else if (!oldinexact)
 		clear_inexact();
 #endif
-	Bfree(b);
+	Bfree(PASS_STATE b);
 	*s = 0;
 	*decpt = k + 1;
 	if (rve)
 		*rve = s;
 	return s0;
 	}
 #ifdef __cplusplus
 }
--- a/js/src/editline/editline.c
+++ b/js/src/editline/editline.c
@@ -164,17 +164,20 @@ STATIC CHAR	*editinput();
 /*
 **  TTY input/output functions.
 */
 
 STATIC void
 TTYflush()
 {
     if (ScreenCount) {
-	(void)write(1, Screen, ScreenCount);
+        /* Dummy assignment avoids GCC warning on
+         * "attribute warn_unused_result" */
+	ssize_t dummy = write(1, Screen, ScreenCount);
+        (void)dummy;
 	ScreenCount = 0;
     }
 }
 
 STATIC void
 TTYput(c)
     CHAR	c;
 {
new file mode 100644
--- /dev/null
+++ b/js/src/gnuplot/gcTimer.gnu
@@ -0,0 +1,25 @@
+# gnuplot script to visualize GCMETER results.
+# usage: "gnuplot gcTimer.pl >outputfile.png"
+
+set terminal png
+# set Title
+set title "Title goes here!"
+set datafile missing "-"
+set noxtics
+set ytics nomirror
+set ylabel "Cycles [1E6]"
+set y2tics nomirror
+set y2label "Chunk count"
+set key below
+set style data linespoints
+
+#set data file
+plot 'gcTimer.dat' using 2 title columnheader(2), \
+'' u 3 title columnheader(3), \
+'' u 4 title columnheader(4), \
+'' u 5 title columnheader(5) with points, \
+'' u 6 title columnheader(6) with points, \
+'' u 7 title columnheader(7) with points, \
+'' u 8 title columnheader(8) with points, \
+'' u 9 title columnheader(9) with points axis x1y2, \
+'' u 10 title columnheader(10) with points axis x1y2
--- a/js/src/js-config.h.in
+++ b/js/src/js-config.h.in
@@ -43,16 +43,19 @@
 
 /* Definitions set at build time that affect SpiderMonkey's public API.
    This header file is generated by the SpiderMonkey configure script,
    and installed along with jsapi.h.  */
 
 /* Define to 1 if SpiderMonkey should support multi-threaded clients.  */
 #undef JS_THREADSAFE
 
+/* Define to 1 if SpiderMonkey should include ctypes support.  */
+#undef JS_HAS_CTYPES
+
 /* Define to 1 if SpiderMonkey should support the ability to perform
    entirely too much GC.  */
 #undef JS_GC_ZEAL
 
 /* Define to 1 if the standard <stdint.h> header is present and
    useable.  See jstypes.h and jsstdint.h.  */
 #undef JS_HAVE_STDINT_H
 
--- a/js/src/jsapi-tests/Makefile.in
+++ b/js/src/jsapi-tests/Makefile.in
@@ -50,16 +50,17 @@ CPPSRCS = \
   selfTest.cpp \
   testContexts.cpp \
   testDebugger.cpp \
   testDefineGetterSetterNonEnumerable.cpp \
   testExtendedEq.cpp \
   testIntString.cpp \
   testIsAboutToBeFinalized.cpp \
   testLookup.cpp \
+  testNewObject.cpp \
   testPropCache.cpp \
   testTrap.cpp \
   testSameValue.cpp \
   testSeal.cpp \
   testXDR.cpp \
   testSetPropertyWithNativeGetterStubSetter.cpp \
   $(NULL)
 
--- a/js/src/jsapi-tests/testLookup.cpp
+++ b/js/src/jsapi-tests/testLookup.cpp
@@ -1,10 +1,10 @@
 #include "tests.h"
-#include "jsfun.h"  // for js_IsInternalFunctionObject
+#include "jsfun.h"  // for js::IsInternalFunctionObject
 
 BEGIN_TEST(testLookup_bug522590)
 {
     // Define a function that makes method-bearing objects.
     jsvalRoot x(cx);
     EXEC("function mkobj() { return {f: function () {return 2;}} }");
 
     // Calling mkobj() multiple times must create multiple functions in ES5.
@@ -15,15 +15,15 @@ BEGIN_TEST(testLookup_bug522590)
     EVAL("mkobj()", x.addr());
     JSObject *xobj = JSVAL_TO_OBJECT(x);
 
     // This lookup must not return an internal function object.
     jsvalRoot r(cx);
     CHECK(JS_LookupProperty(cx, xobj, "f", r.addr()));
     CHECK(JSVAL_IS_OBJECT(r));
     JSObject *funobj = JSVAL_TO_OBJECT(r);
-    CHECK(HAS_FUNCTION_CLASS(funobj));
-    CHECK(!js_IsInternalFunctionObject(funobj));
+    CHECK(funobj->isFunction());
+    CHECK(!js::IsInternalFunctionObject(funobj));
     CHECK(GET_FUNCTION_PRIVATE(cx, funobj) != (JSFunction *) funobj);
 
     return true;
 }
 END_TEST(testLookup_bug522590)
new file mode 100644
--- /dev/null
+++ b/js/src/jsapi-tests/testNewObject.cpp
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=4 sw=4 et tw=99:
+ */
+
+#include "tests.h"
+
+const size_t N = 1000;
+static jsval argv[N];
+
+static JSBool
+constructHook(JSContext *cx, JSObject *thisobj, uintN argc, jsval *argv, jsval *rval)
+{
+    // Check that arguments were passed properly from JS_New.
+    JSObject *callee = JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv));
+    if (!thisobj) {
+        JS_ReportError(cx, "test failed, null 'this'");
+        return false;
+    }
+    if (strcmp(JS_GET_CLASS(cx, thisobj)->name, "Object") != 0) {
+        JS_ReportError(cx, "test failed, wrong class for 'this'");
+        return false;
+    }
+    if (argc != 3) {
+        JS_ReportError(cx, "test failed, argc == %d", argc);
+        return false;
+    }
+    if (!JSVAL_IS_INT(argv[2]) || JSVAL_TO_INT(argv[2]) != 2) {
+        JS_ReportError(cx, "test failed, wrong value in argv[2]");
+        return false;
+    }
+    if (!JS_IsConstructing(cx)) {
+        JS_ReportError(cx, "test failed, not constructing");
+        return false;
+    }
+
+    // Perform a side-effect to indicate that this hook was actually called.
+    if (!JS_SetElement(cx, callee, 0, &argv[0]))
+        return false;
+
+    *rval = OBJECT_TO_JSVAL(callee); // return the callee, perversely
+    argv[0] = argv[1] = argv[2] = JSVAL_VOID;  // trash the argv, perversely
+    return true;
+}
+
+BEGIN_TEST(testNewObject_1)
+{
+    jsval v;
+    EVAL("Array", &v);
+    JSObject *Array = JSVAL_TO_OBJECT(v);
+
+    // With no arguments.
+    JSObject *obj = JS_New(cx, Array, 0, NULL);
+    CHECK(obj);
+    jsvalRoot rt(cx, OBJECT_TO_JSVAL(obj));
+    CHECK(JS_IsArrayObject(cx, obj));
+    jsuint len;
+    CHECK(JS_GetArrayLength(cx, obj, &len));
+    CHECK(len == 0);
+
+    // With one argument.
+    argv[0] = INT_TO_JSVAL(4);
+    obj = JS_New(cx, Array, 1, argv);
+    CHECK(obj);
+    rt = OBJECT_TO_JSVAL(obj);
+    CHECK(JS_IsArrayObject(cx, obj));
+    CHECK(JS_GetArrayLength(cx, obj, &len));
+    CHECK(len == 4);
+
+    // With N arguments.
+    JS_ASSERT(INT_FITS_IN_JSVAL(N));
+    for (size_t i = 0; i < N; i++)
+        argv[i] = INT_TO_JSVAL(i);
+    obj = JS_New(cx, Array, N, argv);
+    CHECK(obj);
+    rt = OBJECT_TO_JSVAL(obj);
+    CHECK(JS_IsArrayObject(cx, obj));
+    CHECK(JS_GetArrayLength(cx, obj, &len));
+    CHECK(len == N);
+    CHECK(JS_GetElement(cx, obj, N - 1, &v));
+    CHECK_SAME(v, INT_TO_JSVAL(N - 1));
+
+    // With JSClass.construct.
+    static JSClass cls = {
+        "testNewObject_1",
+        0,
+        JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+        JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL,
+        NULL, NULL, NULL, constructHook, NULL, NULL, NULL, NULL
+    };
+    JSObject *ctor = JS_NewObject(cx, &cls, NULL, NULL);
+    CHECK(ctor);
+    jsvalRoot rt2(cx, OBJECT_TO_JSVAL(ctor));
+    obj = JS_New(cx, ctor, 3, argv);
+    CHECK(obj);
+    CHECK(obj == ctor);  // constructHook returns ctor, perversely
+    CHECK(JS_GetElement(cx, ctor, 0, &v));
+    CHECK_SAME(v, JSVAL_ZERO);
+    CHECK_SAME(argv[0], JSVAL_ZERO);  // original argv should not have been trashed
+    CHECK_SAME(argv[1], JSVAL_ONE);
+    return true;
+}
+END_TEST(testNewObject_1)
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -433,63 +433,63 @@ JS_ValueToSource(JSContext *cx, jsval v)
     return js_ValueToSource(cx, v);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp)
 {
     CHECK_REQUEST(cx);
 
-    JSAutoTempValueRooter tvr(cx, v);
+    AutoValueRooter tvr(cx, v);
     *dp = js_ValueToNumber(cx, tvr.addr());
     return !JSVAL_IS_NULL(tvr.value());
 }
 
 JS_PUBLIC_API(JSBool)
 JS_DoubleIsInt32(jsdouble d, jsint *ip)
 {
     return JSDOUBLE_IS_INT(d, *ip);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip)
 {
     CHECK_REQUEST(cx);
 
-    JSAutoTempValueRooter tvr(cx, v);
+    AutoValueRooter tvr(cx, v);
     *ip = js_ValueToECMAInt32(cx, tvr.addr());
     return !JSVAL_IS_NULL(tvr.value());
 }
 
 JS_PUBLIC_API(JSBool)
 JS_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip)
 {
     CHECK_REQUEST(cx);
 
-    JSAutoTempValueRooter tvr(cx, v);
+    AutoValueRooter tvr(cx, v);
     *ip = js_ValueToECMAUint32(cx, tvr.addr());
     return !JSVAL_IS_NULL(tvr.value());
 }
 
 JS_PUBLIC_API(JSBool)
 JS_ValueToInt32(JSContext *cx, jsval v, int32 *ip)
 {
     CHECK_REQUEST(cx);
 
-    JSAutoTempValueRooter tvr(cx, v);
+    AutoValueRooter tvr(cx, v);
     *ip = js_ValueToInt32(cx, tvr.addr());
     return !JSVAL_IS_NULL(tvr.value());
 }
 
 JS_PUBLIC_API(JSBool)
 JS_ValueToUint16(JSContext *cx, jsval v, uint16 *ip)
 {
     CHECK_REQUEST(cx);
 
-    JSAutoTempValueRooter tvr(cx, v);
+    AutoValueRooter tvr(cx, v);
     *ip = js_ValueToUint16(cx, tvr.addr());
     return !JSVAL_IS_NULL(tvr.value());
 }
 
 JS_PUBLIC_API(JSBool)
 JS_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp)
 {
     CHECK_REQUEST(cx);
@@ -558,22 +558,23 @@ JSRuntime::JSRuntime()
     JS_INIT_CLIST(&contextList);
     JS_INIT_CLIST(&trapList);
     JS_INIT_CLIST(&watchPointList);
 }
 
 bool
 JSRuntime::init(uint32 maxbytes)
 {
-    if (!js_InitDtoa() ||
-        !js_InitGC(this, maxbytes) ||
-        !js_InitAtomState(this) ||
-        !js_InitDeflatedStringCache(this)) {
+    if (!js_InitGC(this, maxbytes) || !js_InitAtomState(this))
         return false;
-    }
+
+    deflatedStringCache = new js::DeflatedStringCache();
+    if (!deflatedStringCache || !deflatedStringCache->init())
+        return false;
+
 #ifdef JS_THREADSAFE
     gcLock = JS_NEW_LOCK();
     if (!gcLock)
         return false;
     gcDone = JS_NEW_CONDVAR(gcLock);
     if (!gcDone)
         return false;
     requestDone = JS_NEW_CONDVAR(gcLock);
@@ -594,17 +595,17 @@ JSRuntime::init(uint32 maxbytes)
     titleSharingTodo = NO_TITLE_SHARING_TODO;
     debuggerLock = JS_NEW_LOCK();
     if (!debuggerLock)
         return false;
     deallocatorThread = new JSBackgroundThread();
     if (!deallocatorThread || !deallocatorThread->init())
         return false;
 #endif
-    return js_InitPropertyTree(this) && js_InitThreads(this);
+    return propertyTree.init() && js_InitThreads(this);
 }
 
 JSRuntime::~JSRuntime()
 {
 #ifdef DEBUG
     /* Don't hurt everyone in leaky ol' Mozilla with a fatal JS_ASSERT! */
     if (!JS_CLIST_IS_EMPTY(&contextList)) {
         JSContext *cx, *iter = NULL;
@@ -624,17 +625,17 @@ JSRuntime::~JSRuntime()
     js_FinishThreads(this);
     js_FreeRuntimeScriptState(this);
     js_FinishAtomState(this);
 
     /*
      * Finish the deflated string cache after the last GC and after
      * calling js_FinishAtomState, which finalizes strings.
      */
-    js_FinishDeflatedStringCache(this);
+    delete deflatedStringCache;
     js_FinishGC(this);
 #ifdef JS_THREADSAFE
     if (gcLock)
         JS_DESTROY_LOCK(gcLock);
     if (gcDone)
         JS_DESTROY_CONDVAR(gcDone);
     if (requestDone)
         JS_DESTROY_CONDVAR(requestDone);
@@ -646,17 +647,17 @@ JSRuntime::~JSRuntime()
         JS_DESTROY_CONDVAR(titleSharingDone);
     if (debuggerLock)
         JS_DESTROY_LOCK(debuggerLock);
     if (deallocatorThread) {
         deallocatorThread->cancel();
         delete deallocatorThread;
     }
 #endif
-    js_FinishPropertyTree(this);
+    propertyTree.finish();
 }
 
 
 JS_PUBLIC_API(JSRuntime *)
 JS_NewRuntime(uint32 maxbytes)
 {
 #ifdef DEBUG
     if (!js_NewRuntimeWasCalled) {
@@ -748,17 +749,16 @@ JS_ShutDown(void)
     extern void js_DumpOpMeters();
     js_DumpOpMeters();
 #endif
 
 #ifdef JS_REPRMETER
     reprmeter::js_DumpReprMeter();
 #endif
 
-    js_FinishDtoa();
 #ifdef JS_THREADSAFE
     js_CleanupLocks();
 #endif
     PRMJ_NowShutdown();
 }
 
 JS_PUBLIC_API(void *)
 JS_GetRuntimePrivate(JSRuntime *rt)
@@ -870,16 +870,36 @@ JS_ResumeRequest(JSContext *cx, jsrefcou
     while (--saveDepth >= 0) {
         JS_BeginRequest(cx);
         cx->outstandingRequests--;  /* compensate for JS_BeginRequest */
     }
 #endif
 }
 
 JS_PUBLIC_API(void)
+JS_TransferRequest(JSContext *cx, JSContext *another)
+{
+    JS_ASSERT(cx != another);
+    JS_ASSERT(cx->runtime == another->runtime);
+#ifdef JS_THREADSAFE
+    JS_ASSERT(cx->thread);
+    JS_ASSERT(another->thread);
+    JS_ASSERT(cx->thread == another->thread);
+    JS_ASSERT(cx->requestDepth != 0);
+    JS_ASSERT(another->requestDepth == 0);
+
+    /* Serialize access to JSContext::requestDepth from other threads. */
+    JS_LOCK_GC(cx->runtime);
+    another->requestDepth = cx->requestDepth;
+    cx->requestDepth = 0;
+    JS_UNLOCK_GC(cx->runtime);
+#endif
+}
+
+JS_PUBLIC_API(void)
 JS_Lock(JSRuntime *rt)
 {
     JS_LOCK_RUNTIME(rt);
 }
 
 JS_PUBLIC_API(void)
 JS_Unlock(JSRuntime *rt)
 {
@@ -1338,17 +1358,16 @@ static JSStdName standard_class_names[] 
 
     {NULL,                      0, NULL, NULL}
 };
 
 static JSStdName object_prototype_names[] = {
     /* Object.prototype properties (global delegates to Object.prototype). */
     {js_InitObjectClass,        EAGER_ATOM(proto), NULL},
     {js_InitObjectClass,        EAGER_ATOM(parent), NULL},
-    {js_InitObjectClass,        EAGER_ATOM(count), NULL},
 #if JS_HAS_TOSOURCE
     {js_InitObjectClass,        EAGER_ATOM(toSource), NULL},
 #endif
     {js_InitObjectClass,        EAGER_ATOM(toString), NULL},
     {js_InitObjectClass,        EAGER_ATOM(toLocaleString), NULL},
     {js_InitObjectClass,        EAGER_ATOM(valueOf), NULL},
 #if JS_HAS_OBJ_WATCHPOINT
     {js_InitObjectClass,        LAZY_ATOM(watch), NULL},
@@ -1661,25 +1680,23 @@ JS_GetScopeChain(JSContext *cx)
         return obj;
     }
     return js_GetScopeChain(cx, fp);
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_GetGlobalForObject(JSContext *cx, JSObject *obj)
 {
-   while (JSObject *parent = obj->getParent())
-        obj = parent;
-    return obj;
+    return obj->getGlobal();
 }
 
 JS_PUBLIC_API(jsval)
 JS_ComputeThis(JSContext *cx, jsval *vp)
 {
-    if (!js_ComputeThis(cx, JS_FALSE, vp + 2))
+    if (!js_ComputeThis(cx, vp + 2))
         return JSVAL_NULL;
     return vp[1];
 }
 
 JS_PUBLIC_API(void *)
 JS_malloc(JSContext *cx, size_t nbytes)
 {
     return cx->malloc(nbytes);
@@ -1899,17 +1916,17 @@ JS_PrintTraceThingInfo(char *buf, size_t
 
     if (bufsize == 0)
         return;
 
     switch (kind) {
       case JSTRACE_OBJECT:
       {
         JSObject *obj = (JSObject *)thing;
-        JSClass *clasp = STOBJ_GET_CLASS(obj);
+        JSClass *clasp = obj->getClass();
 
         name = clasp->name;
 #ifdef HAVE_XPCONNECT
         if (clasp->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS) {
             void *privateThing = obj->getPrivate();
             if (privateThing) {
                 const char *xpcClassName = GetXPCObjectClassName(privateThing);
                 if (xpcClassName)
@@ -1951,17 +1968,17 @@ JS_PrintTraceThingInfo(char *buf, size_t
     if (details && bufsize > 2) {
         *buf++ = ' ';
         bufsize--;
 
         switch (kind) {
           case JSTRACE_OBJECT:
           {
             JSObject  *obj = (JSObject *)thing;
-            JSClass *clasp = STOBJ_GET_CLASS(obj);
+            JSClass *clasp = obj->getClass();
             if (clasp == &js_FunctionClass) {
                 JSFunction *fun = GET_FUNCTION_PRIVATE(trc->context, obj);
                 if (!fun) {
                     JS_snprintf(buf, bufsize, "<newborn>");
                 } else if (FUN_OBJECT(fun) != obj) {
                     JS_snprintf(buf, bufsize, "%p", fun);
                 } else {
                     if (fun->atom && ATOM_IS_STRING(fun->atom))
@@ -2748,17 +2765,17 @@ JS_SealObject(JSContext *cx, JSObject *o
     JSScope *scope;
     JSIdArray *ida;
     uint32 nslots, i;
     jsval v;
 
     if (obj->isDenseArray() && !js_MakeArraySlow(cx, obj))
         return JS_FALSE;
 
-    if (!OBJ_IS_NATIVE(obj)) {
+    if (!obj->isNative()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                              JSMSG_CANT_SEAL_OBJECT,
                              OBJ_GET_CLASS(cx, obj)->name);
         return JS_FALSE;
     }
 
     scope = OBJ_SCOPE(obj);
 
@@ -2780,32 +2797,30 @@ JS_SealObject(JSContext *cx, JSObject *o
     ida = JS_Enumerate(cx, obj);
     if (!ida)
         return JS_FALSE;
     JS_DestroyIdArray(cx, ida);
 
     /* Ensure that obj has its own, mutable scope, and seal that scope. */
     JS_LOCK_OBJ(cx, obj);
     scope = js_GetMutableScope(cx, obj);
-    if (scope) {
-        scope->sealingShapeChange(cx);
-        scope->setSealed();
-    }
+    if (scope)
+        scope->seal(cx);
     JS_UNLOCK_OBJ(cx, obj);
     if (!scope)
         return JS_FALSE;
 
     /* If we are not sealing an entire object graph, we're done. */
     if (!deep)
         return JS_TRUE;
 
     /* Walk slots in obj and if any value is a non-null object, seal it. */
     nslots = scope->freeslot;
     for (i = 0; i != nslots; ++i) {
-        v = STOBJ_GET_SLOT(obj, i);
+        v = obj->getSlot(i);
         if (i == JSSLOT_PRIVATE && (obj->getClass()->flags & JSCLASS_HAS_PRIVATE))
             continue;
         if (JSVAL_IS_PRIMITIVE(v))
             continue;
         if (!JS_SealObject(cx, JSVAL_TO_OBJECT(v), deep))
             return JS_FALSE;
     }
     return JS_TRUE;
@@ -2831,34 +2846,34 @@ JS_ConstructObjectWithArguments(JSContex
     return js_ConstructObject(cx, clasp, proto, parent, argc, argv);
 }
 
 static JSBool
 DefinePropertyById(JSContext *cx, JSObject *obj, jsid id, jsval value,
                    JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
                    uintN flags, intN tinyid)
 {
-    if (flags != 0 && OBJ_IS_NATIVE(obj)) {
+    if (flags != 0 && obj->isNative()) {
         JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_DECLARING);
         return !!js_DefineNativeProperty(cx, obj, id, value, getter, setter,
                                          attrs, flags, tinyid, NULL);
     }
     return obj->defineProperty(cx, id, value, getter, setter, attrs);
 }
 
 static JSBool
 DefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value,
                JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
                uintN flags, intN tinyid)
 {
     jsid id;
     JSAtom *atom;
 
     if (attrs & JSPROP_INDEX) {
-        id = INT_TO_JSID(JS_PTR_TO_INT32(name));
+        id = INT_TO_JSID(intptr_t(name));
         atom = NULL;
         attrs &= ~JSPROP_INDEX;
     } else {
         atom = js_Atomize(cx, name, strlen(name), 0);
         if (!atom)
             return JS_FALSE;
         id = ATOM_TO_JSID(atom);
     }
@@ -2874,17 +2889,17 @@ DefineUCProperty(JSContext *cx, JSObject
                  JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
                  uintN flags, intN tinyid)
 {
     JSAtom *atom;
 
     atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
     if (!atom)
         return JS_FALSE;
-    if (flags != 0 && OBJ_IS_NATIVE(obj)) {
+    if (flags != 0 && obj->isNative()) {
         JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_DECLARING);
         return !!js_DefineNativeProperty(cx, obj, ATOM_TO_JSID(atom), value,
                                          getter, setter, attrs, flags, tinyid,
                                          NULL);
     }
     return obj->defineProperty(cx, ATOM_TO_JSID(atom), value, getter, setter, attrs);
 }
 
@@ -2967,16 +2982,23 @@ JS_DefinePropertyWithTinyId(JSContext *c
                             JSPropertyOp getter, JSPropertyOp setter,
                             uintN attrs)
 {
     CHECK_REQUEST(cx);
     return DefineProperty(cx, obj, name, value, getter, setter, attrs,
                           JSScopeProperty::HAS_SHORTID, tinyid);
 }
 
+JS_PUBLIC_API(JSBool)
+JS_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id, jsval descriptor, JSBool *bp)
+{
+    CHECK_REQUEST(cx);
+    return js_DefineOwnProperty(cx, obj, id, descriptor, bp);
+}
+
 static JSBool
 LookupPropertyById(JSContext *cx, JSObject *obj, jsid id, uintN flags,
                    JSObject **objp, JSProperty **propp)
 {
     JSAutoResolveFlags rf(cx, flags);
     id = js_CheckForStringIndex(id);
     return obj->lookupProperty(cx, id, objp, propp);
 }
@@ -3018,30 +3040,30 @@ JS_AliasProperty(JSContext *cx, JSObject
 
     CHECK_REQUEST(cx);
     if (!LookupProperty(cx, obj, name, JSRESOLVE_QUALIFIED, &obj2, &prop))
         return JS_FALSE;
     if (!prop) {
         js_ReportIsNotDefined(cx, name);
         return JS_FALSE;
     }
-    if (obj2 != obj || !OBJ_IS_NATIVE(obj)) {
+    if (obj2 != obj || !obj->isNative()) {
         obj2->dropProperty(cx, prop);
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_ALIAS,
                              alias, name, OBJ_GET_CLASS(cx, obj2)->name);
         return JS_FALSE;
     }
     atom = js_Atomize(cx, alias, strlen(alias), 0);
     if (!atom) {
         ok = JS_FALSE;
     } else {
         sprop = (JSScopeProperty *)prop;
         ok = (js_AddNativeProperty(cx, obj, ATOM_TO_JSID(atom),
                                    sprop->getter(), sprop->setter(), sprop->slot,
-                                   sprop->attrs, sprop->getFlags() | JSScopeProperty::ALIAS,
+                                   sprop->attributes(), sprop->getFlags() | JSScopeProperty::ALIAS,
                                    sprop->shortid)
               != NULL);
     }
     obj->dropProperty(cx, prop);
     return ok;
 }
 
 static JSBool
@@ -3050,21 +3072,21 @@ LookupResult(JSContext *cx, JSObject *ob
 {
     if (!prop) {
         /* XXX bad API: no way to tell "not defined" from "void value" */
         *vp = JSVAL_VOID;
         return JS_TRUE;
     }
 
     JSBool ok = JS_TRUE;
-    if (OBJ_IS_NATIVE(obj2)) {
+    if (obj2->isNative()) {
         JSScopeProperty *sprop = (JSScopeProperty *) prop;
 
         if (sprop->isMethod()) {
-            JSAutoTempValueRooter root(cx, sprop);
+            AutoScopePropertyRooter root(cx, sprop);
             JS_UNLOCK_OBJ(cx, obj2);
             *vp = sprop->methodValue();
             return OBJ_SCOPE(obj2)->methodReadBarrier(cx, sprop, vp);
         }
 
         /* Peek at the native property's slot value, without doing a Get. */
         *vp = SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj2))
                ? LOCKED_OBJ_GET_SLOT(obj2, sprop->slot)
@@ -3100,17 +3122,17 @@ GetPropertyAttributesById(JSContext *cx,
             obj2->dropProperty(cx, prop);
         return JS_TRUE;
     }
 
     desc->obj = obj2;
 
     ok = obj2->getAttributes(cx, id, prop, &desc->attrs);
     if (ok) {
-        if (OBJ_IS_NATIVE(obj2)) {
+        if (obj2->isNative()) {
             JSScopeProperty *sprop = (JSScopeProperty *) prop;
 
             desc->getter = sprop->getter();
             desc->setter = sprop->setter();
             desc->value = SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj2))
                           ? LOCKED_OBJ_GET_SLOT(obj2, sprop->slot)
                           : JSVAL_VOID;
         } else {
@@ -3230,17 +3252,17 @@ JS_SetPropertyAttributes(JSContext *cx, 
 }
 
 static JSBool
 AlreadyHasOwnPropertyHelper(JSContext *cx, JSObject *obj, jsid id,
                             JSBool *foundp)
 {
     JSScope *scope;
 
-    if (!OBJ_IS_NATIVE(obj)) {
+    if (!obj->isNative()) {
         JSObject *obj2;
         JSProperty *prop;
 
         if (!LookupPropertyById(cx, obj, id,
                                 JSRESOLVE_QUALIFIED | JSRESOLVE_DETECTING,
                                 &obj2, &prop)) {
             return JS_FALSE;
         }
@@ -3354,17 +3376,17 @@ JS_LookupPropertyWithFlags(JSContext *cx
 JS_PUBLIC_API(JSBool)
 JS_LookupPropertyWithFlagsById(JSContext *cx, JSObject *obj, jsid id,
                                uintN flags, JSObject **objp, jsval *vp)
 {
     JSBool ok;
     JSProperty *prop;
 
     CHECK_REQUEST(cx);
-    ok = OBJ_IS_NATIVE(obj)
+    ok = obj->isNative()
          ? js_LookupPropertyWithFlags(cx, obj, id, flags, objp, &prop) >= 0
          : obj->lookupProperty(cx, id, objp, &prop);
     if (ok)
         ok = LookupResult(cx, obj, *objp, prop, vp);
     return ok;
 }
 
 JS_PUBLIC_API(JSBool)
@@ -3372,16 +3394,23 @@ JS_GetPropertyDescriptorById(JSContext *
                              JSPropertyDescriptor *desc)
 {
     CHECK_REQUEST(cx);
 
     return GetPropertyAttributesById(cx, obj, id, flags, JS_FALSE, desc);
 }
 
 JS_PUBLIC_API(JSBool)
+JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+{
+    CHECK_REQUEST(cx);
+    return js_GetOwnPropertyDescriptor(cx, obj, id, vp);
+}
+
+JS_PUBLIC_API(JSBool)
 JS_GetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
 {
     JSAtom *atom;
 
     CHECK_REQUEST(cx);
     atom = js_Atomize(cx, name, strlen(name), 0);
     if (!atom)
         return JS_FALSE;
@@ -3693,28 +3722,28 @@ JS_AliasElement(JSContext *cx, JSObject 
 
     CHECK_REQUEST(cx);
     if (!LookupProperty(cx, obj, name, JSRESOLVE_QUALIFIED, &obj2, &prop))
         return JS_FALSE;
     if (!prop) {
         js_ReportIsNotDefined(cx, name);
         return JS_FALSE;
     }
-    if (obj2 != obj || !OBJ_IS_NATIVE(obj)) {
+    if (obj2 != obj || !obj->isNative()) {
         char numBuf[12];
         obj2->dropProperty(cx, prop);
         JS_snprintf(numBuf, sizeof numBuf, "%ld", (long)alias);
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_ALIAS,
                              numBuf, name, OBJ_GET_CLASS(cx, obj2)->name);
         return JS_FALSE;
     }
     sprop = (JSScopeProperty *)prop;
     ok = (js_AddNativeProperty(cx, obj, INT_TO_JSID(alias),
                                sprop->getter(), sprop->setter(), sprop->slot,
-                               sprop->attrs, sprop->getFlags() | JSScopeProperty::ALIAS,
+                               sprop->attributes(), sprop->getFlags() | JSScopeProperty::ALIAS,
                                sprop->shortid)
           != NULL);
     obj->dropProperty(cx, prop);
     return ok;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_AlreadyHasOwnElement(JSContext *cx, JSObject *obj, jsint index,
@@ -3805,29 +3834,28 @@ JS_ClearScope(JSContext *cx, JSObject *o
             JS_SetReservedSlot(cx, obj, key, JSVAL_VOID);
     }
 }
 
 JS_PUBLIC_API(JSIdArray *)
 JS_Enumerate(JSContext *cx, JSObject *obj)
 {
     jsint i, n;
-    jsval iter_state, num_properties;
     jsid id;
     JSIdArray *ida;
     jsval *vector;
 
     CHECK_REQUEST(cx);
 
     ida = NULL;
-    iter_state = JSVAL_NULL;
-    JSAutoEnumStateRooter tvr(cx, obj, &iter_state);
+    AutoEnumStateRooter iterState(cx, obj);
 
     /* Get the number of properties to enumerate. */
-    if (!obj->enumerate(cx, JSENUMERATE_INIT, &iter_state, &num_properties))
+    jsval num_properties;
+    if (!obj->enumerate(cx, JSENUMERATE_INIT, iterState.addr(), &num_properties))
         goto error;
     if (!JSVAL_IS_INT(num_properties)) {
         JS_ASSERT(0);
         goto error;
     }
 
     /* Grow as needed if we don't know the exact amount ahead of time. */
     n = JSVAL_TO_INT(num_properties);
@@ -3837,36 +3865,34 @@ JS_Enumerate(JSContext *cx, JSObject *ob
     /* Create an array of jsids large enough to hold all the properties */
     ida = NewIdArray(cx, n);
     if (!ida)
         goto error;
 
     i = 0;
     vector = &ida->vector[0];
     for (;;) {
-        if (!obj->enumerate(cx, JSENUMERATE_NEXT, &iter_state, &id))
+        if (!obj->enumerate(cx, JSENUMERATE_NEXT, iterState.addr(), &id))
             goto error;
 
         /* No more jsid's to enumerate ? */
-        if (iter_state == JSVAL_NULL)
+        if (iterState.state() == JSVAL_NULL)
             break;
 
         if (i == ida->length) {
             ida = SetIdArrayLength(cx, ida, ida->length * 2);
             if (!ida)
                 goto error;
             vector = &ida->vector[0];
         }
         vector[i++] = id;
     }
     return SetIdArrayLength(cx, ida, i);
 
 error:
-    if (!JSVAL_IS_NULL(iter_state))
-        obj->enumerate(cx, JSENUMERATE_DESTROY, &iter_state, 0);
     if (ida)
         JS_DestroyIdArray(cx, ida);
     return NULL;
 }
 
 /*
  * XXX reverse iterator for properties, unreverse and meld with jsinterp.c's
  *     prop_iterator_class somehow...
@@ -3928,29 +3954,29 @@ JS_NewPropertyIterator(JSContext *cx, JS
     jsint index;
     JSIdArray *ida;
 
     CHECK_REQUEST(cx);
     iterobj = js_NewObject(cx, &prop_iter_class, NULL, obj);
     if (!iterobj)
         return NULL;
 
-    if (OBJ_IS_NATIVE(obj)) {
+    if (obj->isNative()) {
         /* Native case: start with the last property in obj's own scope. */
         scope = OBJ_SCOPE(obj);
         pdata = scope->lastProperty();
         index = -1;
     } else {
         /*
          * Non-native case: enumerate a JSIdArray and keep it via private.
          *
          * Note: we have to make sure that we root obj around the call to
          * JS_Enumerate to protect against multiple allocations under it.
          */
-        JSAutoTempValueRooter tvr(cx, iterobj);
+        AutoValueRooter tvr(cx, iterobj);
         ida = JS_Enumerate(cx, obj);
         if (!ida)
             return NULL;
         pdata = ida;
         index = ida->length;
     }
 
     /* iterobj cannot escape to other threads here. */
@@ -3968,17 +3994,17 @@ JS_NextProperty(JSContext *cx, JSObject 
     JSScopeProperty *sprop;
     JSIdArray *ida;
 
     CHECK_REQUEST(cx);
     i = JSVAL_TO_INT(iterobj->fslots[JSSLOT_ITER_INDEX]);
     if (i < 0) {
         /* Native case: private data is a property tree node pointer. */
         obj = iterobj->getParent();
-        JS_ASSERT(OBJ_IS_NATIVE(obj));
+        JS_ASSERT(obj->isNative());
         scope = OBJ_SCOPE(obj);
         sprop = (JSScopeProperty *) iterobj->getPrivate();
 
         /*
          * If the next property mapped by scope in the property tree ancestor
          * line is not enumerable, or it's an alias, skip it and keep on trying
          * to find an enumerable property that is still in scope.
          */
@@ -3994,17 +4020,17 @@ JS_NextProperty(JSContext *cx, JSObject 
     } else {
         /* Non-native case: use the ida enumerated when iterobj was created. */
         ida = (JSIdArray *) iterobj->getPrivate();
         JS_ASSERT(i <= ida->length);
         if (i == 0) {
             *idp = JSVAL_VOID;
         } else {
             *idp = ida->vector[--i];
-            STOBJ_SET_SLOT(iterobj, JSSLOT_ITER_INDEX, INT_TO_JSVAL(i));
+            iterobj->setSlot(JSSLOT_ITER_INDEX, INT_TO_JSVAL(i));
         }
     }
     return JS_TRUE;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
                jsval *vp, uintN *attrsp)
@@ -4252,17 +4278,17 @@ js_generic_fast_native_method_dispatcher
      * passed as |this|.
      */
     memmove(vp + 1, vp + 2, argc * sizeof(jsval));
 
     /*
      * Follow Function.prototype.apply and .call by using the global object as
      * the 'this' param if no args.
      */
-    if (!js_ComputeThis(cx, JS_FALSE, vp + 2))
+    if (!js_ComputeThis(cx, vp + 2))
         return JS_FALSE;
     /*
      * Protect against argc underflowing. By calling js_ComputeThis, we made
      * it as if the static was called with one parameter, the explicit |this|
      * object.
      */
     if (argc != 0) {
         /* Clear the last parameter in case too few arguments were passed. */
@@ -4316,17 +4342,17 @@ js_generic_native_method_dispatcher(JSCo
      * first argument passed as |this|.
      */
     memmove(argv - 1, argv, argc * sizeof(jsval));
 
     /*
      * Follow Function.prototype.apply and .call by using the global object as
      * the 'this' param if no args.
      */
-    if (!js_ComputeThis(cx, JS_TRUE, argv))
+    if (!js_ComputeThis(cx, argv))
         return JS_FALSE;
     js_GetTopStackFrame(cx)->thisv = argv[-1];
     JS_ASSERT(cx->fp->argv == argv);
 
     /*
      * Protect against argc underflowing. By calling js_ComputeThis, we made
      * it as if the static was called with one parameter, the explicit |this|
      * object.
@@ -4408,16 +4434,17 @@ JS_DefineFunction(JSContext *cx, JSObjec
 
 JS_PUBLIC_API(JSFunction *)
 JS_DefineUCFunction(JSContext *cx, JSObject *obj,
                     const jschar *name, size_t namelen, JSNative call,
                     uintN nargs, uintN attrs)
 {
     JSAtom *atom;
 
+    CHECK_REQUEST(cx);
     atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
     if (!atom)
         return NULL;
     return js_DefineFunction(cx, obj, atom, call, nargs, attrs);
 }
 
 JS_PUBLIC_API(JSScript *)
 JS_CompileScript(JSContext *cx, JSObject *obj,
@@ -4590,35 +4617,37 @@ JS_CompileFileHandleForPrincipals(JSCont
                                        NULL, 0, file, filename, 1);
     LAST_FRAME_CHECKS(cx, script);
     return script;
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_NewScriptObject(JSContext *cx, JSScript *script)
 {
-    JSTempValueRooter tvr;
     JSObject *obj;
 
     CHECK_REQUEST(cx);
     if (!script)
         return js_NewObject(cx, &js_ScriptClass, NULL, NULL);
 
     JS_ASSERT(!script->u.object);
 
-    JS_PUSH_TEMP_ROOT_SCRIPT(cx, script, &tvr);
-    obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL);
-    if (obj) {
-        obj->setPrivate(script);
-        script->u.object = obj;
+    {
+        AutoScriptRooter root(cx, script);
+
+        obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL);
+        if (obj) {
+            obj->setPrivate(script);
+            script->u.object = obj;
 #ifdef CHECK_SCRIPT_OWNER
-        script->owner = NULL;
+            script->owner = NULL;
 #endif
+        }
     }
-    JS_POP_TEMP_ROOT(cx, &tvr);
+
     return obj;
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_GetScriptObject(JSScript *script)
 {
     return script->u.object;
 }
@@ -4686,17 +4715,16 @@ JS_CompileUCFunction(JSContext *cx, JSOb
 JS_PUBLIC_API(JSFunction *)
 JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
                                   JSPrincipals *principals, const char *name,
                                   uintN nargs, const char **argnames,
                                   const jschar *chars, size_t length,
                                   const char *filename, uintN lineno)
 {
     JSFunction *fun;
-    JSTempValueRooter tvr;
     JSAtom *funAtom, *argAtom;
     uintN i;
 
     CHECK_REQUEST(cx);
     if (!name) {
         funAtom = NULL;
     } else {
         funAtom = js_Atomize(cx, name, strlen(name), 0);
@@ -4704,57 +4732,58 @@ JS_CompileUCFunctionForPrincipals(JSCont
             fun = NULL;
             goto out2;
         }
     }
     fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, obj, funAtom);
     if (!fun)
         goto out2;
 
-    MUST_FLOW_THROUGH("out");
-    JS_PUSH_TEMP_ROOT_OBJECT(cx, FUN_OBJECT(fun), &tvr);
-    for (i = 0; i < nargs; i++) {
-        argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i]), 0);
-        if (!argAtom) {
-            fun = NULL;
-            goto out;
+    {
+        AutoValueRooter tvr(cx, FUN_OBJECT(fun));
+        MUST_FLOW_THROUGH("out");
+
+        for (i = 0; i < nargs; i++) {
+            argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i]), 0);
+            if (!argAtom) {
+                fun = NULL;
+                goto out;
+            }
+            if (!js_AddLocal(cx, fun, argAtom, JSLOCAL_ARG)) {
+                fun = NULL;
+                goto out;
+            }
         }
-        if (!js_AddLocal(cx, fun, argAtom, JSLOCAL_ARG)) {
+
+        if (!JSCompiler::compileFunctionBody(cx, fun, principals,
+                                             chars, length, filename, lineno)) {
             fun = NULL;
             goto out;
         }
-    }
-
-    if (!JSCompiler::compileFunctionBody(cx, fun, principals,
-                                         chars, length, filename, lineno)) {
-        fun = NULL;
-        goto out;
-    }
-
-    if (obj &&
-        funAtom &&
-        !obj->defineProperty(cx, ATOM_TO_JSID(funAtom), OBJECT_TO_JSVAL(FUN_OBJECT(fun)),
-                             NULL, NULL, JSPROP_ENUMERATE)) {
-        fun = NULL;
-    }
+
+        if (obj && funAtom &&
+            !obj->defineProperty(cx, ATOM_TO_JSID(funAtom), OBJECT_TO_JSVAL(FUN_OBJECT(fun)),
+                                 NULL, NULL, JSPROP_ENUMERATE)) {
+            fun = NULL;
+        }
 
 #ifdef JS_SCOPE_DEPTH_METER
-    if (fun && obj) {
-        JSObject *pobj = obj;
-        uintN depth = 1;
-
-        while ((pobj = pobj->getParent()) != NULL)
-            ++depth;
-        JS_BASIC_STATS_ACCUM(&cx->runtime->hostenvScopeDepthStats, depth);
+        if (fun && obj) {
+            JSObject *pobj = obj;
+            uintN depth = 1;
+
+            while ((pobj = pobj->getParent()) != NULL)
+                ++depth;
+            JS_BASIC_STATS_ACCUM(&cx->runtime->hostenvScopeDepthStats, depth);
+        }
+#endif
+
+      out:
+        cx->weakRoots.finalizableNewborns[FINALIZE_FUNCTION] = fun;
     }
-#endif
-
-  out:
-    cx->weakRoots.finalizableNewborns[FINALIZE_FUNCTION] = fun;
-    JS_POP_TEMP_ROOT(cx, &tvr);
 
   out2:
     LAST_FRAME_CHECKS(cx, fun);
     return fun;
 }
 
 JS_PUBLIC_API(JSString *)
 JS_DecompileScript(JSContext *cx, JSScript *script, const char *name,
@@ -4804,46 +4833,16 @@ JS_ExecuteScript(JSContext *cx, JSObject
     JSBool ok;
 
     CHECK_REQUEST(cx);
     ok = js_Execute(cx, obj, script, NULL, 0, rval);
     LAST_FRAME_CHECKS(cx, ok);
     return ok;
 }
 
-JS_PUBLIC_API(JSBool)
-JS_ExecuteScriptPart(JSContext *cx, JSObject *obj, JSScript *script,
-                     JSExecPart part, jsval *rval)
-{
-    JSScript tmp;
-    JSBool ok;
-
-    /* Make a temporary copy of the JSScript structure and farble it a bit. */
-    tmp = *script;
-    if (part == JSEXEC_PROLOG) {
-        tmp.length = tmp.main - tmp.code;
-    } else {
-        tmp.length -= tmp.main - tmp.code;
-        tmp.code = tmp.main;
-    }
-
-    /* Tell the debugger about our temporary copy of the script structure. */
-    const JSDebugHooks *hooks = cx->debugHooks;
-    if (hooks->newScriptHook) {
-        hooks->newScriptHook(cx, tmp.filename, tmp.lineno, &tmp, NULL,
-                             hooks->newScriptHookData);
-    }
-
-    /* Execute the farbled struct and tell the debugger to forget about it. */
-    ok = JS_ExecuteScript(cx, obj, &tmp, rval);
-    if (hooks->destroyScriptHook)
-        hooks->destroyScriptHook(cx, &tmp, hooks->destroyScriptHookData);
-    return ok;
-}
-
 /* Ancient uintN nbytes is part of API/ABI, so use size_t length local. */
 JS_PUBLIC_API(JSBool)
 JS_EvaluateScript(JSContext *cx, JSObject *obj,
                   const char *bytes, uintN nbytes,
                   const char *filename, uintN lineno,
                   jsval *rval)
 {
     size_t length = nbytes;
@@ -4932,17 +4931,17 @@ JS_CallFunction(JSContext *cx, JSObject 
 }
 
 JS_PUBLIC_API(JSBool)
 JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, uintN argc,
                     jsval *argv, jsval *rval)
 {
     CHECK_REQUEST(cx);
 
-    JSAutoTempValueRooter tvr(cx);
+    AutoValueRooter tvr(cx);
     JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
     JSBool ok = atom &&
                 js_GetMethod(cx, obj, ATOM_TO_JSID(atom),
                              JSGET_NO_METHOD_BARRIER, tvr.addr()) &&
                 js_InternalCall(cx, obj, tvr.value(), argc, argv, rval);
     LAST_FRAME_CHECKS(cx, ok);
     return ok;
 }
@@ -4954,16 +4953,41 @@ JS_CallFunctionValue(JSContext *cx, JSOb
     JSBool ok;
 
     CHECK_REQUEST(cx);
     ok = js_InternalCall(cx, obj, fval, argc, argv, rval);
     LAST_FRAME_CHECKS(cx, ok);
     return ok;
 }
 
+JS_PUBLIC_API(JSObject *)
+JS_New(JSContext *cx, JSObject *ctor, uintN argc, jsval *argv)
+{
+    CHECK_REQUEST(cx);
+
+    // This is not a simple variation of JS_CallFunctionValue because JSOP_NEW
+    // is not a simple variation of JSOP_CALL. We have to determine what class
+    // of object to create, create it, and clamp the return value to an object,
+    // among other details. js_InvokeConstructor does the hard work.
+    void *mark;
+    jsval *vp = js_AllocStack(cx, 2 + argc, &mark);
+    if (!vp)
+        return NULL;
+    vp[0] = OBJECT_TO_JSVAL(ctor);
+    vp[1] = JSVAL_NULL;
+    memcpy(vp + 2, argv, argc * sizeof(jsval));
+
+    JSBool ok = js_InvokeConstructor(cx, argc, JS_TRUE, vp);
+    JSObject *obj = ok ? JSVAL_TO_OBJECT(vp[0]) : NULL;
+
+    js_FreeStack(cx, mark);
+    LAST_FRAME_CHECKS(cx, ok);
+    return obj;
+}
+
 JS_PUBLIC_API(JSOperationCallback)
 JS_SetOperationCallback(JSContext *cx, JSOperationCallback callback)
 {
 #ifdef JS_THREADSAFE
     JS_ASSERT(CURRENT_THREAD_IS_ME(cx->thread));
 #endif
     JSOperationCallback old = cx->operationCallback;
     cx->operationCallback = callback;
@@ -5059,17 +5083,17 @@ JS_NewString(JSContext *cx, char *bytes,
     /* Free chars (but not bytes, which caller frees on error) if we fail. */
     str = js_NewString(cx, chars, length);
     if (!str) {
         cx->free(chars);
         return NULL;
     }
 
     /* Hand off bytes to the deflated string cache, if possible. */
-    if (!js_SetStringBytes(cx, str, bytes, nbytes))
+    if (!cx->runtime->deflatedStringCache->setBytes(cx, str, bytes))
         cx->free(bytes);
     return str;
 }
 
 JS_PUBLIC_API(JSString *)
 JS_NewStringCopyN(JSContext *cx, const char *s, size_t n)
 {
     jschar *js;
@@ -5188,17 +5212,17 @@ JS_GetStringChars(JSString *str)
      */
     if (str->isDependent()) {
         n = str->dependentLength();
         size = (n + 1) * sizeof(jschar);
         s = (jschar *) js_malloc(size);
         if (s) {
             memcpy(s, str->dependentChars(), n * sizeof *s);
             s[n] = 0;
-            str->reinitFlat(s, n);
+            str->initFlat(s, n);
         } else {
             s = str->dependentChars();
         }
     } else {
         str->flatClearMutable();
         s = str->flatChars();
     }
     return s;
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1,9 +1,9 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sw=4 et tw=78:
  *
  * ***** 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
@@ -556,16 +556,19 @@ extern JS_PUBLIC_API(void)
 JS_YieldRequest(JSContext *cx);
 
 extern JS_PUBLIC_API(jsrefcount)
 JS_SuspendRequest(JSContext *cx);
 
 extern JS_PUBLIC_API(void)
 JS_ResumeRequest(JSContext *cx, jsrefcount saveDepth);
 
+extern JS_PUBLIC_API(void)
+JS_TransferRequest(JSContext *cx, JSContext *another);
+
 #ifdef __cplusplus
 JS_END_EXTERN_C
 
 class JSAutoRequest {
   public:
     JSAutoRequest(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM)
         : mContext(cx), mSaveDepth(0) {
         JS_GUARD_OBJECT_NOTIFIER_INIT;
@@ -621,16 +624,37 @@ class JSAutoSuspendRequest {
 
 #if 0
   private:
     static void *operator new(size_t) CPP_THROW_NEW { return 0; };
     static void operator delete(void *, size_t) { };
 #endif
 };
 
+class JSAutoTransferRequest
+{
+  public:
+    JSAutoTransferRequest(JSContext* cx1, JSContext* cx2)
+        : cx1(cx1), cx2(cx2) {
+        if(cx1 != cx2)
+            JS_TransferRequest(cx1, cx2);
+    }
+    ~JSAutoTransferRequest() {
+        if(cx1 != cx2)
+            JS_TransferRequest(cx2, cx1);
+    }
+  private:
+    JSContext* const cx1;
+    JSContext* const cx2;
+
+    /* Not copyable. */
+    JSAutoTransferRequest(JSAutoTransferRequest &);
+    void operator =(JSAutoTransferRequest&);
+};
+
 JS_BEGIN_EXTERN_C
 #endif
 
 extern JS_PUBLIC_API(void)
 JS_Lock(JSRuntime *rt);
 
 extern JS_PUBLIC_API(void)
 JS_Unlock(JSRuntime *rt);
@@ -794,16 +818,25 @@ JS_GetClassObject(JSContext *cx, JSObjec
                   JSObject **objp);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_GetScopeChain(JSContext *cx);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_GetGlobalForObject(JSContext *cx, JSObject *obj);
 
+#ifdef JS_HAS_CTYPES
+/*
+ * Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes'
+ * object will be sealed.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_InitCTypesClass(JSContext *cx, JSObject *global);
+#endif
+
 /*
  * Macros to hide interpreter stack layout details from a JSFastNative using
  * its jsval *vp parameter. The stack layout underlying invocation can't change
  * without breaking source and binary compatibility (argv[-2] is well-known to
  * be the callee jsval, and argv[-1] is as well known to be |this|).
  *
  * Note well: However, argv[-1] may be JSVAL_NULL where with slow natives it
  * is the global object, so embeddings implementing fast natives *must* call
@@ -1677,16 +1710,19 @@ extern JS_PUBLIC_API(JSObject *)
 JS_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
                    JSObject *parent);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_ConstructObjectWithArguments(JSContext *cx, JSClass *clasp, JSObject *proto,
                                 JSObject *parent, uintN argc, jsval *argv);
 
 extern JS_PUBLIC_API(JSObject *)
+JS_New(JSContext *cx, JSObject *ctor, uintN argc, jsval *argv);
+
+extern JS_PUBLIC_API(JSObject *)
 JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, JSClass *clasp,
                 JSObject *proto, uintN attrs);
 
 extern JS_PUBLIC_API(JSBool)
 JS_DefineConstDoubles(JSContext *cx, JSObject *obj, JSConstDoubleSpec *cds);
 
 extern JS_PUBLIC_API(JSBool)
 JS_DefineProperties(JSContext *cx, JSObject *obj, JSPropertySpec *ps);
@@ -1694,16 +1730,19 @@ JS_DefineProperties(JSContext *cx, JSObj
 extern JS_PUBLIC_API(JSBool)
 JS_DefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value,
                   JSPropertyOp getter, JSPropertyOp setter, uintN attrs);
 
 extern JS_PUBLIC_API(JSBool)
 JS_DefinePropertyById(JSContext *cx, JSObject *obj, jsid id, jsval value,
                       JSPropertyOp getter, JSPropertyOp setter, uintN attrs);
 
+extern JS_PUBLIC_API(JSBool)
+JS_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id, jsval descriptor, JSBool *bp);
+
 /*
  * Determine the attributes (JSPROP_* flags) of a property on a given object.
  *
  * If the object does not have a property by that name, *foundp will be
  * JS_FALSE and the value of *attrsp is undefined.
  */
 extern JS_PUBLIC_API(JSBool)
 JS_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
@@ -1789,16 +1828,19 @@ struct JSPropertyDescriptor {
  * an object on the prototype chain (returned in objp). If data->obj is null,
  * then this property was not found on the prototype chain.
  */
 extern JS_PUBLIC_API(JSBool)
 JS_GetPropertyDescriptorById(JSContext *cx, JSObject *obj, jsid id, uintN flags,
                              JSPropertyDescriptor *desc);
 
 extern JS_PUBLIC_API(JSBool)
+JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
+
+extern JS_PUBLIC_API(JSBool)
 JS_GetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp);
 
 extern JS_PUBLIC_API(JSBool)
 JS_GetPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
 
 extern JS_PUBLIC_API(JSBool)
 JS_GetMethodById(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
                  jsval *vp);
@@ -2223,20 +2265,20 @@ JS_DecompileScript(JSContext *cx, JSScri
 
 extern JS_PUBLIC_API(JSString *)
 JS_DecompileFunction(JSContext *cx, JSFunction *fun, uintN indent);
 
 extern JS_PUBLIC_API(JSString *)
 JS_DecompileFunctionBody(JSContext *cx, JSFunction *fun, uintN indent);
 
 /*
- * NB: JS_ExecuteScript, JS_ExecuteScriptPart, and the JS_Evaluate*Script*
- * quadruplets all use the obj parameter as the initial scope chain header,
- * the 'this' keyword value, and the variables object (ECMA parlance for where
- * 'var' and 'function' bind names) of the execution context for script.
+ * NB: JS_ExecuteScript and the JS_Evaluate*Script* quadruplets use the obj
+ * parameter as the initial scope chain header, the 'this' keyword value, and
+ * the variables object (ECMA parlance for where 'var' and 'function' bind
+ * names) of the execution context for script.
  *
  * Using obj as the variables object is problematic if obj's parent (which is
  * the scope chain link; see JS_SetParent and JS_NewObject) is not null: in
  * this case, variables created by 'var x = 0', e.g., go in obj, but variables
  * created by assignment to an unbound id, 'x = 0', go in the last object on
  * the scope chain linked by parent.
  *
  * ECMA calls that last scoping object the "global object", but note that many
@@ -2267,20 +2309,16 @@ JS_ExecuteScript(JSContext *cx, JSObject
 
 /*
  * Execute either the function-defining prolog of a script, or the script's
  * main body, but not both.
  */
 typedef enum JSExecPart { JSEXEC_PROLOG, JSEXEC_MAIN } JSExecPart;
 
 extern JS_PUBLIC_API(JSBool)
-JS_ExecuteScriptPart(JSContext *cx, JSObject *obj, JSScript *script,
-                     JSExecPart part, jsval *rval);
-
-extern JS_PUBLIC_API(JSBool)
 JS_EvaluateScript(JSContext *cx, JSObject *obj,
                   const char *bytes, uintN length,
                   const char *filename, uintN lineno,
                   jsval *rval);
 
 extern JS_PUBLIC_API(JSBool)
 JS_EvaluateScriptForPrincipals(JSContext *cx, JSObject *obj,
                                JSPrincipals *principals,
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -223,26 +223,31 @@ ValueIsLength(JSContext *cx, jsval* vp)
     return 0;
 }
 
 JSBool
 js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
 {
     if (obj->isArray()) {
         *lengthp = obj->fslots[JSSLOT_ARRAY_LENGTH];
-        return JS_TRUE;
+        return true;
     }
 
-    JSAutoTempValueRooter tvr(cx, JSVAL_NULL);
+    if (obj->isArguments() && !IsOverriddenArgsLength(obj)) {
+        *lengthp = GetArgsLength(obj);
+        return true;
+    }
+
+    AutoValueRooter tvr(cx, JSVAL_NULL);
     if (!obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom), tvr.addr()))
-        return JS_FALSE;
+        return false;
 
     if (JSVAL_IS_INT(tvr.value())) {
         *lengthp = jsuint(jsint(JSVAL_TO_INT(tvr.value()))); /* jsuint cast does ToUint32 */
-        return JS_TRUE;
+        return true;
     }
 
     *lengthp = js_ValueToECMAUint32(cx, tvr.addr());
     return !JSVAL_IS_NULL(tvr.value());
 }
 
 static JSBool
 IndexToValue(JSContext *cx, jsdouble index, jsval *vp)
@@ -400,17 +405,17 @@ EnsureCapacity(JSContext *cx, JSObject *
         }
     }
     return JS_TRUE;
 }
 
 static bool
 ReallyBigIndexToId(JSContext* cx, jsdouble index, jsid* idp)
 {
-    JSAutoTempValueRooter dval(cx);
+    AutoValueRooter dval(cx);
     if (!js_NewDoubleInRootedValue(cx, index, dval.addr()) ||
         !js_ValueToStringId(cx, dval.value(), idp)) {
         return JS_FALSE;
     }
     return JS_TRUE;
 }
 
 static bool
@@ -445,17 +450,17 @@ GetArrayElement(JSContext *cx, JSObject 
 {
     JS_ASSERT(index >= 0);
     if (obj->isDenseArray() && index < js_DenseArrayCapacity(obj) &&
         (*vp = obj->dslots[jsuint(index)]) != JSVAL_HOLE) {
         *hole = JS_FALSE;
         return JS_TRUE;
     }
 
-    JSAutoTempIdRooter idr(cx);
+    AutoIdRooter idr(cx);
 
     *hole = JS_FALSE;
     if (!IndexToId(cx, obj, index, hole, idr.addr()))
         return JS_FALSE;
     if (*hole) {
         *vp = JSVAL_VOID;
         return JS_TRUE;
     }
@@ -500,17 +505,17 @@ SetArrayElement(JSContext *cx, JSObject 
                 return JS_TRUE;
             }
         }
 
         if (!js_MakeArraySlow(cx, obj))
             return JS_FALSE;
     }
 
-    JSAutoTempIdRooter idr(cx);
+    AutoIdRooter idr(cx);
 
     if (!IndexToId(cx, obj, index, NULL, idr.addr(), JS_TRUE))
         return JS_FALSE;
     JS_ASSERT(!JSVAL_IS_VOID(idr.id()));
 
     return obj->setProperty(cx, idr.id(), &v);
 }
 
@@ -526,17 +531,17 @@ DeleteArrayElement(JSContext *cx, JSObje
                     obj->fslots[JSSLOT_ARRAY_COUNT]--;
                 obj->dslots[idx] = JSVAL_HOLE;
                 return JS_TRUE;
             }
         }
         return JS_TRUE;
     }
 
-    JSAutoTempIdRooter idr(cx);
+    AutoIdRooter idr(cx);
 
     if (!IndexToId(cx, obj, index, NULL, idr.addr()))
         return JS_FALSE;
     if (JSVAL_IS_VOID(idr.id()))
         return JS_TRUE;
 
     jsval junk;
     return obj->deleteProperty(cx, idr.id(), &junk);
@@ -568,35 +573,33 @@ js_SetLengthProperty(JSContext *cx, JSOb
     id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
     return obj->setProperty(cx, id, &v);
 }
 
 JSBool
 js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
 {
     JSErrorReporter older = JS_SetErrorReporter(cx, NULL);
-    JSAutoTempValueRooter tvr(cx, JSVAL_NULL);
+    AutoValueRooter tvr(cx, JSVAL_NULL);
     jsid id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
     JSBool ok = obj->getProperty(cx, id, tvr.addr());
     JS_SetErrorReporter(cx, older);
     if (!ok)
         return false;
 
     *lengthp = ValueIsLength(cx, tvr.addr());
     return !JSVAL_IS_NULL(tvr.value());
 }
 
 JSBool
 js_IsArrayLike(JSContext *cx, JSObject *obj, JSBool *answerp, jsuint *lengthp)
 {
-    JSClass *clasp;
-
-    clasp = OBJ_GET_CLASS(cx, js_GetWrappedObject(cx, obj));
-    *answerp = (clasp == &js_ArgumentsClass || clasp == &js_ArrayClass ||
-                clasp == &js_SlowArrayClass);
+    JSObject *wrappedObj = js_GetWrappedObject(cx, obj);
+
+    *answerp = wrappedObj->isArguments() || wrappedObj->isArray();
     if (!*answerp) {
         *lengthp = 0;
         return JS_TRUE;
     }
     return js_GetLengthProperty(cx, obj, lengthp);
 }
 
 /*
@@ -621,90 +624,80 @@ array_length_getter(JSContext *cx, JSObj
     return JS_TRUE;
 }
 
 static JSBool
 array_length_setter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
 {
     jsuint newlen, oldlen, gap, index;
     jsval junk;
-    JSObject *iter;
-    JSTempValueRooter tvr;
-    JSBool ok;
 
     if (!obj->isArray()) {
         jsid lengthId = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
 
         return obj->defineProperty(cx, lengthId, *vp, NULL, NULL, JSPROP_ENUMERATE);
     }
 
     newlen = ValueIsLength(cx, vp);
     if (JSVAL_IS_NULL(*vp))
-        return JS_FALSE;
+        return false;
     oldlen = obj->fslots[JSSLOT_ARRAY_LENGTH];
 
     if (oldlen == newlen)
-        return JS_TRUE;
+        return true;
 
     if (!IndexToValue(cx, newlen, vp))
-        return JS_FALSE;
+        return false;
 
     if (oldlen < newlen) {
         obj->fslots[JSSLOT_ARRAY_LENGTH] = newlen;
-        return JS_TRUE;
+        return true;
     }
 
     if (obj->isDenseArray()) {
         /* Don't reallocate if we're not actually shrinking our slots. */
         jsuint capacity = js_DenseArrayCapacity(obj);
         if (capacity > newlen && !ResizeSlots(cx, obj, capacity, newlen))
-            return JS_FALSE;
+            return false;
     } else if (oldlen - newlen < (1 << 24)) {
         do {
             --oldlen;
-            if (!JS_CHECK_OPERATION_LIMIT(cx) ||
-                !DeleteArrayElement(cx, obj, oldlen)) {
-                return JS_FALSE;
-            }
+            if (!JS_CHECK_OPERATION_LIMIT(cx) || !DeleteArrayElement(cx, obj, oldlen))
+                return false;
         } while (oldlen != newlen);
     } else {
         /*
          * We are going to remove a lot of indexes in a presumably sparse
          * array. So instead of looping through indexes between newlen and
          * oldlen, we iterate through all properties and remove those that
          * correspond to indexes in the half-open range [newlen, oldlen).  See
          * bug 322135.
          */
-        iter = JS_NewPropertyIterator(cx, obj);
+        JSObject *iter = JS_NewPropertyIterator(cx, obj);
         if (!iter)
-            return JS_FALSE;
+            return false;
 
         /* Protect iter against GC under JSObject::deleteProperty. */
-        JS_PUSH_TEMP_ROOT_OBJECT(cx, iter, &tvr);
+        AutoValueRooter tvr(cx, iter);
+
         gap = oldlen - newlen;
         for (;;) {
-            ok = (JS_CHECK_OPERATION_LIMIT(cx) &&
-                  JS_NextProperty(cx, iter, &id));
-            if (!ok)
-                break;
+            if (!JS_CHECK_OPERATION_LIMIT(cx) || !JS_NextProperty(cx, iter, &id))
+                return false;
             if (JSVAL_IS_VOID(id))
                 break;
-            if (js_IdIsIndex(id, &index) && index - newlen < gap) {
-                ok = obj->deleteProperty(cx, id, &junk);
-                if (!ok)
-                    break;
+            if (js_IdIsIndex(id, &index) && index - newlen < gap &&
+                !obj->deleteProperty(cx, id, &junk)) {
+                return false;
             }
         }
-        JS_POP_TEMP_ROOT(cx, &tvr);
-        if (!ok)
-            return JS_FALSE;
     }
 
     obj->fslots[JSSLOT_ARRAY_LENGTH] = newlen;
-    return JS_TRUE;
+    return true;
 }
 
 /*
  * We have only indexed properties up to capacity (excepting holes), plus the
  * length property. For all else, we delegate to the prototype.
  */
 static inline bool
 IsDenseArrayId(JSContext *cx, JSObject *obj, jsid id)
@@ -792,17 +785,17 @@ array_getProperty(JSContext *cx, JSObjec
         }
 
         *vp = JSVAL_VOID;
         if (js_LookupPropertyWithFlags(cx, proto, id, cx->resolveFlags,
                                        &obj2, &prop) < 0)
             return JS_FALSE;
 
         if (prop) {
-            if (OBJ_IS_NATIVE(obj2)) {
+            if (obj2->isNative()) {
                 sprop = (JSScopeProperty *) prop;
                 if (!js_NativeGet(cx, obj, obj2, sprop, JSGET_METHOD_BARRIER, vp))
                     return JS_FALSE;
             }
             obj2->dropProperty(cx, prop);
         }
         return JS_TRUE;
     }
@@ -891,17 +884,17 @@ js_PrototypeHasIndexedProperties(JSConte
      * element on the original object.
      */
     while ((obj = obj->getProto()) != NULL) {
         /*
          * If the prototype is a non-native object (possibly a dense array), or
          * a native object (possibly a slow array) that has indexed properties,
          * return true.
          */
-        if (!OBJ_IS_NATIVE(obj))
+        if (!obj->isNative())
             return JS_TRUE;
         if (OBJ_SCOPE(obj)->hadIndexedProperties())
             return JS_TRUE;
     }
     return JS_FALSE;
 }
 
 #ifdef JS_TRACER
@@ -1314,20 +1307,20 @@ js_MakeArraySlow(JSContext *cx, JSObject
     }
     JSScope *scope = JSScope::create(cx, &js_SlowArrayObjectOps, &js_SlowArrayClass, obj,
                                      emptyShape);
     if (!scope)
         return JS_FALSE;
 
     uint32 capacity = js_DenseArrayCapacity(obj);
     if (capacity) {
-        scope->freeslot = STOBJ_NSLOTS(obj) + JS_INITIAL_NSLOTS;
+        scope->freeslot = obj->numSlots() + JS_INITIAL_NSLOTS;
         obj->dslots[-1] = JS_INITIAL_NSLOTS + capacity;
     } else {
-        scope->freeslot = STOBJ_NSLOTS(obj);
+        scope->freeslot = obj->numSlots();
     }
 
     /* Create new properties pointing to existing values in dslots */
     for (uint32 i = 0; i < capacity; i++) {
         jsid id;
         JSScopeProperty *sprop;
 
         if (!JS_ValueToId(cx, INT_TO_JSVAL(i), &id))
@@ -1340,31 +1333,24 @@ js_MakeArraySlow(JSContext *cx, JSObject
 
         sprop = scope->addDataProperty(cx, id, JS_INITIAL_NSLOTS + i,
                                        JSPROP_ENUMERATE);
         if (!sprop)
             goto out_bad;
     }
 
     /*
-     * Render our formerly-reserved count property GC-safe. If length fits in
-     * a jsval, set our slow/sparse COUNT to the current length as a jsval, so
-     * we can tell when only named properties have been added to a dense array
-     * to make it slow-but-not-sparse.
-     *
+     * Render our formerly-reserved count property GC-safe.
      * We do not need to make the length slot GC-safe as this slot is private
      * where the implementation can store an arbitrary value.
      */
     {
         JS_STATIC_ASSERT(JSSLOT_ARRAY_LENGTH == JSSLOT_PRIVATE);
         JS_ASSERT(js_SlowArrayClass.flags & JSCLASS_HAS_PRIVATE);
-        uint32 length = uint32(obj->fslots[JSSLOT_ARRAY_LENGTH]);
-        obj->fslots[JSSLOT_ARRAY_COUNT] = INT_FITS_IN_JSVAL(length)
-                                          ? INT_TO_JSVAL(length)
-                                          : JSVAL_VOID;
+        obj->fslots[JSSLOT_ARRAY_COUNT] = JSVAL_VOID;
     }
 
     /* Make sure we preserve any flags borrowing bits in classword. */
     obj->classword ^= (jsuword) &js_ArrayClass;
     obj->classword |= (jsuword) &js_SlowArrayClass;
 
     obj->map = scope;
     return JS_TRUE;
@@ -1513,17 +1499,17 @@ array_toString_sub(JSContext *cx, JSObje
         }
         genBefore = cx->busyArrays.generation();
     } else {
         /* Cycle, so return empty string. */
         *rval = ATOM_KEY(cx->runtime->atomState.emptyAtom);
         return true;
     }
 
-    JSAutoTempValueRooter tvr(cx, obj);
+    AutoValueRooter tvr(cx, obj);
 
     /* After this point, all paths exit through the 'out' label. */
     MUST_FLOW_THROUGH("out");
     bool ok = false;
 
     /* Get characters to use for the separator. */
     static const jschar comma = ',';
     const jschar *sep;
@@ -1647,17 +1633,17 @@ InitArrayElements(JSContext *cx, JSObjec
      * wouldn't otherwise make the array slow.
      */
     if (obj->isDenseArray() && !js_PrototypeHasIndexedProperties(cx, obj) &&
         start <= MAXINDEX - count && !INDEX_TOO_BIG(start + count)) {
 
 #ifdef DEBUG_jwalden
         {
             /* Verify that overwriteType and writeType were accurate. */
-            JSAutoTempIdRooter idr(cx, JSVAL_ZERO);
+            AutoIdRooter idr(cx);
             for (jsuint i = 0; i < count; i++) {
                 JS_ASSERT_IF(vectorType == SourceVectorAllValues, vector[i] != JSVAL_HOLE);
 
                 jsdouble index = jsdouble(start) + i;
                 if (targetType == TargetElementsAllHoles && index < jsuint(-1)) {
                     JS_ASSERT(ReallyBigIndexToId(cx, index, idr.addr()));
                     JSObject* obj2;
                     JSProperty* prop;
@@ -1713,37 +1699,37 @@ InitArrayElements(JSContext *cx, JSObjec
         return JS_TRUE;
 
     /* Finish out any remaining elements past the max array index. */
     if (obj->isDenseArray() && !ENSURE_SLOW_ARRAY(cx, obj))
         return JS_FALSE;
 
     JS_ASSERT(start == MAXINDEX);
     jsval tmp[2] = {JSVAL_NULL, JSVAL_NULL};
-    JSAutoTempValueRooter tvr(cx, JS_ARRAY_LENGTH(tmp), tmp);
+    AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(tmp), tmp);
     if (!js_NewDoubleInRootedValue(cx, MAXINDEX, &tmp[0]))
         return JS_FALSE;
     jsdouble *dp = JSVAL_TO_DOUBLE(tmp[0]);
     JS_ASSERT(*dp == MAXINDEX);
-    JSAutoTempIdRooter idr(cx);
+    AutoIdRooter idr(cx);
     do {
         tmp[1] = *vector++;
         if (!js_ValueToStringId(cx, tmp[0], idr.addr()) ||
             !obj->setProperty(cx, idr.id(), &tmp[1])) {
             return JS_FALSE;
         }
         *dp += 1;
     } while (vector != end);
 
     return JS_TRUE;
 }
 
 static JSBool
-InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, jsval *vector,
-                JSBool holey = JS_FALSE)
+InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, const jsval *vector,
+                bool holey = false)
 {
     JS_ASSERT(obj->isArray());
 
     obj->fslots[JSSLOT_ARRAY_LENGTH] = length;
 
     if (vector) {
         if (!EnsureCapacity(cx, obj, length))
             return JS_FALSE;
@@ -1764,28 +1750,28 @@ InitArrayObject(JSContext *cx, JSObject 
     }
     return JS_TRUE;
 }
 
 #ifdef JS_TRACER
 static JSString* FASTCALL
 Array_p_join(JSContext* cx, JSObject* obj, JSString *str)
 {
-    JSAutoTempValueRooter tvr(cx);
+    AutoValueRooter tvr(cx);
     if (!array_toString_sub(cx, obj, JS_FALSE, str, tvr.addr())) {
         SetBuiltinError(cx);
         return NULL;
     }
     return JSVAL_TO_STRING(tvr.value());
 }
 
 static JSString* FASTCALL
 Array_p_toString(JSContext* cx, JSObject* obj)
 {
-    JSAutoTempValueRooter tvr(cx);
+    AutoValueRooter tvr(cx);
     if (!array_toString_sub(cx, obj, JS_FALSE, NULL, tvr.addr())) {
         SetBuiltinError(cx);
         return NULL;
     }
     return JSVAL_TO_STRING(tvr.value());
 }
 #endif
 
@@ -1847,17 +1833,17 @@ array_reverse(JSContext *cx, uintN argc,
         /*
          * Per ECMA-262, don't update the length of the array, even if the new
          * array has trailing holes (and thus the original array began with
          * holes).
          */
         return JS_TRUE;
     }
 
-    JSAutoTempValueRooter tvr(cx, JSVAL_NULL);
+    AutoValueRooter tvr(cx);
     for (jsuint i = 0, half = len / 2; i < half; i++) {
         JSBool hole, hole2;
         if (!JS_CHECK_OPERATION_LIMIT(cx) ||
             !GetArrayElement(cx, obj, i, &hole, tvr.addr()) ||
             !GetArrayElement(cx, obj, len - i - 1, &hole2, vp) ||
             !SetOrDeleteArrayElement(cx, obj, len - i - 1, hole, tvr.value()) ||
             !SetOrDeleteArrayElement(cx, obj, i, hole2, *vp)) {
             return false;
@@ -2097,277 +2083,254 @@ sort_compare_strings(void *arg, const vo
  * perform initialization using memset.  Other parts of SpiderMonkey likewise
  * "know" that JSVAL_NULL is zero; this static assertion covers all cases.
  */
 JS_STATIC_ASSERT(JSVAL_NULL == 0);
 
 static JSBool
 array_sort(JSContext *cx, uintN argc, jsval *vp)
 {
-    jsval *argv, fval, *vec, *mergesort_tmp, v;
-    JSObject *obj;
-    CompareArgs ca;
+    jsval fval;
     jsuint len, newlen, i, undefs;
-    JSTempValueRooter tvr;
-    JSBool hole;
-    JSBool ok;
     size_t elemsize;
     JSString *str;
 
-    /*
-     * Optimize the default compare function case if all of obj's elements
-     * have values of type string.
-     */
-    JSBool all_strings;
-
-    argv = JS_ARGV(cx, vp);
+    jsval *argv = JS_ARGV(cx, vp);
     if (argc > 0) {
         if (JSVAL_IS_PRIMITIVE(argv[0])) {
-            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
-                                 JSMSG_BAD_SORT_ARG);
-            return JS_FALSE;
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_SORT_ARG);
+            return false;
         }
         fval = argv[0];     /* non-default compare function */
     } else {
         fval = JSVAL_NULL;
     }
 
-    obj = JS_THIS_OBJECT(cx, vp);
+    JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj || !js_GetLengthProperty(cx, obj, &len))
-        return JS_FALSE;
+        return false;
     if (len == 0) {
         *vp = OBJECT_TO_JSVAL(obj);
-        return JS_TRUE;
+        return true;
     }
 
     /*
      * We need a temporary array of 2 * len jsvals to hold the array elements
      * and the scratch space for merge sort. Check that its size does not
      * overflow size_t, which would allow for indexing beyond the end of the
      * malloc'd vector.
      */
 #if JS_BITS_PER_WORD == 32
-    if ((size_t)len > ~(size_t)0 / (2 * sizeof(jsval))) {
+    if (size_t(len) > size_t(-1) / (2 * sizeof(jsval))) {
         js_ReportAllocationOverflow(cx);
-        return JS_FALSE;
+        return false;
     }
 #endif
-    vec = (jsval *) cx->malloc(2 * (size_t) len * sizeof(jsval));
-    if (!vec)
-        return JS_FALSE;
 
     /*
      * Initialize vec as a root. We will clear elements of vec one by
-     * one while increasing tvr.count when we know that the property at
-     * the corresponding index exists and its value must be rooted.
+     * one while increasing the rooted amount of vec when we know that the
+     * property at the corresponding index exists and its value must be rooted.
      *
      * In this way when sorting a huge mostly sparse array we will not
      * access the tail of vec corresponding to properties that do not
      * exist, allowing OS to avoiding committing RAM. See bug 330812.
      *
      * After this point control must flow through label out: to exit.
      */
-    JS_PUSH_TEMP_ROOT(cx, 0, vec, &tvr);
-
-    /*
-     * By ECMA 262, 15.4.4.11, a property that does not exist (which we
-     * call a "hole") is always greater than an existing property with
-     * value undefined and that is always greater than any other property.
-     * Thus to sort holes and undefs we simply count them, sort the rest
-     * of elements, append undefs after them and then make holes after
-     * undefs.
-     */
-    undefs = 0;
-    newlen = 0;
-    all_strings = JS_TRUE;
-    for (i = 0; i < len; i++) {
-        ok = JS_CHECK_OPERATION_LIMIT(cx);
-        if (!ok)
-            goto out;
-
-        /* Clear vec[newlen] before including it in the rooted set. */
-        vec[newlen] = JSVAL_NULL;
-        tvr.count = newlen + 1;
-        ok = GetArrayElement(cx, obj, i, &hole, &vec[newlen]);
-        if (!ok)
-            goto out;
-
-        if (hole)
-            continue;
-
-        if (JSVAL_IS_VOID(vec[newlen])) {
-            ++undefs;
-            continue;
+    {
+        jsval *vec = (jsval *) cx->malloc(2 * size_t(len) * sizeof(jsval));
+        if (!vec)
+            return false;
+
+        struct AutoFreeVector {
+            AutoFreeVector(JSContext *cx, jsval *&vec) : cx(cx), vec(vec) { }
+            ~AutoFreeVector() {
+                cx->free(vec);
+            }
+            JSContext * const cx;
+            jsval *&vec;
+        } free(cx, vec);
+
+        AutoArrayRooter tvr(cx, 0, vec);
+
+        /*
+         * By ECMA 262, 15.4.4.11, a property that does not exist (which we
+         * call a "hole") is always greater than an existing property with
+         * value undefined and that is always greater than any other property.
+         * Thus to sort holes and undefs we simply count them, sort the rest
+         * of elements, append undefs after them and then make holes after
+         * undefs.
+         */
+        undefs = 0;
+        newlen = 0;
+        bool allStrings = true;
+        for (i = 0; i < len; i++) {
+            if (!JS_CHECK_OPERATION_LIMIT(cx))
+                return false;
+
+            /* Clear vec[newlen] before including it in the rooted set. */
+            JSBool hole;
+            vec[newlen] = JSVAL_NULL;
+            tvr.changeLength(newlen + 1);
+            if (!GetArrayElement(cx, obj, i, &hole, &vec[newlen]))
+                return false;
+
+            if (hole)
+                continue;
+
+            if (JSVAL_IS_VOID(vec[newlen])) {
+                ++undefs;
+                continue;
+            }
+
+            allStrings = allStrings && JSVAL_IS_STRING(vec[newlen]);
+
+            ++newlen;
         }
 
-        /* We know JSVAL_IS_STRING yields 0 or 1, so avoid a branch via &=. */
-        all_strings &= JSVAL_IS_STRING(vec[newlen]);
-
-        ++newlen;
-    }
-
-    if (newlen == 0) {
-        /* The array has only holes and undefs. */
-        ok = JS_TRUE;
-        goto out;
-    }
-
-    /*
-     * The first newlen elements of vec are copied from the array object
-     * (above). The remaining newlen positions are used as GC-rooted scratch
-     * space for mergesort. We must clear the space before including it to
-     * the root set covered by tvr.count. We assume JSVAL_NULL==0 to optimize
-     * initialization using memset.
-     */
-    mergesort_tmp = vec + newlen;
-    memset(mergesort_tmp, 0, newlen * sizeof(jsval));
-    tvr.count = newlen * 2;
-
-    /* Here len == 2 * (newlen + undefs + number_of_holes). */
-    if (fval == JSVAL_NULL) {
+        if (newlen == 0)
+            return true; /* The array has only holes and undefs. */
+
         /*
-         * Sort using the default comparator converting all elements to
-         * strings.
+         * The first newlen elements of vec are copied from the array object
+         * (above). The remaining newlen positions are used as GC-rooted scratch
+         * space for mergesort. We must clear the space before including it to
+         * the root set covered by tvr.count. We assume JSVAL_NULL==0 to optimize
+         * initialization using memset.
          */
-        if (all_strings) {
-            elemsize = sizeof(jsval);
-        } else {
+        jsval *mergesort_tmp = vec + newlen;
+        PodZero(mergesort_tmp, newlen);
+        tvr.changeLength(newlen * 2);
+
+        /* Here len == 2 * (newlen + undefs + number_of_holes). */
+        if (fval == JSVAL_NULL) {
             /*
-             * To avoid string conversion on each compare we do it only once
-             * prior to sorting. But we also need the space for the original
-             * values to recover the sorting result. To reuse
-             * sort_compare_strings we move the original values to the odd
-             * indexes in vec, put the string conversion results in the even
-             * indexes and pass 2 * sizeof(jsval) as an element size to the
-             * sorting function. In this way sort_compare_strings will only
-             * see the string values when it casts the compare arguments as
-             * pointers to jsval.
-             *
-             * This requires doubling the temporary storage including the
-             * scratch space for the merge sort. Since vec already contains
-             * the rooted scratch space for newlen elements at the tail, we
-             * can use it to rearrange and convert to strings first and try
-             * realloc only when we know that we successfully converted all
-             * the elements.
+             * Sort using the default comparator converting all elements to
+             * strings.
              */
+            if (allStrings) {
+                elemsize = sizeof(jsval);
+            } else {
+                /*
+                 * To avoid string conversion on each compare we do it only once
+                 * prior to sorting. But we also need the space for the original
+                 * values to recover the sorting result. To reuse
+                 * sort_compare_strings we move the original values to the odd
+                 * indexes in vec, put the string conversion results in the even
+                 * indexes and pass 2 * sizeof(jsval) as an element size to the
+                 * sorting function. In this way sort_compare_strings will only
+                 * see the string values when it casts the compare arguments as
+                 * pointers to jsval.
+                 *
+                 * This requires doubling the temporary storage including the
+                 * scratch space for the merge sort. Since vec already contains
+                 * the rooted scratch space for newlen elements at the tail, we
+                 * can use it to rearrange and convert to strings first and try
+                 * realloc only when we know that we successfully converted all
+                 * the elements.
+                 */
 #if JS_BITS_PER_WORD == 32
-            if ((size_t)newlen > ~(size_t)0 / (4 * sizeof(jsval))) {
-                js_ReportAllocationOverflow(cx);
-                ok = JS_FALSE;
-                goto out;
-            }
+                if (size_t(newlen) > size_t(-1) / (4 * sizeof(jsval))) {
+                    js_ReportAllocationOverflow(cx);
+                    return false;
+                }
 #endif
 
-            /*
-             * Rearrange and string-convert the elements of the vector from
-             * the tail here and, after sorting, move the results back
-             * starting from the start to prevent overwrite the existing
-             * elements.
-             */
-            i = newlen;
-            do {
-                --i;
-                ok = JS_CHECK_OPERATION_LIMIT(cx);
-                if (!ok)
-                    goto out;
-                v = vec[i];
-                str = js_ValueToString(cx, v);
-                if (!str) {
-                    ok = JS_FALSE;
-                    goto out;
+                /*
+                 * Rearrange and string-convert the elements of the vector from
+                 * the tail here and, after sorting, move the results back
+                 * starting from the start to prevent overwrite the existing
+                 * elements.
+                 */
+                i = newlen;
+                do {
+                    --i;
+                    if (!JS_CHECK_OPERATION_LIMIT(cx))
+                        return false;
+                    jsval v = vec[i];
+                    str = js_ValueToString(cx, v);
+                    if (!str)
+                        return false;
+                    vec[2 * i] = STRING_TO_JSVAL(str);
+                    vec[2 * i + 1] = v;
+                } while (i != 0);
+
+                JS_ASSERT(tvr.array == vec);
+                vec = (jsval *) cx->realloc(vec, 4 * size_t(newlen) * sizeof(jsval));
+                if (!vec) {
+                    vec = tvr.array;
+                    return false;
                 }
-                vec[2 * i] = STRING_TO_JSVAL(str);
-                vec[2 * i + 1] = v;
-            } while (i != 0);
-
-            JS_ASSERT(tvr.u.array == vec);
-            vec = (jsval *) cx->realloc(vec,
-                                        4 * (size_t) newlen * sizeof(jsval));
-            if (!vec) {
-                vec = tvr.u.array;
-                ok = JS_FALSE;
-                goto out;
+                mergesort_tmp = vec + 2 * newlen;
+                PodZero(mergesort_tmp, newlen * 2);
+                tvr.changeArray(vec, newlen * 4);
+                elemsize = 2 * sizeof(jsval);
+            }
+            if (!js_MergeSort(vec, size_t(newlen), elemsize,
+                              sort_compare_strings, cx, mergesort_tmp)) {
+                return false;
             }
-            tvr.u.array = vec;
-            mergesort_tmp = vec + 2 * newlen;
-            memset(mergesort_tmp, 0, newlen * 2 * sizeof(jsval));
-            tvr.count = newlen * 4;
-            elemsize = 2 * sizeof(jsval);
+            if (!allStrings) {
+                /*
+                 * We want to make the following loop fast and to unroot the
+                 * cached results of toString invocations before the operation
+                 * callback has a chance to run the GC. For this reason we do
+                 * not call JS_CHECK_OPERATION_LIMIT in the loop.
+                 */
+                i = 0;
+                do {
+                    vec[i] = vec[2 * i + 1];
+                } while (++i != newlen);
+            }
+        } else {
+            void *mark;
+
+            LeaveTrace(cx);
+
+            CompareArgs ca;
+            ca.context = cx;
+            ca.fval = fval;
+            ca.elemroot  = js_AllocStack(cx, 2 + 2, &mark);
+            if (!ca.elemroot)
+                return false;
+            bool ok = !!js_MergeSort(vec, size_t(newlen), sizeof(jsval),
+                                     comparator_stack_cast(sort_compare),
+                                     &ca, mergesort_tmp);
+            js_FreeStack(cx, mark);
+            if (!ok)
+                return false;
         }
-        ok = js_MergeSort(vec, (size_t) newlen, elemsize,
-                          sort_compare_strings, cx, mergesort_tmp);
-        if (!ok)
-            goto out;
-        if (!all_strings) {
-            /*
-             * We want to make the following loop fast and to unroot the
-             * cached results of toString invocations before the operation
-             * callback has a chance to run the GC. For this reason we do
-             * not call JS_CHECK_OPERATION_LIMIT in the loop.
-             */
-            i = 0;
-            do {
-                vec[i] = vec[2 * i + 1];
-            } while (++i != newlen);
+
+        /*
+         * We no longer need to root the scratch space for the merge sort, so
+         * unroot it now to make the job of a potential GC under
+         * InitArrayElements easier.
+         */
+        tvr.changeLength(newlen);
+        if (!InitArrayElements(cx, obj, 0, newlen, vec, TargetElementsMayContainValues,
+                               SourceVectorAllValues)) {
+            return false;
         }
-    } else {
-        void *mark;
-
-        LeaveTrace(cx);
-
-        ca.context = cx;
-        ca.fval = fval;
-        ca.elemroot  = js_AllocStack(cx, 2 + 2, &mark);
-        if (!ca.elemroot) {
-            ok = JS_FALSE;
-            goto out;
-        }
-        ok = js_MergeSort(vec, (size_t) newlen, sizeof(jsval),
-                          comparator_stack_cast(sort_compare),
-                          &ca, mergesort_tmp);
-        js_FreeStack(cx, mark);
-        if (!ok)
-            goto out;
     }
 
-    /*
-     * We no longer need to root the scratch space for the merge sort, so
-     * unroot it now to make the job of a potential GC under InitArrayElements
-     * easier.
-     */
-    tvr.count = newlen;
-    ok = InitArrayElements(cx, obj, 0, newlen, vec, TargetElementsMayContainValues,
-                           SourceVectorAllValues);
-    if (!ok)
-        goto out;
-
-  out:
-    JS_POP_TEMP_ROOT(cx, &tvr);
-    cx->free(vec);
-    if (!ok)
-        return JS_FALSE;
-
     /* Set undefs that sorted after the rest of elements. */
     while (undefs != 0) {
         --undefs;
-        if (!JS_CHECK_OPERATION_LIMIT(cx) ||
-            !SetArrayElement(cx, obj, newlen++, JSVAL_VOID)) {
-            return JS_FALSE;
-        }
+        if (!JS_CHECK_OPERATION_LIMIT(cx) || !SetArrayElement(cx, obj, newlen++, JSVAL_VOID))
+            return false;
     }
 
     /* Re-create any holes that sorted to the end of the array. */
     while (len > newlen) {
-        if (!JS_CHECK_OPERATION_LIMIT(cx) ||
-            !DeleteArrayElement(cx, obj, --len)) {
+        if (!JS_CHECK_OPERATION_LIMIT(cx) || !DeleteArrayElement(cx, obj, --len))
             return JS_FALSE;
-        }
     }
     *vp = OBJECT_TO_JSVAL(obj);
-    return JS_TRUE;
+    return true;
 }
 
 /*
  * Perl-inspired push, pop, shift, unshift, and splice methods.
  */
 static JSBool
 array_push_slowly(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 {
@@ -2431,17 +2394,17 @@ js_ArrayCompPush(JSContext *cx, JSObject
 }
 JS_DEFINE_CALLINFO_3(extern, BOOL, js_ArrayCompPush, CONTEXT, OBJECT, JSVAL, 0,
                      nanojit::ACC_STORE_ANY)
 
 #ifdef JS_TRACER
 static jsval FASTCALL
 Array_p_push1(JSContext* cx, JSObject* obj, jsval v)
 {
-    JSAutoTempValueRooter tvr(cx, v);
+    AutoValueRooter tvr(cx, v);
     if (obj->isDenseArray()
         ? array_push1_dense(cx, obj, v, tvr.addr())
         : array_push_slowly(cx, obj, 1, tvr.addr(), tvr.addr())) {
         return tvr.value();
     }
     SetBuiltinError(cx);
     return JSVAL_VOID;
 }
@@ -2503,17 +2466,17 @@ array_pop_dense(JSContext *cx, JSObject*
     obj->fslots[JSSLOT_ARRAY_LENGTH] = index;
     return JS_TRUE;
 }
 
 #ifdef JS_TRACER
 static jsval FASTCALL
 Array_p_pop(JSContext* cx, JSObject* obj)
 {
-    JSAutoTempValueRooter tvr(cx);
+    AutoValueRooter tvr(cx);
     if (obj->isDenseArray()
         ? array_pop_dense(cx, obj, tvr.addr())
         : array_pop_slowly(cx, obj, tvr.addr())) {
         return tvr.value();
     }
     SetBuiltinError(cx);
     return JSVAL_VOID;
 }
@@ -2567,17 +2530,17 @@ array_shift(JSContext *cx, uintN argc, j
                 *vp = JSVAL_VOID;
             }
         } else {
             /* Get the to-be-deleted property's value into vp ASAP. */
             if (!GetArrayElement(cx, obj, 0, &hole, vp))
                 return JS_FALSE;
 
             /* Slide down the array above the first element. */
-            JSAutoTempValueRooter tvr(cx, JSVAL_NULL);
+            AutoValueRooter tvr(cx);
             for (i = 0; i != length; i++) {
                 if (!JS_CHECK_OPERATION_LIMIT(cx) ||
                     !GetArrayElement(cx, obj, i + 1, &hole, tvr.addr()) ||
                     !SetOrDeleteArrayElement(cx, obj, i, hole, tvr.value())) {
                     return JS_FALSE;
                 }
             }
 
@@ -2612,17 +2575,17 @@ array_unshift(JSContext *cx, uintN argc,
                 if (!EnsureCapacity(cx, obj, length + argc))
                     return JS_FALSE;