Remove jsobj.h from installed headers, bug 690943. r=luke
authorBrian Hackett <bhackett1024@gmail.com>
Tue, 04 Oct 2011 07:06:54 -0700
changeset 78058 d6756be38c9fcfa206c1a0e660fb0b2dea8ea14d
parent 78057 8a26e77cffaed07138db3328bafc209a7ca37250
child 78059 3304b551a1b5f7def8fa237c509b7db31c03fc91
child 78088 e05e1b35ebedc2fd665a251d3f6c4156e08dd45f
push idunknown
push userunknown
push dateunknown
reviewersluke
bugs690943
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Remove jsobj.h from installed headers, bug 690943. r=luke
caps/src/nsScriptSecurityManager.cpp
caps/src/nsSecurityManagerFactory.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsFrameMessageManager.cpp
content/base/src/nsNodeUtils.cpp
content/canvas/src/CustomQS_Canvas2D.h
content/canvas/src/CustomQS_WebGL.h
content/html/content/src/nsHTMLAudioElement.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMWindowUtils.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
dom/base/nsJSTimeoutHandler.cpp
dom/plugins/base/nsNPAPIPlugin.cpp
dom/workers/Events.cpp
dom/workers/Exceptions.cpp
dom/workers/File.cpp
dom/workers/Location.cpp
dom/workers/Navigator.cpp
dom/workers/WorkerScope.cpp
dom/workers/XMLHttpRequest.cpp
ipc/testshell/XPCShellEnvironment.cpp
js/ductwork/debugger/JSDebugger.cpp
js/ipc/ObjectWrapperParent.cpp
js/jetpack/Handle.h
js/jetpack/JetpackChild.cpp
js/jsd/jsd_val.c
js/src/Makefile.in
js/src/ctypes/Library.cpp
js/src/jsapi-tests/testBug604087.cpp
js/src/jsapi-tests/testRegExpInstanceProperties.cpp
js/src/jsapi-tests/testVersion.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsatom.h
js/src/jsatominlines.h
js/src/jsbool.cpp
js/src/jsclass.h
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jscntxtinlines.h
js/src/jscompartment.cpp
js/src/jscompartment.h
js/src/jsdate.h
js/src/jsdbgapi.cpp
js/src/jsdbgapi.h
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsgc.h
js/src/jsinfer.h
js/src/jsinterp.h
js/src/jsinterpinlines.h
js/src/jsiter.cpp
js/src/jsiter.h
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/jsparse.h
js/src/jsproxy.cpp
js/src/jsproxy.h
js/src/jsprvtd.h
js/src/jsregexp.h
js/src/jsregexpinlines.h
js/src/jsscript.cpp
js/src/jsscript.h
js/src/jsscriptinlines.h
js/src/jsstr.h
js/src/jstracer.cpp
js/src/jsval.h
js/src/jswrapper.cpp
js/src/jswrapper.h
js/src/methodjit/RematInfo.h
js/src/shell/js.cpp
js/src/shell/jsworkers.cpp
js/src/vm/Debugger.cpp
js/src/vm/Stack-inl.h
js/src/vm/Stack.cpp
js/src/vm/Stack.h
js/src/vm/StackSpace.h
js/src/xpconnect/loader/mozJSComponentLoader.cpp
js/src/xpconnect/loader/mozJSSubScriptLoader.cpp
js/src/xpconnect/src/XPCWrapper.cpp
js/src/xpconnect/src/XPCWrapper.h
js/src/xpconnect/src/nsXPConnect.cpp
js/src/xpconnect/src/xpccomponents.cpp
js/src/xpconnect/src/xpcconvert.cpp
js/src/xpconnect/src/xpcdebug.cpp
js/src/xpconnect/src/xpcinlines.h
js/src/xpconnect/src/xpcjsruntime.cpp
js/src/xpconnect/src/xpcprivate.h
js/src/xpconnect/src/xpcpublic.h
js/src/xpconnect/src/xpcquickstubs.cpp
js/src/xpconnect/src/xpcquickstubs.h
js/src/xpconnect/src/xpcvariant.cpp
js/src/xpconnect/src/xpcwrappedjsclass.cpp
js/src/xpconnect/src/xpcwrappednative.cpp
js/src/xpconnect/src/xpcwrappednativeinfo.cpp
js/src/xpconnect/src/xpcwrappednativejsops.cpp
js/src/xpconnect/src/xpcwrappednativescope.cpp
js/src/xpconnect/wrappers/AccessCheck.cpp
js/src/xpconnect/wrappers/CrossOriginWrapper.cpp
js/src/xpconnect/wrappers/WrapperFactory.cpp
js/src/xpconnect/wrappers/WrapperFactory.h
js/src/xpconnect/wrappers/XrayWrapper.cpp
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -54,18 +54,16 @@
 #include "nsNullPrincipal.h"
 #include "nsXPIDLString.h"
 #include "nsCRT.h"
 #include "nsCRTGlue.h"
 #include "nsIJSContextStack.h"
 #include "nsDOMError.h"
 #include "nsDOMCID.h"
 #include "jsdbgapi.h"
-#include "jsfun.h"
-#include "jsobj.h"
 #include "nsIXPConnect.h"
 #include "nsIXPCSecurityManager.h"
 #include "nsTextFormatter.h"
 #include "nsIStringBundle.h"
 #include "nsNetUtil.h"
 #include "nsIProperties.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsIFile.h"
@@ -613,17 +611,17 @@ nsScriptSecurityManager::CheckObjectAcce
     //    trust domain's window or document object.
     // *vp can be a primitive, in that case, we use obj as the target
     // object.
     JSObject* target = JSVAL_IS_PRIMITIVE(*vp) ? obj : JSVAL_TO_OBJECT(*vp);
 
     // Do the same-origin check -- this sets a JS exception if the check fails.
     // Pass the parent object's class name, as we have no class-info for it.
     nsresult rv =
-        ssm->CheckPropertyAccess(cx, target, obj->getClass()->name, id,
+        ssm->CheckPropertyAccess(cx, target, js::GetObjectClass(obj)->name, id,
                                  (mode & JSACC_WRITE) ?
                                  (PRInt32)nsIXPCSecurityManager::ACCESS_SET_PROPERTY :
                                  (PRInt32)nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
 
     if (NS_FAILED(rv))
         return JS_FALSE; // Security check failed (XXX was an error reported?)
 
     return JS_TRUE;
@@ -2408,40 +2406,40 @@ nsScriptSecurityManager::doGetObjectPrin
 {
     NS_ASSERTION(aObj, "Bad call to doGetObjectPrincipal()!");
     nsIPrincipal* result = nsnull;
 
 #ifdef DEBUG
     JSObject* origObj = aObj;
 #endif
     
-    js::Class *jsClass = aObj->getClass();
+    js::Class *jsClass = js::GetObjectClass(aObj);
 
     // A common case seen in this code is that we enter this function
     // with aObj being a Function object, whose parent is a Call
     // object. Neither of those have object principals, so we can skip
     // those objects here before we enter the below loop. That way we
     // avoid wasting time checking properties of their classes etc in
     // the loop.
 
     if (jsClass == &js::FunctionClass) {
-        aObj = aObj->getParent();
+        aObj = js::GetObjectParent(aObj);
 
         if (!aObj)
             return nsnull;
 
-        jsClass = aObj->getClass();
+        jsClass = js::GetObjectClass(aObj);
 
         if (jsClass == &js::CallClass) {
-            aObj = aObj->getParent();
+            aObj = js::GetObjectParent(aObj);
 
             if (!aObj)
                 return nsnull;
 
-            jsClass = aObj->getClass();
+            jsClass = js::GetObjectClass(aObj);
         }
     }
 
     do {
         // Note: jsClass is set before this loop, and also at the
         // *end* of this loop.
         
         if (IS_WRAPPER_CLASS(jsClass)) {
@@ -2452,17 +2450,17 @@ nsScriptSecurityManager::doGetObjectPrin
                                               PR_TRUE
 #endif
                                               );
             if (result) {
                 break;
             }
         } else if (!(~jsClass->flags & (JSCLASS_HAS_PRIVATE |
                                         JSCLASS_PRIVATE_IS_NSISUPPORTS))) {
-            nsISupports *priv = (nsISupports *) aObj->getPrivate();
+            nsISupports *priv = (nsISupports *) js::GetObjectPrivate(aObj);
 
 #ifdef DEBUG
             if (aAllowShortCircuit) {
                 nsCOMPtr<nsIXPConnectWrappedNative> xpcWrapper =
                     do_QueryInterface(priv);
 
                 NS_ASSERTION(!xpcWrapper ||
                              !strcmp(jsClass->name, "XPCNativeWrapper"),
@@ -2478,22 +2476,22 @@ nsScriptSecurityManager::doGetObjectPrin
                 result = objPrin->GetPrincipal();
 
                 if (result) {
                     break;
                 }
             }
         }
 
-        aObj = aObj->getParent();
+        aObj = js::GetObjectParent(aObj);
 
         if (!aObj)
             break;
 
-        jsClass = aObj->getClass();
+        jsClass = js::GetObjectClass(aObj);
     } while (1);
 
 #ifdef DEBUG
     if (aAllowShortCircuit) {
         nsIPrincipal *principal = doGetObjectPrincipal(origObj, PR_FALSE);
 
         // Location is always wrapped (even for same-compartment), so we can
         // loosen the check to same-origin instead of same-principal.
--- a/caps/src/nsSecurityManagerFactory.cpp
+++ b/caps/src/nsSecurityManagerFactory.cpp
@@ -47,21 +47,21 @@
 #include "nsIScriptContext.h"
 #include "nsICategoryManager.h"
 #include "nsXPIDLString.h"
 #include "nsCOMPtr.h"
 #include "nsIServiceManager.h"
 #include "nsString.h"
 #include "nsNetCID.h"
 #include "nsIClassInfoImpl.h"
-#include "jsobj.h"
 #include "nsJSUtils.h"
 #include "nsPIDOMWindow.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIDocument.h"
+#include "jsfriendapi.h"
 
 ///////////////////////
 // nsSecurityNameSet //
 ///////////////////////
 
 nsSecurityNameSet::nsSecurityNameSet()
 {
 }
@@ -321,18 +321,17 @@ static JSFunctionSpec PrivilegeManager_s
 /*
  * "Steal" calls to netscape.security.PrivilegeManager.enablePrivilege,
  * et al. so that code that worked with 4.0 can still work.
  */
 NS_IMETHODIMP 
 nsSecurityNameSet::InitializeNameSet(nsIScriptContext* aScriptContext)
 {
     JSContext* cx = aScriptContext->GetNativeContext();
-    JSObject *global = JS_GetGlobalObject(cx);
-    OBJ_TO_INNER_OBJECT(cx, global);
+    JSObject *global = JS_ObjectToInnerObject(cx, JS_GetGlobalObject(cx));
 
     /*
      * Find Object.prototype's class by walking up the global object's
      * prototype chain.
      */
     JSObject *obj = global;
     JSObject *proto;
     JSAutoRequest ar(cx);
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -5132,17 +5132,17 @@ nsContentUtils::CanAccessNativeAnon()
     return PR_TRUE;
   }
 
   // XXX HACK EWW! Allow chrome://global/ access to these things, even
   // if they've been cloned into less privileged contexts.
   static const char prefix[] = "chrome://global/";
   const char *filename;
   if (fp && JS_IsScriptFrame(cx, fp) &&
-      (filename = JS_GetFrameScript(cx, fp)->filename) &&
+      (filename = JS_GetScriptFilename(cx, JS_GetFrameScript(cx, fp))) &&
       !strncmp(filename, prefix, NS_ARRAY_LENGTH(prefix) - 1)) {
     return PR_TRUE;
   }
 
   // Before we throw, check for UniversalXPConnect.
   nsresult rv = sSecurityManager->IsCapabilityEnabled("UniversalXPConnect", &privileged);
   if (NS_SUCCEEDED(rv) && privileged) {
     return PR_TRUE;
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -38,17 +38,16 @@
 
 #include "ContentChild.h"
 #include "ContentParent.h"
 #include "jscntxt.h"
 #include "nsFrameMessageManager.h"
 #include "nsContentUtils.h"
 #include "nsIXPConnect.h"
 #include "jsapi.h"
-#include "jsinterp.h"
 #include "nsJSUtils.h"
 #include "nsNetUtil.h"
 #include "nsScriptLoader.h"
 #include "nsIJSContextStack.h"
 #include "nsIXULRuntime.h"
 #include "nsIScriptError.h"
 #include "nsIConsoleService.h"
 #include "nsIProtocolHandler.h"
--- a/content/base/src/nsNodeUtils.cpp
+++ b/content/base/src/nsNodeUtils.cpp
@@ -58,17 +58,16 @@
 #include "nsXULElement.h"
 #endif
 #include "nsBindingManager.h"
 #include "nsGenericHTMLElement.h"
 #ifdef MOZ_MEDIA
 #include "nsHTMLMediaElement.h"
 #endif // MOZ_MEDIA
 #include "nsImageLoadingContent.h"
-#include "jsobj.h"
 #include "jsgc.h"
 #include "xpcpublic.h"
 
 using namespace mozilla::dom;
 
 // This macro expects the ownerDocument of content_ to be in scope as
 // |nsIDocument* doc|
 // NOTE: AttributeChildRemoved doesn't use this macro but has a very similar use.
--- a/content/canvas/src/CustomQS_Canvas2D.h
+++ b/content/canvas/src/CustomQS_Canvas2D.h
@@ -412,18 +412,18 @@ nsIDOMCanvasRenderingContext2D_PutImageD
     if (JSVAL_IS_PRIMITIVE(tv.jsval_value()))
         return xpc_qsThrow(cx, NS_ERROR_DOM_TYPE_MISMATCH_ERR);
 
     darray = JSVAL_TO_OBJECT(tv.jsval_value());
 
     js::AutoValueRooter tsrc_tvr(cx);
 
     JSObject *tsrc = NULL;
-    if (darray->getClass() == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8] ||
-        darray->getClass() == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8_CLAMPED])
+    if (js::GetObjectClass(darray) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8] ||
+        js::GetObjectClass(darray) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8_CLAMPED])
     {
         tsrc = js::TypedArray::getTypedArray(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
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_UINT8, darray);
         if (!nobj)
             return JS_FALSE;
 
--- a/content/canvas/src/CustomQS_WebGL.h
+++ b/content/canvas/src/CustomQS_WebGL.h
@@ -62,22 +62,22 @@
     if (argc > index) \
       if (!JS_ValueToECMAUint32(cx, argv[index], &(var))) \
         return JS_FALSE; \
   } while (0)
 
 
 static inline bool
 helper_isInt32Array(JSObject *obj) {
-    return obj->getClass() == &js::TypedArray::fastClasses[js::TypedArray::TYPE_INT32];
+    return js::GetObjectClass(obj) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_INT32];
 }
 
 static inline bool
 helper_isFloat32Array(JSObject *obj) {
-    return obj->getClass() == &js::TypedArray::fastClasses[js::TypedArray::TYPE_FLOAT32];
+    return js::GetObjectClass(obj) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_FLOAT32];
 }
 
 /*
  * BufferData takes:
  *    BufferData (int, int, int)
  *    BufferData_buf (int, js::ArrayBuffer *, int)
  *    BufferData_array (int, js::TypedArray *, int)
  */
--- a/content/html/content/src/nsHTMLAudioElement.cpp
+++ b/content/html/content/src/nsHTMLAudioElement.cpp
@@ -53,16 +53,17 @@
 #include "nsXPCOMStrings.h"
 #include "prlock.h"
 #include "nsThreadUtils.h"
 
 #include "nsIScriptSecurityManager.h"
 #include "nsIXPConnect.h"
 #include "jsapi.h"
 #include "jscntxt.h"
+#include "jsfriendapi.h"
 #include "jstypedarray.h"
 #include "nsJSUtils.h"
 
 #include "nsITimer.h"
 
 #include "nsEventDispatcher.h"
 #include "nsIDOMProgressEvent.h"
 #include "nsContentUtils.h"
@@ -195,17 +196,17 @@ nsHTMLAudioElement::MozWriteAudio(const 
     return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
   }
 
   JSObject *darray = JSVAL_TO_OBJECT(aData);
   js::AutoValueRooter tsrc_tvr(aCx);
   JSObject *tsrc = NULL;
 
   // Allow either Float32Array or plain JS Array
-  if (darray->getClass() == &js::TypedArray::fastClasses[js::TypedArray::TYPE_FLOAT32])
+  if (js::GetObjectClass(darray) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_FLOAT32])
   {
     tsrc = js::TypedArray::getTypedArray(darray);
   } else if (JS_IsArrayObject(aCx, darray)) {
     JSObject *nobj = js_CreateTypedArrayWithArray(aCx, js::TypedArray::TYPE_FLOAT32, darray);
     if (!nobj) {
       return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
     }
     *tsrc_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -37,17 +37,16 @@
  * 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 "WrapperFactory.h"
 #include "AccessCheck.h"
 
 #include "xpcprivate.h"
 #include "XPCWrapper.h"
 
 #include "nscore.h"
@@ -1632,20 +1631,20 @@ static const JSClass *sObjectClass = nsn
 static void
 FindObjectClass(JSObject* aGlobalObject)
 {
   NS_ASSERTION(!sObjectClass,
                "Double set of sObjectClass");
   JSObject *obj, *proto = aGlobalObject;
   do {
     obj = proto;
-    proto = obj->getProto();
+    proto = js::GetObjectProto(obj);
   } while (proto);
 
-  sObjectClass = obj->getJSClass();
+  sObjectClass = js::GetObjectJSClass(obj);
 }
 
 static void
 PrintWarningOnConsole(JSContext *cx, const char *stringBundleProperty)
 {
   nsCOMPtr<nsIStringBundleService> stringService =
     mozilla::services::GetStringBundleService();
   if (!stringService) {
@@ -1818,17 +1817,17 @@ WrapNativeParent(JSContext *cx, JSObject
   return NS_OK;
 }
 
 // static
 
 nsISupports *
 nsDOMClassInfo::GetNative(nsIXPConnectWrappedNative *wrapper, JSObject *obj)
 {
-  return wrapper ? wrapper->Native() : static_cast<nsISupports*>(obj->getPrivate());
+  return wrapper ? wrapper->Native() : static_cast<nsISupports*>(js::GetObjectPrivate(obj));
 }
 
 nsresult
 nsDOMClassInfo::DefineStaticJSVals(JSContext *cx)
 {
 #define SET_JSID_TO_STRING(_id, _cx, _str)                                    \
   if (JSString *str = ::JS_InternString(_cx, _str))                           \
       _id = INTERNED_STRING_TO_JSID(_cx, str);                                \
@@ -4720,17 +4719,17 @@ nsDOMClassInfo::PostCreatePrototype(JSCo
   if (win->IsClosedOrClosing()) {
     return NS_OK;
   }
 
   // If the window is in a different compartment than the global object, then
   // it's likely that global is a sandbox object whose prototype is a window.
   // Don't do anything in this case.
   if (win->FastGetGlobalJSObject() &&
-      global->compartment() != win->FastGetGlobalJSObject()->compartment()) {
+      js::GetObjectCompartment(global) != js::GetObjectCompartment(win->FastGetGlobalJSObject())) {
     return NS_OK;
   }
 
   if (win->IsOuterWindow()) {
     // XXXjst: Do security checks here when we remove the security
     // checks on the inner window.
 
     win = win->GetCurrentInnerWindowInternal();
@@ -5256,17 +5255,17 @@ nsWindowSH::GetProperty(nsIXPConnectWrap
 
         return NS_SUCCESS_I_DID_SOMETHING;
       }
     }
   }
 
   if (id == sWrappedJSObject_id &&
       xpc::AccessCheck::isChrome(cx->compartment)) {
-    OBJ_TO_OUTER_OBJECT(cx, obj);
+    obj = JS_ObjectToOuterObject(cx, obj);
     *vp = OBJECT_TO_JSVAL(obj);
     return NS_SUCCESS_I_DID_SOMETHING;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -6849,17 +6848,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
   // binding a name) a new undefined property that's not already
   // defined on our prototype chain. This way we can access this
   // expando w/o ever getting back into XPConnect.
   if ((flags & JSRESOLVE_ASSIGNING) && !(flags & JSRESOLVE_WITH)) {
     JSObject *realObj;
     wrapper->GetJSObject(&realObj);
 
     if (obj == realObj) {
-      JSObject *proto = obj->getProto();
+      JSObject *proto = js::GetObjectProto(obj);
       if (proto) {
         JSObject *pobj = NULL;
         jsval val;
 
         if (!::JS_LookupPropertyWithFlagsById(cx, proto, id, flags,
                                               &pobj, &val)) {
           *_retval = JS_FALSE;
 
@@ -6881,17 +6880,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
       // know here we're dealing with an undefined property set, so
       // we're not declaring readonly or permanent properties.
       //
       // Since we always create the undeclared property here without given a
       // chance for the interpreter to report applicable strict mode warnings,
       // we must take care to check those warnings here.
       JSString *str = JSID_TO_STRING(id);
       if ((!(flags & JSRESOLVE_QUALIFIED) &&
-           !js_CheckUndeclaredVarAssignment(cx, str)) ||
+           !js::CheckUndeclaredVarAssignment(cx, str)) ||
           !::JS_DefinePropertyById(cx, obj, id, JSVAL_VOID, JS_PropertyStub,
                                    JS_StrictPropertyStub, JSPROP_ENUMERATE)) {
         *_retval = JS_FALSE;
 
         return NS_OK;
       }
 
       *objp = obj;
@@ -7167,17 +7166,17 @@ NodePrincipalGetter(JSContext *cx, JSObj
 }
 
 NS_IMETHODIMP
 nsNodeSH::PostCreatePrototype(JSContext * cx, JSObject * proto)
 {
   // set up our proto first
   nsresult rv = nsDOMGenericSH::PostCreatePrototype(cx, proto);
 
-  if (xpc::AccessCheck::isChrome(proto->compartment())) {
+  if (xpc::AccessCheck::isChrome(js::GetObjectCompartment(proto))) {
     // Stick nodePrincipal and baseURIObject  properties on there
     JS_DefinePropertyById(cx, proto, sNodePrincipal_id,
                           JSVAL_VOID, GetterShim<NodePrincipalGetter>,
                           nsnull,
                           JSPROP_READONLY | JSPROP_SHARED);
     JS_DefinePropertyById(cx, proto, sBaseURIObject_id,
                           JSVAL_VOID, GetterShim<BaseURIObjectGetter>,
                           nsnull,
@@ -8242,17 +8241,17 @@ DocumentURIObjectGetter(JSContext *cx, J
 }
 
 NS_IMETHODIMP
 nsDocumentSH::PostCreatePrototype(JSContext * cx, JSObject * proto)
 {
   // set up our proto first
   nsresult rv = nsNodeSH::PostCreatePrototype(cx, proto);
 
-  if (xpc::AccessCheck::isChrome(proto->compartment())) {
+  if (xpc::AccessCheck::isChrome(js::GetObjectCompartment(proto))) {
     // Stick a documentURIObject property on there
     JS_DefinePropertyById(cx, proto, sDocumentURIObject_id,
                           JSVAL_VOID, GetterShim<DocumentURIObjectGetter>,
                           nsnull,
                           JSPROP_READONLY | JSPROP_SHARED);
   }
 
   return rv;
@@ -8473,18 +8472,18 @@ nsHTMLDocumentSH::DocumentAllGetProperty
   // document.all.item and .namedItem get their value in the
   // newResolve hook, so nothing to do for those properties here. And
   // we need to return early to prevent <div id="item"> from shadowing
   // document.all.item(), etc.
   if (id == sItem_id || id == sNamedItem_id) {
     return JS_TRUE;
   }
 
-  while (obj->getJSClass() != &sHTMLDocumentAllClass) {
-    obj = obj->getProto();
+  while (js::GetObjectJSClass(obj) != &sHTMLDocumentAllClass) {
+    obj = js::GetObjectProto(obj);
 
     if (!obj) {
       NS_ERROR("The JS engine lies!");
 
       return JS_TRUE;
     }
   }
 
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -74,18 +74,16 @@
 #include "nsCSSProps.h"
 #include "nsDOMFile.h"
 
 #if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK2)
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
 #endif
 
-#include "jsobj.h"
-
 #include "Layers.h"
 #include "nsIIOService.h"
 
 #include "mozilla/dom/Element.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::layers;
 
@@ -1570,17 +1568,17 @@ nsDOMWindowUtils::GetParent()
   if(JSVAL_IS_PRIMITIVE(argv[0]))
     return NS_ERROR_XPC_BAD_CONVERT_JS;
 
   JSObject *parent = JS_GetParent(cx, JSVAL_TO_OBJECT(argv[0]));
   *rval = OBJECT_TO_JSVAL(parent);
 
   // Outerize if necessary.
   if (parent) {
-    if (JSObjectOp outerize = parent->getClass()->ext.outerObject)
+    if (JSObjectOp outerize = js::GetObjectClass(parent)->ext.outerObject)
       *rval = OBJECT_TO_JSVAL(outerize(cx, parent));
   }
 
   cc->SetReturnValueWasSet(PR_TRUE);
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -772,35 +772,35 @@ nsPIDOMWindow::~nsPIDOMWindow() {}
 
 //*****************************************************************************
 // nsOuterWindowProxy: Outer Window Proxy
 //*****************************************************************************
 
 JSString *
 nsOuterWindowProxy::obj_toString(JSContext *cx, JSObject *proxy)
 {
-    JS_ASSERT(proxy->isProxy());
+    JS_ASSERT(js::IsProxy(proxy));
 
     return JS_NewStringCopyZ(cx, "[object Window]");
 }
 
 nsOuterWindowProxy
 nsOuterWindowProxy::singleton;
 
 JSObject *
 NS_NewOuterWindowProxy(JSContext *cx, JSObject *parent)
 {
   JSAutoEnterCompartment ac;
   if (!ac.enter(cx, parent)) {
     return nsnull;
   }
 
-  JSObject *obj = js::Wrapper::New(cx, parent, parent->getProto(), parent,
+  JSObject *obj = js::Wrapper::New(cx, parent, js::GetObjectProto(parent), parent,
                                    &nsOuterWindowProxy::singleton);
-  NS_ASSERTION(obj->getClass()->ext.innerObject, "bad class");
+  NS_ASSERTION(js::GetObjectClass(obj)->ext.innerObject, "bad class");
   return obj;
 }
 
 //*****************************************************************************
 //***    nsGlobalWindow: Object Management
 //*****************************************************************************
 
 nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
@@ -2237,17 +2237,18 @@ nsGlobalWindow::SetNewDocument(nsIDocume
 
       // Initialize DOM classes etc on the inner window.
       rv = mContext->InitClasses(newInnerWindow->mJSObject);
       NS_ENSURE_SUCCESS(rv, rv);
 
       if (navigatorHolder) {
         JS_ASSERT(JSVAL_IS_OBJECT(nav));
 
-        if (JSVAL_TO_OBJECT(nav)->compartment() == newInnerWindow->mJSObject->compartment()) {
+        if (js::GetObjectCompartment(JSVAL_TO_OBJECT(nav)) ==
+            js::GetObjectCompartment(newInnerWindow->mJSObject)) {
           // Restore window.navigator onto the new inner window.
 
           ::JS_DefineProperty(cx, newInnerWindow->mJSObject, "navigator",
                               nav, nsnull, nsnull,
                               JSPROP_ENUMERATE | JSPROP_PERMANENT |
                               JSPROP_READONLY);
 
           // The Navigator's prototype object keeps a reference to the
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -690,17 +690,17 @@ nsJSContext::DOMOperationCallback(JSCont
   }
 
   PRTime duration = now - callbackTime;
 
   // Check the amount of time this script has been running, or if the
   // dialog is disabled.
   JSObject* global = ::JS_GetGlobalForScopeChain(cx);
   bool isTrackingChromeCodeTime =
-    global && xpc::AccessCheck::isChrome(global->getCompartment());
+    global && xpc::AccessCheck::isChrome(js::GetObjectCompartment(global));
   if (duration < (isTrackingChromeCodeTime ?
                   sMaxChromeScriptRunTime : sMaxScriptRunTime)) {
     return JS_TRUE;
   }
 
   if (!nsContentUtils::IsSafeToRunScript()) {
     // If it isn't safe to run script, then it isn't safe to bring up the
     // prompt (since that will cause the event loop to spin). In this case
@@ -2161,33 +2161,32 @@ nsJSContext::GetGlobalObject()
     return nsnull;
   }
 
   if (mGlobalObjectRef)
     return mGlobalObjectRef;
 
 #ifdef DEBUG
   {
-    JSObject *inner = global;
-    OBJ_TO_INNER_OBJECT(mContext, inner);
+    JSObject *inner = JS_ObjectToInnerObject(mContext, global);
 
     // If this assertion hits then it means that we have a window object as
     // our global, but we never called CreateOuterObject.
     NS_ASSERTION(inner == global, "Shouldn't be able to innerize here");
   }
 #endif
 
   JSClass *c = JS_GET_CLASS(mContext, global);
 
   if (!c || ((~c->flags) & (JSCLASS_HAS_PRIVATE |
                             JSCLASS_PRIVATE_IS_NSISUPPORTS))) {
     return nsnull;
   }
 
-  nsISupports *priv = (nsISupports *)global->getPrivate();
+  nsISupports *priv = (nsISupports *)js::GetObjectPrivate(global);
 
   nsCOMPtr<nsIXPConnectWrappedNative> wrapped_native =
     do_QueryInterface(priv);
 
   nsCOMPtr<nsIScriptGlobalObject> sgo;
   if (wrapped_native) {
     // The global object is a XPConnect wrapped native, the native in
     // the wrapper might be the nsIScriptGlobalObject
@@ -2328,18 +2327,17 @@ nsJSContext::SetOuterObject(void *aOuter
   JS_SetPrototype(mContext, outer, JS_GetPrototype(mContext, inner));
 
   return NS_OK;
 }
 
 nsresult
 nsJSContext::InitOuterWindow()
 {
-  JSObject *global = JS_GetGlobalObject(mContext);
-  OBJ_TO_INNER_OBJECT(mContext, global);
+  JSObject *global = JS_ObjectToInnerObject(mContext, JS_GetGlobalObject(mContext));
 
   nsresult rv = InitClasses(global); // this will complete global object initialization
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 nsresult
@@ -3018,17 +3016,17 @@ nsJSContext::ClearScope(void *aGlobalObj
       if (!JS_DefineProperty(mContext, obj, "window", window,
                              JS_PropertyStub, JS_StrictPropertyStub,
                              JSPROP_ENUMERATE | JSPROP_READONLY |
                              JSPROP_PERMANENT)) {
         JS_ClearPendingException(mContext);
       }
     }
 
-    if (!obj->getParent()) {
+    if (!js::GetObjectParent(obj)) {
       JS_ClearRegExpStatics(mContext, obj);
     }
 
     // Always clear watchpoints, to deal with two cases:
     // 1.  The first document for this window is loading, and a miscreant has
     //     preset watchpoints on the window object in order to attack the new
     //     document's privileged information.
     // 2.  A document loaded and used watchpoints on its own window, leaving
--- a/dom/base/nsJSTimeoutHandler.cpp
+++ b/dom/base/nsJSTimeoutHandler.cpp
@@ -123,18 +123,18 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
     if (tmp->mExpr) {
       foo.AppendLiteral(" [");
       foo.Append(tmp->mFileName);
       foo.AppendLiteral(":");
       foo.AppendInt(tmp->mLineNo);
       foo.AppendLiteral("]");
     }
     else if (tmp->mFunObj) {
-      JSFunction* fun = (JSFunction*)tmp->mFunObj->getPrivate();
-      if (fun->atom) {
+      JSFunction* fun = JS_GetObjectFunction(tmp->mFunObj);
+      if (JS_GetFunctionId(fun)) {
         JSFlatString *funId = JS_ASSERT_STRING_IS_FLAT(JS_GetFunctionId(fun));
         size_t size = 1 + JS_PutEscapedFlatString(NULL, 0, funId, 0);
         char *name = new char[size];
         if (name) {
           JS_PutEscapedFlatString(name, size, funId, 0);
           foo.AppendLiteral(" [");
           foo.Append(name);
           delete[] name;
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -43,16 +43,17 @@
 #include "base/basictypes.h"
 
 #include "prtypes.h"
 #include "prmem.h"
 #include "prenv.h"
 #include "prclist.h"
 
 #include "jscntxt.h"
+#include "jsfriendapi.h"
 
 #include "nsPluginHost.h"
 #include "nsNPAPIPlugin.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsNPAPIPluginStreamListener.h"
 #include "nsIServiceManager.h"
 #include "nsThreadUtils.h"
 #include "nsIPrivateBrowsingService.h"
@@ -1612,17 +1613,17 @@ bool NP_CALLBACK
 
   JSObject *obj =
     nsNPObjWrapper::GetNewOrUsed(npp, cx, npobj);
 
   if (!obj) {
     return false;
   }
 
-  OBJ_TO_INNER_OBJECT(cx, obj);
+  obj = JS_ObjectToInnerObject(cx, obj);
 
   // Root obj and the rval (below).
   jsval vec[] = { OBJECT_TO_JSVAL(obj), JSVAL_NULL };
   js::AutoArrayRooter tvr(cx, NS_ARRAY_LENGTH(vec), vec);
   jsval *rval = &vec[1];
 
   if (result) {
     // Initialize the out param to void
--- a/dom/workers/Events.cpp
+++ b/dom/workers/Events.cpp
@@ -36,17 +36,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "Events.h"
 
 #include "jsapi.h"
 #include "jscntxt.h"
-#include "jsobj.h"
+#include "jsfriendapi.h"
 
 #include "nsTraceRefcnt.h"
 
 #include "WorkerInlines.h"
 #include "WorkerPrivate.h"
 
 #define PROPERTY_FLAGS \
   JSPROP_ENUMERATE | JSPROP_SHARED
--- a/dom/workers/Exceptions.cpp
+++ b/dom/workers/Exceptions.cpp
@@ -36,17 +36,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "Exceptions.h"
 
 #include "jsapi.h"
 #include "jscntxt.h"
-#include "jsobj.h"
+#include "jsfriendapi.h"
 #include "jsprf.h"
 
 #include "nsTraceRefcnt.h"
 
 #include "WorkerInlines.h"
 
 #define PROPERTY_FLAGS \
   JSPROP_ENUMERATE | JSPROP_SHARED
--- a/dom/workers/File.cpp
+++ b/dom/workers/File.cpp
@@ -39,16 +39,17 @@
 
 #include "File.h"
 
 #include "nsIDOMFile.h"
 
 #include "jsapi.h"
 #include "jsatom.h"
 #include "jscntxt.h"
+#include "jsfriendapi.h"
 #include "nsCOMPtr.h"
 #include "nsJSUtils.h"
 #include "nsStringGlue.h"
 #include "xpcprivate.h"
 #include "xpcquickstubs.h"
 
 #include "Exceptions.h"
 #include "WorkerInlines.h"
--- a/dom/workers/Location.cpp
+++ b/dom/workers/Location.cpp
@@ -35,17 +35,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "Location.h"
 
 #include "jsapi.h"
 #include "jscntxt.h"
-#include "jsobj.h"
+#include "jsfriendapi.h"
 
 #include "nsTraceRefcnt.h"
 
 #define PROPERTY_FLAGS \
   JSPROP_ENUMERATE | JSPROP_SHARED
 
 USING_WORKERS_NAMESPACE
 
--- a/dom/workers/Navigator.cpp
+++ b/dom/workers/Navigator.cpp
@@ -35,17 +35,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "Navigator.h"
 
 #include "jsapi.h"
 #include "jscntxt.h"
-#include "jsobj.h"
+#include "jsfriendapi.h"
 
 #include "nsTraceRefcnt.h"
 
 #include "RuntimeService.h"
 
 #define PROPERTY_FLAGS \
   JSPROP_ENUMERATE | JSPROP_SHARED
 
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -36,17 +36,16 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "WorkerScope.h"
 
 #include "jsapi.h"
 #include "jscntxt.h"
-#include "jsobj.h"
 
 #include "nsTraceRefcnt.h"
 #include "xpcprivate.h"
 
 #include "ChromeWorkerScope.h"
 #include "Events.h"
 #include "EventTarget.h"
 #include "Exceptions.h"
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -35,17 +35,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "XMLHttpRequest.h"
 
 #include "jsapi.h"
 #include "jscntxt.h"
-#include "jsobj.h"
+#include "jsfriendapi.h"
 
 #include "WorkerPrivate.h"
 #include "XMLHttpRequestPrivate.h"
 
 #include "WorkerInlines.h"
 
 #define PROPERTY_FLAGS \
   JSPROP_ENUMERATE | JSPROP_SHARED
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -41,16 +41,17 @@
 #endif
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>     /* for isatty() */
 #endif
 
 #include "base/basictypes.h"
 
 #include "jsapi.h"
+#include "jsdbgapi.h"
 #include "jsprf.h"
 
 #include "xpcpublic.h"
 
 #include "XPCShellEnvironment.h"
 
 #include "mozilla/XPCOM.h"
 
--- a/js/ductwork/debugger/JSDebugger.cpp
+++ b/js/ductwork/debugger/JSDebugger.cpp
@@ -35,17 +35,16 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "JSDebugger.h"
 #include "nsIXPConnect.h"
 #include "nsThreadUtils.h"
 #include "jsapi.h"
-#include "jsobj.h"
 #include "jsgc.h"
 #include "jsfriendapi.h"
 #include "jsdbgapi.h"
 #include "mozilla/ModuleUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsMemory.h"
 
 #define JSDEBUGGER_CONTRACTID \
--- a/js/ipc/ObjectWrapperParent.cpp
+++ b/js/ipc/ObjectWrapperParent.cpp
@@ -39,19 +39,18 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/jsipc/ObjectWrapperParent.h"
 #include "mozilla/jsipc/ContextWrapperParent.h"
 #include "mozilla/jsipc/CPOWTypes.h"
 #include "mozilla/unused.h"
 #include "nsJSUtils.h"
 
-#include "jsobj.h"
-#include "jsfun.h"
 #include "jsutil.h"
+#include "jsfriendapi.h"
 
 using namespace mozilla::jsipc;
 
 namespace {
 
     // Only need one reserved slot because the ObjectWrapperParent* is
     // stored in the private slot.
     static const uintN sFlagsSlot = 0;
@@ -197,17 +196,17 @@ const js::Class ObjectWrapperParent::sCP
           nsnull, // wrappedObject
     }
 };
 
 void
 ObjectWrapperParent::ActorDestroy(ActorDestroyReason)
 {
     if (mObj) {
-        mObj->setPrivate(NULL);
+        JS_SetPrivate(NULL, mObj, NULL);
         mObj = NULL;
     }
 }
 
 ContextWrapperParent*
 ObjectWrapperParent::Manager()
 {
     PContextWrapperParent* pcwp = PObjectWrapperParent::Manager();
@@ -223,18 +222,18 @@ ObjectWrapperParent::GetJSObject(JSConte
         JS_SetReservedSlot(cx, mObj, sFlagsSlot, JSVAL_ZERO);
     }
     return mObj;
 }
 
 static ObjectWrapperParent*
 Unwrap(JSContext* cx, JSObject* obj)
 {
-    while (obj->getClass() != &ObjectWrapperParent::sCPOW_JSClass)
-        if (!(obj = obj->getProto()))
+    while (js::GetObjectClass(obj) != &ObjectWrapperParent::sCPOW_JSClass)
+        if (!(obj = js::GetObjectProto(obj)))
             return NULL;
     
     ObjectWrapperParent* self =
         static_cast<ObjectWrapperParent*>(JS_GetPrivate(cx, obj));
 
     NS_ASSERTION(!self || self->GetJSObject(cx) == obj,
                  "Wrapper and wrapped object disagree?");
     
--- a/js/jetpack/Handle.h
+++ b/js/jetpack/Handle.h
@@ -40,18 +40,19 @@
 
 #ifndef mozilla_jetpack_HandleParent_h
 #define mozilla_jetpack_HandleParent_h
 
 #include "mozilla/jetpack/PHandleParent.h"
 #include "mozilla/jetpack/PHandleChild.h"
 
 #include "jsapi.h"
-#include "jsobj.h"
+#include "jsclass.h"
 #include "jscntxt.h"
+#include "jsfriendapi.h"
 
 #include "mozilla/unused.h"
 
 namespace mozilla {
 namespace jetpack {
 
 /**
  * BaseType should be one of PHandleParent or PHandleChild; see the
@@ -152,17 +153,17 @@ private:
   static bool IsParent(const PHandleParent* handle) { return true; }
   static bool IsParent(const PHandleChild* handle) { return false; }
 
   void TearDown() {
     if (mCx) {
       JSAutoRequest ar(mCx);
 
       if (mObj) {
-        mObj->setPrivate(NULL);
+        JS_SetPrivate(mCx, mObj, NULL);
 
         js::AutoObjectRooter obj(mCx, mObj);
         mObj = NULL;
 
         // If we can't enter the compartment, we won't run onInvalidate().
         JSAutoEnterCompartment ac;
         if (ac.enter(mCx, obj.object())) {
           JSBool hasOnInvalidate;
@@ -196,18 +197,18 @@ private:
   // Used to cache the JSObject returned by ToJSObject, which is
   // otherwise a const method.
   JSObject*  mObj;
   JSContext* mCx;
   bool mRooted;
 
   static Handle*
   Unwrap(JSContext* cx, JSObject* obj) {
-    while (obj && obj->getJSClass() != &sHandle_JSClass)
-      obj = obj->getProto();
+    while (obj && Jsvalify(js::GetObjectClass(obj)) != &sHandle_JSClass)
+      obj = js::GetObjectProto(obj);
 
     if (!obj)
       return NULL;
 
     Handle* self = static_cast<Handle*>(JS_GetPrivate(cx, obj));
 
     NS_ASSERTION(!self || self->ToJSObject(cx) == obj,
                  "Wrapper and wrapped object disagree?");
--- a/js/jetpack/JetpackChild.cpp
+++ b/js/jetpack/JetpackChild.cpp
@@ -32,16 +32,17 @@
  * 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 "base/basictypes.h"
 #include "jscntxt.h"
+#include "jswrapper.h"
 #include "nsXULAppAPI.h"
 #include "nsNativeCharsetUtils.h"
 
 #include "mozilla/jetpack/JetpackChild.h"
 #include "mozilla/jetpack/Handle.h"
 #include "mozilla/IntentionalCrash.h"
 
 #include <stdio.h>
@@ -481,17 +482,17 @@ JetpackChild::EvalInSandbox(JSContext* c
   if (!JSVAL_IS_OBJECT(argv[0]) ||
       !(obj = JSVAL_TO_OBJECT(argv[0]))) {
     JS_ReportError(cx, "The first argument to evalInSandbox must be a global object created using createSandbox.");
     JS_ASSERT(JS_FALSE);
     return JS_FALSE;
   }
 
   // Unwrap, and switch compartments
-  obj = obj->unwrap();
+  obj = js::UnwrapObject(obj);
 
   JSAutoEnterCompartment ac;
   if (!ac.enter(cx, obj))
     return JS_FALSE;
 
   if (&sGlobalClass != JS_GetClass(cx, obj) ||
       obj == JS_GetGlobalObject(cx)) {
     JS_ReportError(cx, "The first argument to evalInSandbox must be a global object created using createSandbox.");
--- a/js/jsd/jsd_val.c
+++ b/js/jsd/jsd_val.c
@@ -378,17 +378,17 @@ jsd_DropValue(JSDContext* jsdc, JSDValue
 jsval
 jsd_GetValueWrappedJSVal(JSDContext* jsdc, JSDValue* jsdval)
 {
     JSObject* obj;
     JSContext* cx;
     jsval val = jsdval->val;
     if (!JSVAL_IS_PRIMITIVE(val)) {
         cx = JSD_GetDefaultJSContext(jsdc);
-        obj = js_ObjectToOuterObject(cx, JSVAL_TO_OBJECT(val));
+        obj = JS_ObjectToOuterObject(cx, JSVAL_TO_OBJECT(val));
         if (!obj)
         {
             JS_ClearPendingException(cx);
             val = JSVAL_NULL;
         }
         else
             val = OBJECT_TO_JSVAL(obj);
     }
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -181,47 +181,38 @@ INSTALLED_HEADERS = \
 		jsclone.h \
 		jscntxt.h \
 		jscompat.h \
 		jscrashreport.h \
 		jsdate.h \
 		jsdbgapi.h \
 		jsdhash.h \
 		jsemit.h \
-		jsfun.h \
 		jsfriendapi.h \
 		jsgc.h \
 		jscell.h \
 		jsgcchunk.h \
 		jsgcstats.h \
 		jshash.h \
-		jsinfer.h \
-		jsinferinlines.h \
-		jsinterp.h \
 		jsinttypes.h \
-		jsiter.h \
 		jslock.h \
-		jsobj.h \
 		json.h \
 		jsopcode.tbl \
 		jsopcode.h \
 		jsotypes.h \
-		jsparse.h \
 		jsproxy.h \
 		jsprf.h \
 		jsprobes.h \
 		jspropertycache.h \
 		jspropertytree.h \
 		jsproto.tbl \
 		jsprvtd.h \
 		jspubtd.h \
 		jsreflect.h \
 		jsscan.h \
-		jsscope.h \
-		jsscript.h \
 		jsstaticcheck.h \
 		jsstdint.h \
 		jsstr.h \
 		jstracer.h \
 		jstypedarray.h \
 		jstypes.h \
 		jsutil.h \
 		jsvector.h \
@@ -241,22 +232,18 @@ VPATH		+= \
 		$(srcdir)/vm \
 		$(srcdir)/frontend \
 		$(srcdir)/ds \
 		$(NULL)
 
 EXPORTS_NAMESPACES = vm ds
 
 EXPORTS_vm = \
-		ArgumentsObject.h \
-		CallObject.h \
-		GlobalObject.h \
-		Stack.h \
 		String.h \
-		StringObject.h \
+		StackSpace.h \
 		Unicode.h  \
 		$(NULL)
 
 EXPORTS_ds = \
 		LifoAlloc.h
 
 ###############################################
 # BEGIN include sources for low-level code shared with Gecko
--- a/js/src/ctypes/Library.cpp
+++ b/js/src/ctypes/Library.cpp
@@ -34,16 +34,17 @@
  * 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 "jsstr.h"
 #include "Library.h"
 #include "CTypes.h"
 #include "prlink.h"
 
 namespace js {
 namespace ctypes {
 
 /*******************************************************************************
--- a/js/src/jsapi-tests/testBug604087.cpp
+++ b/js/src/jsapi-tests/testBug604087.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sw=4 et tw=99:
  *
  * Tests JS_TransplantObject
  */
 
 #include "tests.h"
+#include "jsobj.h"
 #include "jswrapper.h"
 
 struct OuterWrapper : js::Wrapper
 {
     OuterWrapper() : Wrapper(0) {}
 
     virtual bool isOuterWindow() {
         return true;
@@ -52,25 +53,25 @@ BEGIN_TEST(testBug604087)
     JSObject *outerObj = js::Wrapper::New(cx, global, global->getProto(), global,
                                           &OuterWrapper::singleton);
     JSObject *compartment2 = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL);
     JSObject *compartment3 = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL);
     JSObject *compartment4 = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL);
 
     JSObject *c2wrapper = wrap(cx, outerObj, compartment2);
     CHECK(c2wrapper);
-    c2wrapper->setProxyExtra(js::Int32Value(2));
+    js::SetProxyExtra(c2wrapper, js::Int32Value(2));
 
     JSObject *c3wrapper = wrap(cx, outerObj, compartment3);
     CHECK(c3wrapper);
-    c3wrapper->setProxyExtra(js::Int32Value(3));
+    js::SetProxyExtra(c3wrapper, js::Int32Value(3));
 
     JSObject *c4wrapper = wrap(cx, outerObj, compartment4);
     CHECK(c4wrapper);
-    c4wrapper->setProxyExtra(js::Int32Value(4));
+    js::SetProxyExtra(c4wrapper, js::Int32Value(4));
     compartment4 = c4wrapper = NULL;
 
     JSObject *next;
     {
         JSAutoEnterCompartment ac;
         CHECK(ac.enter(cx, compartment2));
         next = js::Wrapper::New(cx, compartment2, compartment2->getProto(), compartment2,
                                 &OuterWrapper::singleton);
--- a/js/src/jsapi-tests/testRegExpInstanceProperties.cpp
+++ b/js/src/jsapi-tests/testRegExpInstanceProperties.cpp
@@ -17,56 +17,56 @@ BEGIN_TEST(testRegExpInstanceProperties)
 
     JSObject *regexpProto = JSVAL_TO_OBJECT(regexpProtoVal);
 
     if (!helper(regexpProto))
         return false;
 
     JS_GC(cx);
 
-    CHECK_EQUAL(regexpProto->getCompartment()->initialRegExpShape, NULL);
+    CHECK_EQUAL(regexpProto->compartment()->initialRegExpShape, NULL);
 
     jsval regexp;
     EVAL("/foopy/", &regexp);
     JSObject *robj = JSVAL_TO_OBJECT(regexp);
 
     CHECK(robj->lastProperty());
-    CHECK_EQUAL(robj->getCompartment()->initialRegExpShape, robj->lastProperty());
+    CHECK_EQUAL(robj->compartment()->initialRegExpShape, robj->lastProperty());
 
     return true;
 }
 
 /*
  * Do this all in a nested function evaluation so as (hopefully) not to get
  * screwed up by the conservative stack scanner when GCing.
  */
 JS_NEVER_INLINE bool helper(JSObject *regexpProto)
 {
     CHECK(!regexpProto->inDictionaryMode());
 
     // Verify the compartment's cached shape is being used by RegExp.prototype.
     const js::Shape *shape = regexpProto->lastProperty();
     js::AutoShapeRooter root(cx, shape);
     for (js::Shape::Range r = shape;
-         &r.front() != regexpProto->getCompartment()->initialRegExpShape;
+         &r.front() != regexpProto->compartment()->initialRegExpShape;
          r.popFront())
     {
          CHECK(!r.empty());
     }
 
     jsval v = INT_TO_JSVAL(17);
     CHECK(JS_SetProperty(cx, regexpProto, "foopy", &v));
     v = INT_TO_JSVAL(42);
     CHECK(JS_SetProperty(cx, regexpProto, "bunky", &v));
     CHECK(JS_DeleteProperty(cx, regexpProto, "foopy"));
     CHECK(regexpProto->inDictionaryMode());
 
     const js::Shape *shape2 = regexpProto->lastProperty();
     js::AutoShapeRooter root2(cx, shape2);
     js::Shape::Range r2 = shape2;
     while (!r2.empty()) {
-        CHECK(&r2.front() != regexpProto->getCompartment()->initialRegExpShape);
+        CHECK(&r2.front() != regexpProto->compartment()->initialRegExpShape);
         r2.popFront();
     }
 
     return true;
 }
 END_TEST(testRegExpInstanceProperties)
--- a/js/src/jsapi-tests/testVersion.cpp
+++ b/js/src/jsapi-tests/testVersion.cpp
@@ -1,12 +1,14 @@
 #include "tests.h"
 #include "jsscript.h"
 #include "jscntxt.h"
 
+#include "jscntxtinlines.h"
+
 using namespace js;
 
 struct VersionFixture;
 
 /*
  * Fast-native callbacks for use from JS.
  * They set their results on the current fixture instance.
  */
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1319,17 +1319,17 @@ JS_LeaveCrossCompartmentCall(JSCrossComp
     realcall->leave();
     Foreground::delete_(realcall);
 }
 
 bool
 JSAutoEnterCompartment::enter(JSContext *cx, JSObject *target)
 {
     JS_ASSERT(!call);
-    if (cx->compartment == target->getCompartment()) {
+    if (cx->compartment == target->compartment()) {
         call = reinterpret_cast<JSCrossCompartmentCall*>(1);
         return true;
     }
     call = JS_EnterCrossCompartmentCall(cx, target);
     return call != NULL;
 }
 
 void
@@ -1397,22 +1397,22 @@ JS_WrapValue(JSContext *cx, jsval *vp)
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_TransplantObject(JSContext *cx, JSObject *origobj, JSObject *target)
 {
      // This function is called when an object moves between two
      // different compartments. In that case, we need to "move" the
      // window from origobj's compartment to target's compartment.
-    JSCompartment *destination = target->getCompartment();
+    JSCompartment *destination = target->compartment();
     WrapperMap &map = destination->crossCompartmentWrappers;
     Value origv = ObjectValue(*origobj);
     JSObject *obj;
 
-    if (origobj->getCompartment() == destination) {
+    if (origobj->compartment() == destination) {
         // If the original object is in the same compartment as the
         // destination, then we know that we won't find wrapper in the
         // destination's cross compartment map and that the same
         // object will continue to work.  Note the rare case where
         // |origobj == target|. In that case, we can just treat this
         // as a same compartment navigation. The effect is to clear
         // all of the wrappers and their holders if they have
         // them. This would be cleaner as a separate API.
@@ -1474,24 +1474,24 @@ JS_TransplantObject(JSContext *cx, JSObj
         // to the old wrapper.
         JS_ASSERT(tobj != wobj);
         if (!wobj->swap(cx, tobj))
             return NULL;
         pmap.put(targetv, ObjectValue(*wobj));
     }
 
     // Lastly, update the original object to point to the new one.
-    if (origobj->getCompartment() != destination) {
+    if (origobj->compartment() != destination) {
         AutoCompartment ac(cx, origobj);
         JSObject *tobj = obj;
         if (!ac.enter() || !JS_WrapObject(cx, &tobj))
             return NULL;
         if (!origobj->swap(cx, tobj))
             return NULL;
-        origobj->getCompartment()->crossCompartmentWrappers.put(targetv, origv);
+        origobj->compartment()->crossCompartmentWrappers.put(targetv, origv);
     }
 
     return obj;
 }
 
 /*
  * The location object is special. There is the location object itself and
  * then the location object wrapper. Because there are no direct references to
@@ -1503,17 +1503,17 @@ JS_TransplantObject(JSContext *cx, JSObj
 JS_FRIEND_API(JSObject *)
 js_TransplantObjectWithWrapper(JSContext *cx,
                                JSObject *origobj,
                                JSObject *origwrapper,
                                JSObject *targetobj,
                                JSObject *targetwrapper)
 {
     JSObject *obj;
-    JSCompartment *destination = targetobj->getCompartment();
+    JSCompartment *destination = targetobj->compartment();
     WrapperMap &map = destination->crossCompartmentWrappers;
 
     // |origv| is the map entry we're looking up. The map entries are going to
     // be for the location object itself.
     Value origv = ObjectValue(*origobj);
 
     // There might already be a wrapper for the original object in the new
     // compartment.
@@ -1578,18 +1578,18 @@ js_TransplantObjectWithWrapper(JSContext
     // itself, since all of the references are to the object itself.
     {
         AutoCompartment ac(cx, origobj);
         JSObject *tobj = obj;
         if (!ac.enter() || !JS_WrapObject(cx, &tobj))
             return NULL;
         if (!origwrapper->swap(cx, tobj))
             return NULL;
-        origwrapper->getCompartment()->crossCompartmentWrappers.put(targetv,
-                                                                    ObjectValue(*origwrapper));
+        origwrapper->compartment()->crossCompartmentWrappers.put(targetv,
+                                                                 ObjectValue(*origwrapper));
     }
 
     return obj;
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_GetGlobalObject(JSContext *cx)
 {
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -3936,17 +3936,17 @@ Call(JSContext *cx, JSObject *thisObj, j
 extern JS_PUBLIC_API(bool)
 Call(JSContext *cx, jsval thisv, jsval fun, uintN argc, jsval *argv, jsval *rval);
 
 static inline bool
 Call(JSContext *cx, jsval thisv, JSObject *funObj, uintN argc, jsval *argv, jsval *rval) {
     return Call(cx, thisv, OBJECT_TO_JSVAL(funObj), argc, argv, rval);
 }
 
-} /* namespace js */
+} /* namespace JS */
 
 JS_BEGIN_EXTERN_C
 #endif /* __cplusplus */
 
 /*
  * These functions allow setting an operation callback that will be called
  * from the thread the context is associated with some time after any thread
  * triggered the callback using JS_TriggerOperationCallback(cx).
--- a/js/src/jsatom.h
+++ b/js/src/jsatom.h
@@ -39,19 +39,19 @@
 
 #ifndef jsatom_h___
 #define jsatom_h___
 
 #include <stddef.h>
 #include "jsversion.h"
 #include "jsapi.h"
 #include "jsprvtd.h"
+#include "jshash.h"
 #include "jshashtable.h"
 #include "jspubtd.h"
-#include "jsstr.h"
 #include "jslock.h"
 
 #include "vm/String.h"
 
 /* Engine-internal extensions of jsid */
 
 static JS_ALWAYS_INLINE jsid
 JSID_FROM_BITS(size_t bits)
@@ -158,16 +158,26 @@ struct DefaultHasher<jsid>
  * Return a printable, lossless char[] representation of a string-type atom.
  * The lifetime of the result matches the lifetime of bytes.
  */
 extern const char *
 js_AtomToPrintableString(JSContext *cx, JSAtom *atom, JSAutoByteString *bytes);
 
 namespace js {
 
+/* Compute a hash function from chars/length. */
+inline uint32
+HashChars(const jschar *chars, size_t length)
+{
+    uint32 h = 0;
+    for (; length; chars++, length--)
+        h = JS_ROTATE_LEFT32(h, 4) ^ *chars;
+    return h;
+}
+
 typedef TaggedPointerEntry<JSAtom> AtomStateEntry;
 
 struct AtomHasher
 {
     struct Lookup
     {
         const jschar    *chars;
         size_t          length;
@@ -189,16 +199,39 @@ struct AtomHasher
         if (key->length() != lookup.length)
             return false;
         return PodEqual(key->chars(), lookup.chars, lookup.length);
     }
 };
 
 typedef HashSet<AtomStateEntry, AtomHasher, SystemAllocPolicy> AtomSet;
 
+/*
+ * On encodings:
+ *
+ * - Some string functions have an optional FlationCoding argument that allow
+ *   the caller to force CESU-8 encoding handling. 
+ * - Functions that don't take a FlationCoding base their NormalEncoding
+ *   behavior on the js_CStringsAreUTF8 value. NormalEncoding is either raw
+ *   (simple zero-extension) or UTF-8 depending on js_CStringsAreUTF8.
+ * - Functions that explicitly state their encoding do not use the
+ *   js_CStringsAreUTF8 value.
+ *
+ * CESU-8 (Compatibility Encoding Scheme for UTF-16: 8-bit) is a variant of
+ * UTF-8 that allows us to store any wide character string as a narrow
+ * character string. For strings containing mostly ascii, it saves space.
+ * http://www.unicode.org/reports/tr26/
+ */
+
+enum FlationCoding
+{
+    NormalEncoding,
+    CESU8Encoding
+};
+
 }  /* namespace js */
 
 struct JSAtomState
 {
     js::AtomSet         atoms;
 
 #ifdef JS_THREADSAFE
     JSThinLock          lock;
--- a/js/src/jsatominlines.h
+++ b/js/src/jsatominlines.h
@@ -40,16 +40,17 @@
 #ifndef jsatominlines_h___
 #define jsatominlines_h___
 
 #include "mozilla/RangedPtr.h"
 
 #include "jsatom.h"
 #include "jsnum.h"
 #include "jsobj.h"
+#include "jsstr.h"
 
 inline bool
 js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp)
 {
     if (!v.isString()) {
         JSString *str = js_ValueToString(cx, v);
         if (!str)
             return false;
--- a/js/src/jsbool.cpp
+++ b/js/src/jsbool.cpp
@@ -206,17 +206,17 @@ BooleanGetPrimitiveValueSlow(JSContext *
      * its [[Class]] is "Boolean". Boolean.prototype.valueOf is specified to
      * return the [[PrimitiveValue]] internal property, so call that instead.
      */
     InvokeArgsGuard args;
     if (!cx->stack.pushInvokeArgs(cx, 0, &args))
         return false;
     args.calleev().setUndefined();
     args.thisv().setObject(obj);
-    if (!obj.getProxyHandler()->nativeCall(cx, &obj, &BooleanClass, bool_valueOf, args))
+    if (!GetProxyHandler(&obj)->nativeCall(cx, &obj, &BooleanClass, bool_valueOf, args))
         return false;
     *vp = args.rval();
     return true;
 }
 
 }  /* namespace js */
 
 JSBool
--- a/js/src/jsclass.h
+++ b/js/src/jsclass.h
@@ -43,16 +43,18 @@
  * A JSClass acts as a vtable for JS objects that allows JSAPI clients to
  * control various aspects of the behavior of an object like property lookup.
  * js::Class is an engine-private extension that allows more control over
  * object behavior and, e.g., allows custom slow layout.
  */
 #include "jsapi.h"
 #include "jsprvtd.h"
 
+#ifdef __cplusplus
+
 namespace js {
 
 class AutoIdVector;
 class PropertyName;
 class SpecialId;
 
 static JS_ALWAYS_INLINE jsid
 SPECIALID_TO_JSID(const SpecialId &sid);
@@ -383,10 +385,28 @@ Jsvalify(Class *c)
 }
 
 static JS_ALWAYS_INLINE Class *
 Valueify(JSClass *c)
 {
     return (Class *)c;
 }
 
+/*
+ * Enumeration describing possible values of the [[Class]] internal property
+ * value of objects.
+ */
+enum ESClassValue { ESClass_Array, ESClass_Number, ESClass_String, ESClass_Boolean };
+
+/*
+ * Return whether the given object has the given [[Class]] internal property
+ * value. Beware, this query says nothing about the js::Class of the JSObject
+ * so the caller must not assume anything about obj's representation (e.g., obj
+ * may be a proxy).
+ */
+inline bool
+ObjectClassIs(JSObject &obj, ESClassValue classValue, JSContext *cx);
+
 }  /* namespace js */
+
+#endif  /* __cplusplus */
+
 #endif  /* jsclass_h__ */
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -1659,9 +1659,18 @@ CanLeaveTrace(JSContext *cx)
     JS_ASSERT(JS_ON_TRACE(cx));
 #ifdef JS_TRACER
     return JS_TRACE_MONITOR_ON_TRACE(cx)->bailExit != NULL;
 #else
     return false;
 #endif
 }
 
+AutoEnumStateRooter::~AutoEnumStateRooter()
+{
+    if (!stateValue.isNull()) {
+        DebugOnly<JSBool> ok =
+            obj->enumerate(context, JSENUMERATE_DESTROY, &stateValue, 0);
+        JS_ASSERT(ok);
+    }
+}
+
 } /* namespace js */
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -41,36 +41,31 @@
 #ifndef jscntxt_h___
 #define jscntxt_h___
 /*
  * JS execution context.
  */
 #include <string.h>
 
 #include "jsprvtd.h"
+#include "jsatom.h"
 #include "jsclist.h"
-#include "jsatom.h"
 #include "jsdhash.h"
-#include "jsfun.h"
 #include "jsgc.h"
 #include "jsgcchunk.h"
 #include "jshashtable.h"
-#include "jsinfer.h"
-#include "jsinterp.h"
-#include "jsobj.h"
 #include "jspropertycache.h"
 #include "jspropertytree.h"
 #include "jsstaticcheck.h"
 #include "jsutil.h"
 #include "jsvector.h"
 #include "prmjtime.h"
 
 #include "ds/LifoAlloc.h"
-#include "vm/Stack.h"
-#include "vm/String.h"
+#include "vm/StackSpace.h"
 
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable:4100) /* Silence unreferenced formal parameter warnings */
 #pragma warning(push)
 #pragma warning(disable:4355) /* Silence warning about "this" used in base member initializer list */
 #endif
 
@@ -85,16 +80,22 @@ template<typename K, typename V, typenam
 template<typename T> class Seq;
 
 }  /* namespace nanojit */
 
 JS_BEGIN_EXTERN_C
 struct DtoaState;
 JS_END_EXTERN_C
 
+struct JSSharpObjectMap {
+    jsrefcount  depth;
+    uint32      sharpgen;
+    JSHashTable *table;
+};
+
 namespace js {
 
 /* Tracer constants. */
 static const size_t MONITOR_N_GLOBAL_STATES = 4;
 static const size_t FRAGMENT_TABLE_SIZE = 512;
 static const size_t MAX_GLOBAL_SLOTS = 4096;
 static const size_t GLOBAL_SLOTS_BUFFER_SIZE = MAX_GLOBAL_SLOTS + 1;
 
@@ -104,16 +105,17 @@ class FrameInfoCache;
 struct FrameInfo;
 struct VMSideExit;
 struct TreeFragment;
 struct TracerState;
 template<typename T> class Queue;
 typedef Queue<uint16> SlotList;
 class TypeMap;
 class LoopProfile;
+class InterpreterFrames;
 
 #if defined(JS_JIT_SPEW) || defined(DEBUG)
 struct FragPI;
 typedef nanojit::HashMap<uint32, FragPI, nanojit::DefaultHash<uint32> > FragStatsMap;
 #endif
 
 namespace mjit {
 class JaegerCompartment;
@@ -1003,21 +1005,21 @@ struct JSContext
     void setThread(JSThread *thread);
     static const size_t threadOffset() { return offsetof(JSContext, thread_); }
 #endif
 
     /* Current execution stack. */
     js::ContextStack    stack;
 
     /* ContextStack convenience functions */
-    bool hasfp() const                { return stack.hasfp(); }
-    js::StackFrame* fp() const        { return stack.fp(); }
-    js::StackFrame* maybefp() const   { return stack.maybefp(); }
-    js::FrameRegs& regs() const       { return stack.regs(); }
-    js::FrameRegs* maybeRegs() const  { return stack.maybeRegs(); }
+    inline bool hasfp() const;
+    inline js::StackFrame* fp() const;
+    inline js::StackFrame* maybefp() const;
+    inline js::FrameRegs& regs() const;
+    inline js::FrameRegs* maybeRegs() const;
 
     /* Set cx->compartment based on the current scope chain. */
     void resetCompartment();
 
     /* Wrap cx->exception for the current compartment. */
     void wrapPendingException();
 
   private:
@@ -1057,26 +1059,20 @@ struct JSContext
     }
 
     inline bool ensureParseMapPool();
 
     /*
      * The default script compilation version can be set iff there is no code running.
      * This typically occurs via the JSAPI right after a context is constructed.
      */
-    bool canSetDefaultVersion() const {
-        return !stack.hasfp() && !hasVersionOverride;
-    }
+    inline bool canSetDefaultVersion() const;
 
     /* Force a version for future script compilation. */
-    void overrideVersion(JSVersion newVersion) {
-        JS_ASSERT(!canSetDefaultVersion());
-        versionOverride = newVersion;
-        hasVersionOverride = true;
-    }
+    inline void overrideVersion(JSVersion newVersion);
 
     /* Set the default script compilation version. */
     void setDefaultVersion(JSVersion version) {
         defaultVersion = version;
     }
 
     void clearVersionOverride() { hasVersionOverride = false; }
     JSVersion getDefaultVersion() const { return defaultVersion; }
@@ -1086,24 +1082,17 @@ struct JSContext
         JS_ASSERT(isVersionOverridden());
         return versionOverride;
     }
 
     /*
      * Set the default version if possible; otherwise, force the version.
      * Return whether an override occurred.
      */
-    bool maybeOverrideVersion(JSVersion newVersion) {
-        if (canSetDefaultVersion()) {
-            setDefaultVersion(newVersion);
-            return false;
-        }
-        overrideVersion(newVersion);
-        return true;
-    }
+    inline bool maybeOverrideVersion(JSVersion newVersion);
 
     /*
      * If there is no code on the stack, turn the override version into the
      * default version.
      */
     void maybeMigrateVersionOverride() {
         JS_ASSERT(stack.empty());
         if (JS_UNLIKELY(isVersionOverridden())) {
@@ -1115,50 +1104,29 @@ struct JSContext
     /*
      * Return:
      * - The override version, if there is an override version.
      * - The newest scripted frame's version, if there is such a frame.
      * - The default version.
      *
      * Note: if this ever shows up in a profile, just add caching!
      */
-    JSVersion findVersion() const {
-        if (hasVersionOverride)
-            return versionOverride;
-
-        if (stack.hasfp()) {
-            /* There may be a scripted function somewhere on the stack! */
-            js::StackFrame *f = fp();
-            while (f && !f->isScriptFrame())
-                f = f->prev();
-            if (f)
-                return f->script()->getVersion();
-        }
-
-        return defaultVersion;
-    }
+    inline JSVersion findVersion() const;
 
     void setRunOptions(uintN ropts) {
         JS_ASSERT((ropts & JSRUNOPTION_MASK) == ropts);
         runOptions = ropts;
     }
 
     /* Note: may override the version. */
-    void setCompileOptions(uintN newcopts) {
-        JS_ASSERT((newcopts & JSCOMPILEOPTION_MASK) == newcopts);
-        if (JS_LIKELY(getCompileOptions() == newcopts))
-            return;
-        JSVersion version = findVersion();
-        JSVersion newVersion = js::OptionFlagsToVersion(newcopts, version);
-        maybeOverrideVersion(newVersion);
-    }
+    inline void setCompileOptions(uintN newcopts);
 
     uintN getRunOptions() const { return runOptions; }
-    uintN getCompileOptions() const { return js::VersionFlagsToOptions(findVersion()); }
-    uintN allOptions() const { return getRunOptions() | getCompileOptions(); }
+    inline uintN getCompileOptions() const;
+    inline uintN allOptions() const;
 
     bool hasRunOption(uintN ropt) const {
         JS_ASSERT((ropt & JSRUNOPTION_MASK) == ropt);
         return !!(runOptions & ropt);
     }
 
     bool hasStrictOption() const { return hasRunOption(JSOPTION_STRICT); }
     bool hasWErrorOption() const { return hasRunOption(JSOPTION_WERROR); }
@@ -1303,24 +1271,18 @@ struct JSContext
         runtime->free_(p);
     }
 
     JS_DECLARE_NEW_METHODS(malloc_, inline)
     JS_DECLARE_DELETE_METHODS(free_, inline)
 
     void purge();
 
-#ifdef DEBUG
-    void assertValidStackDepth(uintN depth) {
-        JS_ASSERT(0 <= regs().sp - fp()->base());
-        JS_ASSERT(depth <= uintptr_t(regs().sp - fp()->base()));
-    }
-#else
-    void assertValidStackDepth(uintN /*depth*/) {}
-#endif
+    /* For DEBUG. */
+    inline void assertValidStackDepth(uintN depth);
 
     bool isExceptionPending() {
         return throwing;
     }
 
     js::Value getPendingException() {
         JS_ASSERT(throwing);
         return exception;
@@ -1400,24 +1362,16 @@ class AutoCheckRequestDepth {
     JS_ASSERT((cx)->thread()->data.requestDepth || (cx)->thread() == (cx)->runtime->gcThread); \
     AutoCheckRequestDepth _autoCheckRequestDepth(cx);
 
 #else
 # define CHECK_REQUEST(cx)          ((void) 0)
 # define CHECK_REQUEST_THREAD(cx)   ((void) 0)
 #endif
 
-static inline JSAtom **
-FrameAtomBase(JSContext *cx, js::StackFrame *fp)
-{
-    return fp->hasImacropc()
-           ? cx->runtime->atomState.commonAtomsStart()
-           : fp->script()->atoms;
-}
-
 struct AutoResolving {
   public:
     enum Kind {
         LOOKUP,
         WATCH
     };
 
     AutoResolving(JSContext *cx, JSObject *obj, jsid id, Kind kind = LOOKUP
@@ -1734,23 +1688,17 @@ class AutoEnumStateRooter : private Auto
     AutoEnumStateRooter(JSContext *cx, JSObject *obj
                         JS_GUARD_OBJECT_NOTIFIER_PARAM)
       : AutoGCRooter(cx, ENUMERATOR), obj(obj), stateValue()
     {
         JS_GUARD_OBJECT_NOTIFIER_INIT;
         JS_ASSERT(obj);
     }
 
-    ~AutoEnumStateRooter() {
-        if (!stateValue.isNull()) {
-            DebugOnly<JSBool> ok =
-                obj->enumerate(context, JSENUMERATE_DESTROY, &stateValue, 0);
-            JS_ASSERT(ok);
-        }
-    }
+    ~AutoEnumStateRooter();
 
     friend void AutoGCRooter::trace(JSTracer *trc);
 
     const Value &state() const { return stateValue; }
     Value *addr() { return &stateValue; }
 
   protected:
     void trace(JSTracer *trc);
@@ -2322,35 +2270,16 @@ namespace mjit {
 } /* namespace js */
 
 /* How much expansion of inlined frames to do when inspecting the stack. */
 enum FrameExpandKind {
     FRAME_EXPAND_NONE = 0,
     FRAME_EXPAND_ALL = 1
 };
 
-/*
- * Get the current frame, first lazily instantiating stack frames if needed.
- * (Do not access cx->fp() directly except in JS_REQUIRES_STACK code.)
- *
- * LeaveTrace is defined in jstracer.cpp if JS_TRACER is defined.
- */
-static JS_FORCES_STACK JS_INLINE js::StackFrame *
-js_GetTopStackFrame(JSContext *cx, FrameExpandKind expand)
-{
-    js::LeaveTrace(cx);
-
-#ifdef JS_METHODJIT
-    if (expand)
-        js::mjit::ExpandInlineFrames(cx->compartment);
-#endif
-
-    return cx->maybefp();
-}
-
 static JS_INLINE JSBool
 js_IsPropertyCacheDisabled(JSContext *cx)
 {
     return cx->runtime->shapeGen >= js::SHAPE_OVERFLOW_BIT;
 }
 
 static JS_INLINE uint32
 js_RegenerateShapeForGC(JSRuntime *rt)
@@ -2366,16 +2295,93 @@ js_RegenerateShapeForGC(JSRuntime *rt)
     uint32 shape = rt->shapeGen;
     shape = (shape + 1) | (shape & js::SHAPE_OVERFLOW_BIT);
     rt->shapeGen = shape;
     return shape;
 }
 
 namespace js {
 
+/************************************************************************/
+
+static JS_ALWAYS_INLINE void
+ClearValueRange(Value *vec, uintN len, bool useHoles)
+{
+    if (useHoles) {
+        for (uintN i = 0; i < len; i++)
+            vec[i].setMagic(JS_ARRAY_HOLE);
+    } else {
+        for (uintN i = 0; i < len; i++)
+            vec[i].setUndefined();
+    }
+}
+
+static JS_ALWAYS_INLINE void
+MakeRangeGCSafe(Value *vec, size_t len)
+{
+    PodZero(vec, len);
+}
+
+static JS_ALWAYS_INLINE void
+MakeRangeGCSafe(Value *beg, Value *end)
+{
+    PodZero(beg, end - beg);
+}
+
+static JS_ALWAYS_INLINE void
+MakeRangeGCSafe(jsid *beg, jsid *end)
+{
+    for (jsid *id = beg; id != end; ++id)
+        *id = INT_TO_JSID(0);
+}
+
+static JS_ALWAYS_INLINE void
+MakeRangeGCSafe(jsid *vec, size_t len)
+{
+    MakeRangeGCSafe(vec, vec + len);
+}
+
+static JS_ALWAYS_INLINE void
+MakeRangeGCSafe(const Shape **beg, const Shape **end)
+{
+    PodZero(beg, end - beg);
+}
+
+static JS_ALWAYS_INLINE void
+MakeRangeGCSafe(const Shape **vec, size_t len)
+{
+    PodZero(vec, len);
+}
+
+static JS_ALWAYS_INLINE void
+SetValueRangeToUndefined(Value *beg, Value *end)
+{
+    for (Value *v = beg; v != end; ++v)
+        v->setUndefined();
+}
+
+static JS_ALWAYS_INLINE void
+SetValueRangeToUndefined(Value *vec, size_t len)
+{
+    SetValueRangeToUndefined(vec, vec + len);
+}
+
+static JS_ALWAYS_INLINE void
+SetValueRangeToNull(Value *beg, Value *end)
+{
+    for (Value *v = beg; v != end; ++v)
+        v->setNull();
+}
+
+static JS_ALWAYS_INLINE void
+SetValueRangeToNull(Value *vec, size_t len)
+{
+    SetValueRangeToNull(vec, vec + len);
+}
+
 template<class T>
 class AutoVectorRooter : protected AutoGCRooter
 {
   public:
     explicit AutoVectorRooter(JSContext *cx, ptrdiff_t tag
                               JS_GUARD_OBJECT_NOTIFIER_PARAM)
         : AutoGCRooter(cx, tag), vector(cx)
     {
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -38,16 +38,18 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef jscntxtinlines_h___
 #define jscntxtinlines_h___
 
 #include "jscntxt.h"
 #include "jscompartment.h"
+#include "jsfriendapi.h"
+#include "jsinterp.h"
 #include "jsstaticcheck.h"
 #include "jsxml.h"
 #include "jsregexp.h"
 #include "jsgc.h"
 
 #include "frontend/ParseMaps.h"
 
 namespace js {
@@ -82,18 +84,18 @@ GetGlobalForScopeChain(JSContext *cx)
      * cx->fp->scopeChain->getGlobal() returns the same object whether we're on
      * trace or not, since we do not trace calls across global objects.
      */
     VOUCH_DOES_NOT_REQUIRE_STACK();
 
     if (cx->hasfp())
         return cx->fp()->scopeChain().getGlobal();
 
-    JSObject *scope = cx->globalObject;
-    if (!NULLABLE_OBJ_TO_INNER_OBJECT(cx, scope))
+    JSObject *scope = JS_ObjectToInnerObject(cx, cx->globalObject);
+    if (!scope)
         return NULL;
     return scope->asGlobal();
 }
 
 inline GSNCache *
 GetGSNCache(JSContext *cx)
 {
     return &JS_THREAD_DATA(cx)->gsnCache;
@@ -393,18 +395,95 @@ LeaveTraceIfGlobalObject(JSContext *cx, 
 
 static JS_INLINE void
 LeaveTraceIfArgumentsObject(JSContext *cx, JSObject *obj)
 {
     if (obj->isArguments())
         LeaveTrace(cx);
 }
 
+static inline JSAtom **
+FrameAtomBase(JSContext *cx, js::StackFrame *fp)
+{
+    return fp->hasImacropc()
+           ? cx->runtime->atomState.commonAtomsStart()
+           : fp->script()->atoms;
+}
+
 }  /* namespace js */
 
+inline JSVersion
+JSContext::findVersion() const
+{
+    if (hasVersionOverride)
+        return versionOverride;
+
+    if (stack.hasfp()) {
+        /* There may be a scripted function somewhere on the stack! */
+        js::StackFrame *f = fp();
+        while (f && !f->isScriptFrame())
+            f = f->prev();
+        if (f)
+            return f->script()->getVersion();
+    }
+
+    return defaultVersion;
+}
+
+inline bool
+JSContext::canSetDefaultVersion() const
+{
+    return !stack.hasfp() && !hasVersionOverride;
+}
+
+inline void
+JSContext::overrideVersion(JSVersion newVersion)
+{
+    JS_ASSERT(!canSetDefaultVersion());
+    versionOverride = newVersion;
+    hasVersionOverride = true;
+}
+
+inline bool
+JSContext::maybeOverrideVersion(JSVersion newVersion)
+{
+    if (canSetDefaultVersion()) {
+        setDefaultVersion(newVersion);
+        return false;
+    }
+    overrideVersion(newVersion);
+    return true;
+}
+
+inline uintN
+JSContext::getCompileOptions() const { return js::VersionFlagsToOptions(findVersion()); }
+
+inline uintN
+JSContext::allOptions() const { return getRunOptions() | getCompileOptions(); }
+
+inline void
+JSContext::setCompileOptions(uintN newcopts)
+{
+    JS_ASSERT((newcopts & JSCOMPILEOPTION_MASK) == newcopts);
+    if (JS_LIKELY(getCompileOptions() == newcopts))
+        return;
+    JSVersion version = findVersion();
+    JSVersion newVersion = js::OptionFlagsToVersion(newcopts, version);
+    maybeOverrideVersion(newVersion);
+}
+
+inline void
+JSContext::assertValidStackDepth(uintN depth)
+{
+#ifdef DEBUG
+    JS_ASSERT(0 <= regs().sp - fp()->base());
+    JS_ASSERT(depth <= uintptr_t(regs().sp - fp()->base()));
+#endif
+}
+
 #ifdef JS_METHODJIT
 inline js::mjit::JaegerCompartment *JSContext::jaegerCompartment()
 {
     return compartment->jaegerCompartment();
 }
 #endif
 
 inline js::LifoAlloc &
@@ -439,9 +518,28 @@ inline bool
 JSContext::ensureParseMapPool()
 {
     if (parseMapPool_)
         return true;
     parseMapPool_ = js::OffTheBooks::new_<js::ParseMapPool>(this);
     return parseMapPool_;
 }
 
+/*
+ * Get the current frame, first lazily instantiating stack frames if needed.
+ * (Do not access cx->fp() directly except in JS_REQUIRES_STACK code.)
+ *
+ * LeaveTrace is defined in jstracer.cpp if JS_TRACER is defined.
+ */
+static JS_FORCES_STACK JS_INLINE js::StackFrame *
+js_GetTopStackFrame(JSContext *cx, FrameExpandKind expand)
+{
+    js::LeaveTrace(cx);
+
+#ifdef JS_METHODJIT
+    if (expand)
+        js::mjit::ExpandInlineFrames(cx->compartment);
+#endif
+
+    return cx->maybefp();
+}
+
 #endif /* jscntxtinlines_h___ */
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -175,23 +175,16 @@ JSCompartment::getMjitCodeStats(size_t& 
     } else {
         method = 0;
         regexp = 0;
         unused = 0;
     }
 }
 #endif
 
-static bool
-IsCrossCompartmentWrapper(JSObject *wrapper)
-{
-    return wrapper->isWrapper() &&
-           !!(Wrapper::wrapperHandler(wrapper)->flags() & Wrapper::CROSS_COMPARTMENT);
-}
-
 bool
 JSCompartment::wrap(JSContext *cx, Value *vp)
 {
     JS_ASSERT(cx->compartment == this);
 
     uintN flags = 0;
 
     JS_CHECK_RECURSION(cx, return false);
@@ -220,18 +213,18 @@ JSCompartment::wrap(JSContext *cx, Value
      * parent without being a proper global object (JSCLASS_IS_GLOBAL). Instead,
      * we parent all wrappers to the global object in their home compartment.
      * This loses us some transparency, and is generally very cheesy.
      */
     JSObject *global;
     if (cx->hasfp()) {
         global = cx->fp()->scopeChain().getGlobal();
     } else {
-        global = cx->globalObject;
-        if (!NULLABLE_OBJ_TO_INNER_OBJECT(cx, global))
+        global = JS_ObjectToInnerObject(cx, cx->globalObject);
+        if (!global)
             return false;
     }
 
     /* Unwrap incoming objects. */
     if (vp->isObject()) {
         JSObject *obj = &vp->toObject();
 
         /* If the object is already in this compartment, we are done. */
@@ -239,29 +232,29 @@ JSCompartment::wrap(JSContext *cx, Value
             return true;
 
         /* Translate StopIteration singleton. */
         if (obj->isStopIteration())
             return js_FindClassObject(cx, NULL, JSProto_StopIteration, vp);
 
         /* Don't unwrap an outer window proxy. */
         if (!obj->getClass()->ext.innerObject) {
-            obj = vp->toObject().unwrap(&flags);
+            obj = UnwrapObject(&vp->toObject(), &flags);
             vp->setObject(*obj);
-            if (obj->getCompartment() == this)
+            if (obj->compartment() == this)
                 return true;
 
             if (cx->runtime->preWrapObjectCallback) {
                 obj = cx->runtime->preWrapObjectCallback(cx, global, obj, flags);
                 if (!obj)
                     return false;
             }
 
             vp->setObject(*obj);
-            if (obj->getCompartment() == this)
+            if (obj->compartment() == this)
                 return true;
         } else {
             if (cx->runtime->preWrapObjectCallback) {
                 obj = cx->runtime->preWrapObjectCallback(cx, global, obj, flags);
                 if (!obj)
                     return false;
             }
 
@@ -278,22 +271,22 @@ JSCompartment::wrap(JSContext *cx, Value
 #endif
     }
 
     /* If we already have a wrapper for this value, use it. */
     if (WrapperMap::Ptr p = crossCompartmentWrappers.lookup(*vp)) {
         *vp = p->value;
         if (vp->isObject()) {
             JSObject *obj = &vp->toObject();
-            JS_ASSERT(IsCrossCompartmentWrapper(obj));
+            JS_ASSERT(obj->isCrossCompartmentWrapper());
             if (global->getJSClass() != &js_dummy_class && obj->getParent() != global) {
                 do {
                     obj->setParent(global);
                     obj = obj->getProto();
-                } while (obj && IsCrossCompartmentWrapper(obj));
+                } while (obj && obj->isCrossCompartmentWrapper());
             }
         }
         return true;
     }
 
     if (vp->isString()) {
         Value orig = *vp;
         JSString *str = vp->toString();
@@ -332,17 +325,17 @@ JSCompartment::wrap(JSContext *cx, Value
     if (!wrapper)
         return false;
 
     vp->setObject(*wrapper);
 
     if (wrapper->getProto() != proto && !SetProto(cx, wrapper, proto, false))
         return false;
 
-    if (!crossCompartmentWrappers.put(wrapper->getProxyPrivate(), *vp))
+    if (!crossCompartmentWrappers.put(GetProxyPrivate(wrapper), *vp))
         return false;
 
     wrapper->setParent(global);
     return true;
 }
 
 bool
 JSCompartment::wrap(JSContext *cx, JSString **strp)
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -748,17 +748,17 @@ class SwitchToCompartment : public Prese
         JS_GUARD_OBJECT_NOTIFIER_INIT;
         cx->setCompartment(newCompartment);
     }
 
     SwitchToCompartment(JSContext *cx, JSObject *target JS_GUARD_OBJECT_NOTIFIER_PARAM)
         : PreserveCompartment(cx)
     {
         JS_GUARD_OBJECT_NOTIFIER_INIT;
-        cx->setCompartment(target->getCompartment());
+        cx->setCompartment(target->compartment());
     }
 
     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 class AssertCompartmentUnchanged {
   protected:
     JSContext * const cx;
@@ -770,11 +770,52 @@ class AssertCompartmentUnchanged {
         JS_GUARD_OBJECT_NOTIFIER_INIT;
     }
 
     ~AssertCompartmentUnchanged() {
         JS_ASSERT(cx->compartment == oldCompartment);
     }
 };
 
-}
+class AutoCompartment
+{
+  public:
+    JSContext * const context;
+    JSCompartment * const origin;
+    JSObject * const target;
+    JSCompartment * const destination;
+  private:
+    Maybe<DummyFrameGuard> frame;
+    bool entered;
+
+  public:
+    AutoCompartment(JSContext *cx, JSObject *target);
+    ~AutoCompartment();
+
+    bool enter();
+    void leave();
+
+  private:
+    // Prohibit copying.
+    AutoCompartment(const AutoCompartment &);
+    AutoCompartment & operator=(const AutoCompartment &);
+};
+
+/*
+ * Use this to change the behavior of an AutoCompartment slightly on error. If
+ * the exception happens to be an Error object, copy it to the origin compartment
+ * instead of wrapping it.
+ */
+class ErrorCopier
+{
+    AutoCompartment &ac;
+    JSObject *scope;
+
+  public:
+    ErrorCopier(AutoCompartment &ac, JSObject *scope) : ac(ac), scope(scope) {
+        JS_ASSERT(scope->compartment() == ac.origin);
+    }
+    ~ErrorCopier();
+};
+
+} /* namespace js */
 
 #endif /* jscompartment_h___ */
--- a/js/src/jsdate.h
+++ b/js/src/jsdate.h
@@ -39,17 +39,17 @@
 
 /*
  * JS Date class interface.
  */
 
 #ifndef jsdate_h___
 #define jsdate_h___
 
-#include "jsobj.h"
+#include "jscntxt.h"
 
 #define HalfTimeDomain  8.64e15
 
 #define TIMECLIP(d) ((JSDOUBLE_IS_FINITE(d) \
                       && !((d < 0 ? -d : d) > HalfTimeDomain)) \
                      ? js_DoubleToInteger(d + (+0.)) : js_NaN)
 
 extern JSObject *
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -2187,8 +2187,14 @@ DumpBytecodeScriptCallback(JSContext *cx
     JS_DumpBytecode(cx, script);
 }
 
 JS_PUBLIC_API(void)
 JS_DumpCompartmentBytecode(JSContext *cx)
 {
     IterateCells(cx, cx->compartment, gc::FINALIZE_SCRIPT, NULL, DumpBytecodeScriptCallback);
 }
+
+JS_PUBLIC_API(JSObject *)
+JS_UnwrapObject(JSObject *obj)
+{
+    return UnwrapObject(obj);
+}
--- a/js/src/jsdbgapi.h
+++ b/js/src/jsdbgapi.h
@@ -82,16 +82,26 @@ class JS_PUBLIC_API(AutoEnterScriptCompa
 class JS_PUBLIC_API(AutoEnterFrameCompartment) : public AutoEnterScriptCompartment
 {
   public:
     bool enter(JSContext *cx, JSStackFrame *target);
 };
 
 } /* namespace JS */
 
+#ifdef DEBUG
+JS_FRIEND_API(void) js_DumpChars(const jschar *s, size_t n);
+JS_FRIEND_API(void) js_DumpString(JSString *str);
+JS_FRIEND_API(void) js_DumpAtom(JSAtom *atom);
+JS_FRIEND_API(void) js_DumpObject(JSObject *obj);
+JS_FRIEND_API(void) js_DumpValue(const js::Value &val);
+JS_FRIEND_API(void) js_DumpId(jsid id);
+JS_FRIEND_API(void) js_DumpStackFrame(JSContext *cx, js::StackFrame *start = NULL);
+#endif
+
 JS_BEGIN_EXTERN_C
 #endif
 
 extern JS_PUBLIC_API(JSString *)
 JS_DecompileScript(JSContext *cx, JSScript *script, const char *name, uintN indent);
 
 /*
  * Currently, we only support runtime-wide debugging. In the future, we should
@@ -609,11 +619,14 @@ JS_GetFunctionCallback(JSContext *cx);
 #endif /* MOZ_TRACE_JSCALLS */
 
 extern JS_PUBLIC_API(void)
 JS_DumpBytecode(JSContext *cx, JSScript *script);
 
 extern JS_PUBLIC_API(void)
 JS_DumpCompartmentBytecode(JSContext *cx);
 
+extern JS_PUBLIC_API(JSObject *)
+JS_UnwrapObject(JSObject *obj);
+
 JS_END_EXTERN_C
 
 #endif /* jsdbgapi_h___ */
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -35,16 +35,17 @@
  * 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 "jscompartment.h"
 #include "jsfriendapi.h"
+#include "jswrapper.h"
 
 #include "jsobjinlines.h"
 
 using namespace js;
 using namespace JS;
 
 JS_FRIEND_API(JSString *)
 JS_GetAnonymousString(JSRuntime *rt)
@@ -56,31 +57,33 @@ JS_GetAnonymousString(JSRuntime *rt)
 JS_FRIEND_API(JSObject *)
 JS_FindCompilationScope(JSContext *cx, JSObject *obj)
 {
     /*
      * We unwrap wrappers here. This is a little weird, but it's what's being
      * asked of us.
      */
     if (obj->isWrapper())
-        obj = obj->unwrap();
+        obj = UnwrapObject(obj);
     
     /*
      * Innerize the target_obj so that we compile in the correct (inner)
      * scope.
      */
     if (JSObjectOp op = obj->getClass()->ext.innerObject)
         obj = op(cx, obj);
     return obj;
 }
 
-JS_FRIEND_API(JSObject *)
-JS_UnwrapObject(JSObject *obj)
+JS_FRIEND_API(JSFunction *)
+JS_GetObjectFunction(JSObject *obj)
 {
-    return obj->unwrap();
+    if (obj->isFunction())
+        return obj->getFunctionPrivate();
+    return NULL;
 }
 
 JS_FRIEND_API(JSObject *)
 JS_GetFrameScopeChainRaw(JSStackFrame *fp)
 {
     return &Valueify(fp)->scopeChain();
 }
 
@@ -164,16 +167,25 @@ AutoSwitchCompartment::AutoSwitchCompart
 }
 
 AutoSwitchCompartment::~AutoSwitchCompartment()
 {
     /* The old compartment may have been destroyed, so we can't use cx->setCompartment. */
     cx->compartment = oldCompartment;
 }
 
+#ifdef DEBUG
+JS_FRIEND_API(void)
+js::CheckReservedSlot(const JSObject *obj, size_t slot)
+{
+    JS_ASSERT(slot < obj->numSlots());
+    JS_ASSERT(slot < JSSLOT_FREE(obj->getClass()));
+}
+#endif
+
 /*
  * The below code is for temporary telemetry use. It can be removed when
  * sufficient data has been harvested.
  */
 
 extern size_t sE4XObjectsCreated;
 
 JS_FRIEND_API(size_t)
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -35,29 +35,30 @@
  * 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 jsfriendapi_h___
 #define jsfriendapi_h___
 
+#include "jsclass.h"
 #include "jspubtd.h"
 #include "jsprvtd.h"
 
 JS_BEGIN_EXTERN_C
 
 extern JS_FRIEND_API(JSString *)
 JS_GetAnonymousString(JSRuntime *rt);
 
 extern JS_FRIEND_API(JSObject *)
 JS_FindCompilationScope(JSContext *cx, JSObject *obj);
 
-extern JS_FRIEND_API(JSObject *)
-JS_UnwrapObject(JSObject *obj);
+extern JS_FRIEND_API(JSFunction *)
+JS_GetObjectFunction(JSObject *obj);
 
 extern JS_FRIEND_API(JSObject *)
 JS_GetFrameScopeChainRaw(JSStackFrame *fp);
 
 extern JS_FRIEND_API(JSBool)
 JS_SplicePrototype(JSContext *cx, JSObject *obj, JSObject *proto);
 
 extern JS_FRIEND_API(JSObject *)
@@ -91,28 +92,48 @@ JS_GetTypeInferenceMemoryStats(JSContext
 
 extern JS_FRIEND_API(void)
 JS_GetTypeInferenceObjectStats(/*TypeObject*/ void *object,
                                TypeInferenceMemoryStats *stats);
 
 extern JS_FRIEND_API(JSPrincipals *)
 JS_GetCompartmentPrincipals(JSCompartment *compartment);
 
+/* Safe to call with input obj == NULL. Returns non-NULL iff obj != NULL. */
+extern JS_FRIEND_API(JSObject *)
+JS_ObjectToInnerObject(JSContext *cx, JSObject *obj);
+
+/* Requires obj != NULL. */
+extern JS_FRIEND_API(JSObject *)
+JS_ObjectToOuterObject(JSContext *cx, JSObject *obj);
+
+extern JS_FRIEND_API(JSObject *)
+JS_CloneObject(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent);
+
+extern JS_FRIEND_API(JSBool)
+js_GetterOnlyPropertyStub(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp);
+
 #ifdef __cplusplus
 
+extern JS_FRIEND_API(bool)
+JS_CopyPropertiesFrom(JSContext *cx, JSObject *target, JSObject *obj);
+
 extern JS_FRIEND_API(JSBool)
 JS_WrapPropertyDescriptor(JSContext *cx, js::PropertyDescriptor *desc);
 
+extern JS_FRIEND_API(JSBool)
+JS_EnumerateState(JSContext *cx, JSObject *obj, JSIterateOp enum_op, js::Value *statep, jsid *idp);
+
 #endif
 
 JS_END_EXTERN_C
 
 #ifdef __cplusplus
 
-namespace JS {
+namespace js {
 
 class JS_FRIEND_API(AutoPreserveCompartment) {
   private:
     JSContext *cx;
     JSCompartment *oldCompartment;
   public:
     AutoPreserveCompartment(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM);
     ~AutoPreserveCompartment();
@@ -126,12 +147,158 @@ class JS_FRIEND_API(AutoSwitchCompartmen
   public:
     AutoSwitchCompartment(JSContext *cx, JSCompartment *newCompartment
                           JS_GUARD_OBJECT_NOTIFIER_PARAM);
     AutoSwitchCompartment(JSContext *cx, JSObject *target JS_GUARD_OBJECT_NOTIFIER_PARAM);
     ~AutoSwitchCompartment();
     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
+#ifdef OLD_GETTER_SETTER_METHODS
+JS_FRIEND_API(JSBool) obj_defineGetter(JSContext *cx, uintN argc, js::Value *vp);
+JS_FRIEND_API(JSBool) obj_defineSetter(JSContext *cx, uintN argc, js::Value *vp);
+#endif
+
+/*
+ * Check whether it is OK to assign an undeclared property with name
+ * propname of the global object in the current script on cx.  Reports
+ * an error if one needs to be reported (in particular in all cases
+ * when it returns false).
+ */
+extern JS_FRIEND_API(bool)
+CheckUndeclaredVarAssignment(JSContext *cx, JSString *propname);
+
+/*
+ * Shadow declarations of JS internal structures, for access by inline access
+ * functions below. Do not use these structures in any other way. When adding
+ * new fields for access by inline methods, make sure to add static asserts to
+ * the original header file to ensure that offsets are consistent.
+ */
+namespace shadow {
+
+struct TypeObject {
+    JSObject    *proto;
+};
+
+struct Object {
+    void        *_1;
+    js::Class   *clasp;
+    uint32      flags;
+    uint32      _3;
+    void        *_4;
+    JSObject    *parent;
+    void        *privateData;
+    jsuword     _5;
+    js::Value   *slots;
+    TypeObject  *type;
+
+    static const uint32 FIXED_SLOTS_SHIFT = 27;
+
+    js::Value &slotRef(size_t slot) const {
+        size_t nfixed = flags >> FIXED_SLOTS_SHIFT;
+        if (slot < nfixed)
+            return ((Value *)((jsuword) this + sizeof(shadow::Object)))[slot];
+        return slots[slot - nfixed];
+    }
+};
+
+} /* namespace shadow */
+
+extern JS_FRIEND_DATA(js::Class) AnyNameClass;
+extern JS_FRIEND_DATA(js::Class) AttributeNameClass;
+extern JS_FRIEND_DATA(js::Class) CallClass;
+extern JS_FRIEND_DATA(js::Class) DeclEnvClass;
+extern JS_FRIEND_DATA(js::Class) FunctionClass;
+extern JS_FRIEND_DATA(js::Class) FunctionProxyClass;
+extern JS_FRIEND_DATA(js::Class) NamespaceClass;
+extern JS_FRIEND_DATA(js::Class) OuterWindowProxyClass;
+extern JS_FRIEND_DATA(js::Class) ObjectProxyClass;
+extern JS_FRIEND_DATA(js::Class) QNameClass;
+extern JS_FRIEND_DATA(js::Class) ScriptClass;
+extern JS_FRIEND_DATA(js::Class) XMLClass;
+
+inline js::Class *
+GetObjectClass(const JSObject *obj)
+{
+    return reinterpret_cast<const shadow::Object*>(obj)->clasp;
 }
+
+inline JSClass *
+GetObjectJSClass(const JSObject *obj)
+{
+    return js::Jsvalify(GetObjectClass(obj));
+}
+
+inline JSObject *
+GetObjectParent(const JSObject *obj)
+{
+    return reinterpret_cast<const shadow::Object*>(obj)->parent;
+}
+
+inline JSObject *
+GetObjectProto(const JSObject *obj)
+{
+    return reinterpret_cast<const shadow::Object*>(obj)->type->proto;
+}
+
+inline void *
+GetObjectPrivate(const JSObject *obj)
+{
+    return reinterpret_cast<const shadow::Object*>(obj)->privateData;
+}
+
+#ifdef DEBUG
+extern JS_FRIEND_API(void) CheckReservedSlot(const JSObject *obj, size_t slot);
+#else
+inline void CheckReservedSlot(const JSObject *obj, size_t slot) {}
+#endif
+
+/*
+ * Get a slot that is both reserved for object's clasp *and* is fixed (fits
+ * within the maximum capacity for the object's fixed slots).
+ */
+inline const Value &
+GetReservedSlot(const JSObject *obj, size_t slot)
+{
+    CheckReservedSlot(obj, slot);
+    return reinterpret_cast<const shadow::Object *>(obj)->slotRef(slot);
+}
+
+inline void
+SetReservedSlot(JSObject *obj, size_t slot, const Value &value)
+{
+    CheckReservedSlot(obj, slot);
+    reinterpret_cast<shadow::Object *>(obj)->slotRef(slot) = value;
+}
+
+static inline js::PropertyOp
+CastAsJSPropertyOp(JSObject *object)
+{
+    return JS_DATA_TO_FUNC_PTR(js::PropertyOp, object);
+}
+
+static inline js::StrictPropertyOp
+CastAsJSStrictPropertyOp(JSObject *object)
+{
+    return JS_DATA_TO_FUNC_PTR(js::StrictPropertyOp, object);
+}
+
+JS_FRIEND_API(bool)
+GetPropertyNames(JSContext *cx, JSObject *obj, uintN flags, js::AutoIdVector *props);
+
+/*
+ * NB: these flag bits are encoded into the bytecode stream in the immediate
+ * operand of JSOP_ITER, so don't change them without advancing jsxdrapi.h's
+ * JSXDR_BYTECODE_VERSION.
+ */
+#define JSITER_ENUMERATE  0x1   /* for-in compatible hidden default iterator */
+#define JSITER_FOREACH    0x2   /* return [key, value] pair rather than key */
+#define JSITER_KEYVALUE   0x4   /* destructuring for-in wants [key, value] */
+#define JSITER_OWNONLY    0x8   /* iterate over obj's own properties only */
+#define JSITER_HIDDEN     0x10  /* also enumerate non-enumerable properties */
+
+/* When defining functions, JSFunctionSpec::call points to a JSNativeTraceInfo. */
+#define JSFUN_TRCINFO     0x2000
+
+} /* namespace js */
 #endif
 
 #endif /* jsfriendapi_h___ */
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -1684,17 +1684,17 @@ fun_finalize(JSContext *cx, JSObject *ob
     obj->finalizeUpvarsIfFlatClosure();
 }
 
 /*
  * Reserve two slots in all function objects for XPConnect.  Note that this
  * does not bloat every instance, only those on which reserved slots are set,
  * and those on which ad-hoc properties are defined.
  */
-JS_PUBLIC_DATA(Class) js::FunctionClass = {
+JS_FRIEND_DATA(Class) js::FunctionClass = {
     js_Function_str,
     JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE |
     JSCLASS_HAS_RESERVED_SLOTS(JSFunction::CLASS_RESERVED_SLOTS) |
     JSCLASS_HAS_CACHED_PROTO(JSProto_Function) |
     JSCLASS_CONCURRENT_FINALIZER,
     JS_PropertyStub,         /* addProperty */
     JS_PropertyStub,         /* delProperty */
     JS_PropertyStub,         /* getProperty */
@@ -1711,17 +1711,17 @@ JS_PUBLIC_DATA(Class) js::FunctionClass 
     fun_hasInstance,
     fun_trace
 };
 
 JSString *
 fun_toStringHelper(JSContext *cx, JSObject *obj, uintN indent)
 {
     if (!obj->isFunction()) {
-        if (obj->isFunctionProxy())
+        if (IsFunctionProxy(obj))
             return Proxy::fun_toString(cx, obj, indent);
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                              JSMSG_INCOMPATIBLE_PROTO,
                              js_Function_str, js_toString_str,
                              "object");
         return NULL;
     }
 
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -87,19 +87,18 @@
 #define JSFUN_JOINABLE      0x0001  /* function is null closure that does not
                                        appear to call itself via its own name
                                        or arguments.callee */
 
 #define JSFUN_PROTOTYPE     0x0800  /* function is Function.prototype for some
                                        global object */
 
 #define JSFUN_EXPR_CLOSURE  0x1000  /* expression closure: function(x) x*x */
-#define JSFUN_TRCINFO       0x2000  /* when set, u.n.trcinfo is non-null,
-                                       JSFunctionSpec::call points to a
-                                       JSNativeTraceInfo. */
+                                    /* 0x2000 is JSFUN_TRCINFO:
+                                       u.n.trcinfo is non-null */
 #define JSFUN_INTERPRETED   0x4000  /* use u.i if kind >= this value else u.n */
 #define JSFUN_FLAT_CLOSURE  0x8000  /* flat (aka "display") closure */
 #define JSFUN_NULL_CLOSURE  0xc000  /* null closure entrains no scope chain */
 #define JSFUN_KINDMASK      0xc000  /* encode interp vs. native and closure
                                        optimization level -- see above */
 
 struct JSFunction : public JSObject_Slots2
 {
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -46,21 +46,21 @@
 #include <setjmp.h>
 
 #include "jstypes.h"
 #include "jsprvtd.h"
 #include "jspubtd.h"
 #include "jsdhash.h"
 #include "jsbit.h"
 #include "jsgcchunk.h"
+#include "jshashtable.h"
+#include "jslock.h"
 #include "jsutil.h"
 #include "jsvector.h"
 #include "jsversion.h"
-#include "jsobj.h"
-#include "jsfun.h"
 #include "jsgcstats.h"
 #include "jscell.h"
 
 struct JSCompartment;
 
 extern "C" void
 js_TraceXML(JSTracer *trc, JSXML* thing);
 
@@ -1598,18 +1598,16 @@ namespace gc {
 
 JSCompartment *
 NewCompartment(JSContext *cx, JSPrincipals *principals);
 
 /* Tries to run a GC no matter what (used for GC zeal). */
 void
 RunDebugGC(JSContext *cx);
 
-} /* namespace js */
 } /* namespace gc */
 
-inline JSCompartment *
-JSObject::getCompartment() const
-{
-    return compartment();
-}
+static inline JSCompartment *
+GetObjectCompartment(JSObject *obj) { return reinterpret_cast<js::gc::Cell *>(obj)->compartment(); }
+
+} /* namespace js */
 
 #endif /* jsgc_h___ */
--- a/js/src/jsinfer.h
+++ b/js/src/jsinfer.h
@@ -39,16 +39,17 @@
 
 /* Definitions related to javascript type inference. */
 
 #ifndef jsinfer_h___
 #define jsinfer_h___
 
 #include "jsalloc.h"
 #include "jscell.h"
+#include "jsfriendapi.h"
 #include "jstl.h"
 #include "jsprvtd.h"
 #include "jshashtable.h"
 
 #include "ds/LifoAlloc.h"
 
 namespace js {
 namespace types {
@@ -860,16 +861,20 @@ struct TypeObject : gc::Cell
      * object pending deletion is released when weak references are sweeped
      * from all the compartment's type objects.
      */
     void finalize(JSContext *cx) {}
 
   private:
     inline uint32 basePropertyCount() const;
     inline void setBasePropertyCount(uint32 count);
+
+    static void staticAsserts() {
+        JS_STATIC_ASSERT(offsetof(TypeObject, proto) == offsetof(js::shadow::TypeObject, proto));
+    }
 };
 
 /* Global singleton for the generic type of objects with no prototype. */
 extern TypeObject emptyTypeObject;
 
 /*
  * Call to mark a script's arguments as having been created, recompile any
  * dependencies and walk the stack if necessary to fix any lazy arguments.
--- a/js/src/jsinterp.h
+++ b/js/src/jsinterp.h
@@ -41,17 +41,16 @@
 #ifndef jsinterp_h___
 #define jsinterp_h___
 /*
  * JS interpreter interface.
  */
 #include "jsprvtd.h"
 #include "jspubtd.h"
 #include "jsopcode.h"
-#include "jsscript.h"
 
 #include "vm/Stack.h"
 
 namespace js {
 
 extern JSObject *
 GetBlockChain(JSContext *cx, StackFrame *fp);
 
@@ -297,20 +296,17 @@ class InterpreterFrames {
       public:
         virtual void enableInterrupts() const = 0;
     };
 
     InterpreterFrames(JSContext *cx, FrameRegs *regs, const InterruptEnablerBase &enabler);
     ~InterpreterFrames();
 
     /* If this js::Interpret frame is running |script|, enable interrupts. */
-    void enableInterruptsIfRunning(JSScript *script) {
-        if (script == regs->fp()->script())
-            enabler.enableInterrupts();
-    }
+    inline void enableInterruptsIfRunning(JSScript *script);
 
     InterpreterFrames *older;
 
   private:
     JSContext *context;
     FrameRegs *regs;
     const InterruptEnablerBase &enabler;
 };
@@ -325,91 +321,16 @@ UnwindScope(JSContext *cx, jsint stackDe
 extern bool
 OnUnknownMethod(JSContext *cx, js::Value *vp);
 
 extern bool
 IsActiveWithOrBlock(JSContext *cx, JSObject &obj, int stackDepth);
 
 /************************************************************************/
 
-static JS_ALWAYS_INLINE void
-ClearValueRange(Value *vec, uintN len, bool useHoles)
-{
-    if (useHoles) {
-        for (uintN i = 0; i < len; i++)
-            vec[i].setMagic(JS_ARRAY_HOLE);
-    } else {
-        for (uintN i = 0; i < len; i++)
-            vec[i].setUndefined();
-    }
-}
-
-static JS_ALWAYS_INLINE void
-MakeRangeGCSafe(Value *vec, size_t len)
-{
-    PodZero(vec, len);
-}
-
-static JS_ALWAYS_INLINE void
-MakeRangeGCSafe(Value *beg, Value *end)
-{
-    PodZero(beg, end - beg);
-}
-
-static JS_ALWAYS_INLINE void
-MakeRangeGCSafe(jsid *beg, jsid *end)
-{
-    for (jsid *id = beg; id != end; ++id)
-        *id = INT_TO_JSID(0);
-}
-
-static JS_ALWAYS_INLINE void
-MakeRangeGCSafe(jsid *vec, size_t len)
-{
-    MakeRangeGCSafe(vec, vec + len);
-}
-
-static JS_ALWAYS_INLINE void
-MakeRangeGCSafe(const Shape **beg, const Shape **end)
-{
-    PodZero(beg, end - beg);
-}
-
-static JS_ALWAYS_INLINE void
-MakeRangeGCSafe(const Shape **vec, size_t len)
-{
-    PodZero(vec, len);
-}
-
-static JS_ALWAYS_INLINE void
-SetValueRangeToUndefined(Value *beg, Value *end)
-{
-    for (Value *v = beg; v != end; ++v)
-        v->setUndefined();
-}
-
-static JS_ALWAYS_INLINE void
-SetValueRangeToUndefined(Value *vec, size_t len)
-{
-    SetValueRangeToUndefined(vec, vec + len);
-}
-
-static JS_ALWAYS_INLINE void
-SetValueRangeToNull(Value *beg, Value *end)
-{
-    for (Value *v = beg; v != end; ++v)
-        v->setNull();
-}
-
-static JS_ALWAYS_INLINE void
-SetValueRangeToNull(Value *vec, size_t len)
-{
-    SetValueRangeToNull(vec, vec + len);
-}
-
 /*
  * To really poison a set of values, using 'magic' or 'undefined' isn't good
  * enough since often these will just be ignored by buggy code (see bug 629974)
  * in debug builds and crash in release builds. Instead, we use a safe-for-crash
  * pointer.
  */
 static JS_ALWAYS_INLINE void
 Debug_SetValueRangeToCrashOnTouch(Value *beg, Value *end)
--- a/js/src/jsinterpinlines.h
+++ b/js/src/jsinterpinlines.h
@@ -245,11 +245,18 @@ ScriptEpilogueOrGeneratorYield(JSContext
 {
     if (!fp->isYielding())
         return ScriptEpilogue(cx, fp, ok);
     if (cx->compartment->debugMode())
         return ScriptDebugEpilogue(cx, fp, ok);
     return ok;
 }
 
+inline void
+InterpreterFrames::enableInterruptsIfRunning(JSScript *script)
+{
+    if (script == regs->fp()->script())
+        enabler.enableInterrupts();
+}
+
 }  /* namespace js */
 
 #endif /* jsinterpinlines_h__ */
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -308,43 +308,39 @@ Snapshot(JSContext *cx, JSObject *obj, u
 
         if ((flags & JSITER_OWNONLY) || pobj->isXML())
             break;
     } while ((pobj = pobj->getProto()) != NULL);
 
     return true;
 }
 
-namespace js {
-
 bool
-VectorToIdArray(JSContext *cx, AutoIdVector &props, JSIdArray **idap)
+js::VectorToIdArray(JSContext *cx, AutoIdVector &props, JSIdArray **idap)
 {
     JS_STATIC_ASSERT(sizeof(JSIdArray) > sizeof(jsid));
     size_t len = props.length();
     size_t idsz = len * sizeof(jsid);
     size_t sz = (sizeof(JSIdArray) - sizeof(jsid)) + idsz;
     JSIdArray *ida = static_cast<JSIdArray *>(cx->malloc_(sz));
     if (!ida)
         return false;
 
     ida->length = static_cast<jsint>(len);
     memcpy(ida->vector, props.begin(), idsz);
     *idap = ida;
     return true;
 }
 
 JS_FRIEND_API(bool)
-GetPropertyNames(JSContext *cx, JSObject *obj, uintN flags, AutoIdVector *props)
+js::GetPropertyNames(JSContext *cx, JSObject *obj, uintN flags, AutoIdVector *props)
 {
     return Snapshot(cx, obj, flags & (JSITER_OWNONLY | JSITER_HIDDEN), props);
 }
 
-}
-
 size_t sCustomIteratorCount = 0;
 
 static inline bool
 GetCustomIterator(JSContext *cx, JSObject *obj, uintN flags, Value *vp)
 {
     /* Check whether we have a valid __iterator__ method. */
     JSAtom *atom = cx->runtime->atomState.iteratorAtom;
     if (!js_GetMethod(cx, obj, ATOM_TO_JSID(atom), JSGET_NO_METHOD_BARRIER, vp))
--- a/js/src/jsiter.h
+++ b/js/src/jsiter.h
@@ -43,26 +43,17 @@
 /*
  * JavaScript iterators.
  */
 #include "jscntxt.h"
 #include "jsprvtd.h"
 #include "jspubtd.h"
 #include "jsversion.h"
 
-/*
- * NB: these flag bits are encoded into the bytecode stream in the immediate
- * operand of JSOP_ITER, so don't change them without advancing jsxdrapi.h's
- * JSXDR_BYTECODE_VERSION.
- */
-#define JSITER_ENUMERATE  0x1   /* for-in compatible hidden default iterator */
-#define JSITER_FOREACH    0x2   /* return [key, value] pair rather than key */
-#define JSITER_KEYVALUE   0x4   /* destructuring for-in wants [key, value] */
-#define JSITER_OWNONLY    0x8   /* iterate over obj's own properties only */
-#define JSITER_HIDDEN     0x10  /* also enumerate non-enumerable properties */
+#include "vm/Stack.h"
 
 /*
  * For cacheable native iterators, whether the iterator is currently active.
  * Not serialized by XDR.
  */
 #define JSITER_ACTIVE       0x1000
 #define JSITER_UNREUSABLE   0x2000
 
@@ -107,19 +98,16 @@ struct NativeIterator {
     void init(JSObject *obj, uintN flags, uint32 slength, uint32 key);
 
     void mark(JSTracer *trc);
 };
 
 bool
 VectorToIdArray(JSContext *cx, js::AutoIdVector &props, JSIdArray **idap);
 
-JS_FRIEND_API(bool)
-GetPropertyNames(JSContext *cx, JSObject *obj, uintN flags, js::AutoIdVector *props);
-
 bool
 GetIterator(JSContext *cx, JSObject *obj, uintN flags, js::Value *vp);
 
 bool
 VectorToKeyIterator(JSContext *cx, JSObject *obj, uintN flags, js::AutoIdVector &props, js::Value *vp);
 
 bool
 VectorToValueIterator(JSContext *cx, JSObject *obj, uintN flags, js::AutoIdVector &props, js::Value *vp);
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -123,33 +123,33 @@ Class js::ObjectClass = {
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
     JS_ConvertStub
 };
 
 JS_FRIEND_API(JSObject *)
-js_ObjectToOuterObject(JSContext *cx, JSObject *obj)
+JS_ObjectToInnerObject(JSContext *cx, JSObject *obj)
+{
+    if (!obj) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INACTIVE);
+        return NULL;
+    }
+    OBJ_TO_INNER_OBJECT(cx, obj);
+    return obj;
+}
+
+JS_FRIEND_API(JSObject *)
+JS_ObjectToOuterObject(JSContext *cx, JSObject *obj)
 {
     OBJ_TO_OUTER_OBJECT(cx, obj);
     return obj;
 }
 
-JS_FRIEND_API(bool)
-NULLABLE_OBJ_TO_INNER_OBJECT(JSContext *cx, JSObject *&obj)
-{
-    if (!obj) {
-        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INACTIVE);
-        return false;
-    }
-    OBJ_TO_INNER_OBJECT(cx, obj);
-    return !!obj;
-}
-
 #if JS_HAS_OBJ_PROTO_PROP
 
 static JSBool
 obj_getProto(JSContext *cx, JSObject *obj, jsid id, Value *vp);
 
 static JSBool
 obj_setProto(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value *vp);
 
@@ -1602,17 +1602,17 @@ js_PropertyIsEnumerable(JSContext *cx, J
 #if OLD_GETTER_SETTER_METHODS
 
 const char js_defineGetter_str[] = "__defineGetter__";
 const char js_defineSetter_str[] = "__defineSetter__";
 const char js_lookupGetter_str[] = "__lookupGetter__";
 const char js_lookupSetter_str[] = "__lookupSetter__";
 
 JS_FRIEND_API(JSBool)
-js_obj_defineGetter(JSContext *cx, uintN argc, Value *vp)
+js::obj_defineGetter(JSContext *cx, uintN argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     if (!BoxNonStrictThis(cx, args))
         return false;
     JSObject *obj = &args.thisv().toObject();
 
     if (args.length() <= 1 || !js_IsCallable(args[1])) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
@@ -1636,17 +1636,17 @@ js_obj_defineGetter(JSContext *cx, uintN
     if (!CheckAccess(cx, obj, id, JSACC_WATCH, &junk, &attrs))
         return JS_FALSE;
     args.rval().setUndefined();
     return obj->defineProperty(cx, id, UndefinedValue(), getter, JS_StrictPropertyStub,
                                JSPROP_ENUMERATE | JSPROP_GETTER | JSPROP_SHARED);
 }
 
 JS_FRIEND_API(JSBool)
-js_obj_defineSetter(JSContext *cx, uintN argc, Value *vp)
+js::obj_defineSetter(JSContext *cx, uintN argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     if (!BoxNonStrictThis(cx, args))
         return false;
     JSObject *obj = &args.thisv().toObject();
 
     if (args.length() <= 1 || !js_IsCallable(args[1])) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
@@ -2876,18 +2876,18 @@ JSFunctionSpec object_methods[] = {
 #if JS_HAS_OBJ_WATCHPOINT
     JS_FN(js_watch_str,                obj_watch,                   2,0),
     JS_FN(js_unwatch_str,              obj_unwatch,                 1,0),
 #endif
     JS_FN(js_hasOwnProperty_str,       obj_hasOwnProperty,          1,0),
     JS_FN(js_isPrototypeOf_str,        obj_isPrototypeOf,           1,0),
     JS_FN(js_propertyIsEnumerable_str, obj_propertyIsEnumerable,    1,0),
 #if OLD_GETTER_SETTER_METHODS
-    JS_FN(js_defineGetter_str,         js_obj_defineGetter,         2,0),
-    JS_FN(js_defineSetter_str,         js_obj_defineSetter,         2,0),
+    JS_FN(js_defineGetter_str,         js::obj_defineGetter,        2,0),
+    JS_FN(js_defineSetter_str,         js::obj_defineSetter,        2,0),
     JS_FN(js_lookupGetter_str,         obj_lookupGetter,            1,0),
     JS_FN(js_lookupSetter_str,         obj_lookupSetter,            1,0),
 #endif
     JS_FS_END
 };
 
 JSFunctionSpec object_static_methods[] = {
     JS_FN("getPrototypeOf",            obj_getPrototypeOf,          1,0),
@@ -3672,22 +3672,22 @@ JSObject::nonNativeSetElement(JSContext 
         JS_ASSERT(id == js_CheckForStringIndex(id));
         WatchpointMap *wpmap = cx->compartment->watchpointMap;
         if (wpmap && !wpmap->triggerWatchpoint(cx, this, id, vp))
             return false;
     }
     return getOps()->setElement(cx, this, index, vp, strict);
 }
 
-bool
-JSObject::copyPropertiesFrom(JSContext *cx, JSObject *obj)
+JS_FRIEND_API(bool)
+JS_CopyPropertiesFrom(JSContext *cx, JSObject *target, JSObject *obj)
 {
     // If we're not native, then we cannot copy properties.
-    JS_ASSERT(isNative() == obj->isNative());
-    if (!isNative())
+    JS_ASSERT(target->isNative() == obj->isNative());
+    if (!target->isNative())
         return true;
 
     AutoShapeVector shapes(cx);
     for (Shape::Range r(obj->lastProperty()); !r.empty(); r.popFront()) {
         if (!shapes.append(&r.front()))
             return false;
     }
 
@@ -3699,17 +3699,17 @@ JSObject::copyPropertiesFrom(JSContext *
         if ((attrs & JSPROP_GETTER) && !cx->compartment->wrap(cx, &getter))
             return false;
         StrictPropertyOp setter = shape->setter();
         if ((attrs & JSPROP_SETTER) && !cx->compartment->wrap(cx, &setter))
             return false;
         Value v = shape->hasSlot() ? obj->getSlot(shape->slot) : UndefinedValue();
         if (!cx->compartment->wrap(cx, &v))
             return false;
-        if (!defineProperty(cx, shape->propid, v, getter, setter, attrs))
+        if (!target->defineProperty(cx, shape->propid, v, getter, setter, attrs))
             return false;
     }
     return true;
 }
 
 static bool
 CopySlots(JSContext *cx, JSObject *from, JSObject *to)
 {
@@ -3730,48 +3730,48 @@ CopySlots(JSContext *cx, JSObject *from,
         Value v = from->getSlot(n);
         if (!cx->compartment->wrap(cx, &v))
             return false;
         to->setSlot(n, v);
     }
     return true;
 }
 
-JSObject *
-JSObject::clone(JSContext *cx, JSObject *proto, JSObject *parent)
+JS_FRIEND_API(JSObject *)
+JS_CloneObject(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent)
 {
     /*
      * We can only clone native objects and proxies. Dense arrays are slowified if
      * we try to clone them.
      */
-    if (!isNative()) {
-        if (isDenseArray()) {
-            if (!makeDenseArraySlow(cx))
+    if (!obj->isNative()) {
+        if (obj->isDenseArray()) {
+            if (!obj->makeDenseArraySlow(cx))
                 return NULL;
-        } else if (!isProxy()) {
+        } else if (!obj->isProxy()) {
             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                                  JSMSG_CANT_CLONE_OBJECT);
             return NULL;
         }
     }
-    JSObject *clone = NewObject<WithProto::Given>(cx, getClass(), proto, parent, getAllocKind());
+    JSObject *clone = NewObject<WithProto::Given>(cx, obj->getClass(), proto, parent, obj->getAllocKind());
     if (!clone)
         return NULL;
-    if (isNative()) {
-        if (clone->isFunction() && (compartment() != clone->compartment())) {
+    if (obj->isNative()) {
+        if (clone->isFunction() && (obj->compartment() != clone->compartment())) {
             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                                  JSMSG_CANT_CLONE_OBJECT);
             return NULL;
         }
 
-        if (getClass()->flags & JSCLASS_HAS_PRIVATE)
-            clone->setPrivate(getPrivate());
+        if (obj->getClass()->flags & JSCLASS_HAS_PRIVATE)
+            clone->setPrivate(obj->getPrivate());
     } else {
-        JS_ASSERT(isProxy());
-        if (!CopySlots(cx, this, clone))
+        JS_ASSERT(obj->isProxy());
+        if (!CopySlots(cx, obj, clone))
             return NULL;
     }
 
     return clone;
 }
 
 struct JSObject::TradeGutsReserved {
     JSContext *cx;
@@ -3965,26 +3965,26 @@ JSObject::swap(JSContext *cx, JSObject *
     }
 
     JSObject *thisClone;
     JSObject *otherClone;
     {
         AutoCompartment ac(cx, other);
         if (!ac.enter())
             return false;
-        thisClone = this->clone(cx, other->getProto(), other->getParent());
-        if (!thisClone || !thisClone->copyPropertiesFrom(cx, this))
+        thisClone = JS_CloneObject(cx, this, other->getProto(), other->getParent());
+        if (!thisClone || !JS_CopyPropertiesFrom(cx, thisClone, this))
             return false;
     }
     {
         AutoCompartment ac(cx, this);
         if (!ac.enter())
             return false;
-        otherClone = other->clone(cx, other->getProto(), other->getParent());
-        if (!otherClone || !otherClone->copyPropertiesFrom(cx, other))
+        otherClone = JS_CloneObject(cx, other, other->getProto(), other->getParent());
+        if (!otherClone || !JS_CopyPropertiesFrom(cx, otherClone, other))
             return false;
     }
 
     TradeGutsReserved reservedThis(cx);
     TradeGutsReserved reservedOther(cx);
 
     if (!ReserveForTradeGuts(cx, this, otherClone, reservedThis) ||
         !ReserveForTradeGuts(cx, other, thisClone, reservedOther)) {
@@ -5979,17 +5979,17 @@ js_GetMethod(JSContext *cx, JSObject *ob
 #if JS_HAS_XML_SUPPORT
     if (obj->isXML())
         return js_GetXMLMethod(cx, obj, id, vp);
 #endif
     return op(cx, obj, obj, id, vp);
 }
 
 JS_FRIEND_API(bool)
-js_CheckUndeclaredVarAssignment(JSContext *cx, JSString *propname)
+js::CheckUndeclaredVarAssignment(JSContext *cx, JSString *propname)
 {
     StackFrame *const fp = js_GetTopStackFrame(cx, FRAME_EXPAND_ALL);
     if (!fp)
         return true;
 
     /* If neither cx nor the code is strict, then no check is needed. */
     if (!(fp->isScriptFrame() && fp->script()->strictModeCode) &&
         !cx->hasStrictOption()) {
@@ -6113,17 +6113,17 @@ js_SetPropertyHelper(JSContext *cx, JSOb
             prop = NULL;
         }
     } else {
         /* We should never add properties to lexical blocks.  */
         JS_ASSERT(!obj->isBlock());
 
         if (!obj->getParent() &&
             (defineHow & DNP_UNQUALIFIED) &&
-            !js_CheckUndeclaredVarAssignment(cx, JSID_TO_STRING(id))) {
+            !js::CheckUndeclaredVarAssignment(cx, JSID_TO_STRING(id))) {
             return JS_FALSE;
         }
     }
     shape = (Shape *) prop;
 
     /*
      * Now either shape is null, meaning id was not found in obj or one of its
      * prototypes; or shape is non-null, meaning id was found directly in pobj.
@@ -6575,17 +6575,17 @@ DefaultValue(JSContext *cx, JSObject *ob
     js_ReportValueError2(cx, JSMSG_CANT_CONVERT_TO, JSDVG_SEARCH_STACK, ObjectValue(*obj), str,
                          (hint == JSTYPE_VOID) ? "primitive type" : JS_TYPE_STR(hint));
     return false;
 }
 
 } /* namespace js */
 
 JS_FRIEND_API(JSBool)
-js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, Value *statep, jsid *idp)
+JS_EnumerateState(JSContext *cx, JSObject *obj, JSIterateOp enum_op, Value *statep, jsid *idp)
 {
     /* If the class has a custom JSCLASS_NEW_ENUMERATE hook, call it. */
     Class *clasp = obj->getClass();
     JSEnumerateOp enumerate = clasp->enumerate;
     if (clasp->flags & JSCLASS_NEW_ENUMERATE) {
         JS_ASSERT(enumerate != JS_EnumerateStub);
         return ((JSNewEnumerateOp) enumerate)(cx, obj, enum_op, statep, idp);
     }
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -46,16 +46,17 @@
  *
  * A JS object consists of a possibly-shared object descriptor containing
  * ordered property names, called the map; and a dense vector of property
  * values, called slots.  The map/slot pointer pair is GC'ed, while the map
  * is reference counted and the slot vector is malloc'ed.
  */
 #include "jsapi.h"
 #include "jsclass.h"
+#include "jsfriendapi.h"
 #include "jsinfer.h"
 #include "jshash.h"
 #include "jspubtd.h"
 #include "jsprvtd.h"
 #include "jslock.h"
 #include "jsvector.h"
 #include "jscell.h"
 
@@ -81,28 +82,16 @@ CastAsPropertyOp(JSObject *object)
 }
 
 static inline StrictPropertyOp
 CastAsStrictPropertyOp(JSObject *object)
 {
     return JS_DATA_TO_FUNC_PTR(StrictPropertyOp, object);
 }
 
-static inline PropertyOp
-CastAsJSPropertyOp(JSObject *object)
-{
-    return JS_DATA_TO_FUNC_PTR(PropertyOp, object);
-}
-
-static inline StrictPropertyOp
-CastAsJSStrictPropertyOp(JSObject *object)
-{
-    return JS_DATA_TO_FUNC_PTR(StrictPropertyOp, object);
-}
-
 inline JSObject *
 CastAsObject(PropertyOp op)
 {
     return JS_FUNC_TO_DATA_PTR(JSObject *, op);
 }
 
 inline JSObject *
 CastAsObject(StrictPropertyOp op)
@@ -322,42 +311,25 @@ extern JSBool
 js_SetElementAttributes(JSContext *cx, JSObject *obj, uint32 index, uintN *attrsp);
 
 extern JSBool
 js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *rval, JSBool strict);
 
 extern JSBool
 js_DeleteElement(JSContext *cx, JSObject *obj, uint32 index, js::Value *rval, JSBool strict);
 
-extern JS_FRIEND_API(JSBool)
-js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
-             js::Value *statep, jsid *idp);
-
 extern JSType
 js_TypeOf(JSContext *cx, JSObject *obj);
 
 namespace js {
 
 /* ES5 8.12.8. */
 extern JSBool
 DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp);
 
-extern JS_FRIEND_DATA(Class) AnyNameClass;
-extern JS_FRIEND_DATA(Class) AttributeNameClass;
-extern JS_FRIEND_DATA(Class) CallClass;
-extern JS_FRIEND_DATA(Class) DeclEnvClass;
-extern JS_FRIEND_DATA(Class) FunctionClass;
-extern JS_FRIEND_DATA(Class) FunctionProxyClass;
-extern JS_FRIEND_DATA(Class) NamespaceClass;
-extern JS_FRIEND_DATA(Class) OuterWindowProxyClass;
-extern JS_FRIEND_DATA(Class) ObjectProxyClass;
-extern JS_FRIEND_DATA(Class) QNameClass;
-extern JS_FRIEND_DATA(Class) ScriptClass;
-extern JS_FRIEND_DATA(Class) XMLClass;
-
 extern Class ArrayClass;
 extern Class ArrayBufferClass;
 extern Class BlockClass;
 extern Class BooleanClass;
 extern Class CallableObjectClass;
 extern Class DateClass;
 extern Class ErrorClass;
 extern Class GeneratorClass;
@@ -1287,22 +1259,16 @@ struct JSObject : js::gc::Cell {
 
     inline JSAtom *getQNameLocalName() const;
     inline jsval getQNameLocalNameVal() const;
     inline void setQNameLocalName(JSAtom *name);
 
     /*
      * Proxy-specific getters and setters.
      */
-
-    inline js::ProxyHandler *getProxyHandler() const;
-    inline const js::Value &getProxyPrivate() const;
-    inline void setProxyPrivate(const js::Value &priv);
-    inline const js::Value &getProxyExtra() const;
-    inline void setProxyExtra(const js::Value &extra);
     inline js::Wrapper *getWrapperHandler() const;
 
     /*
      * With object-specific getters and setters.
      */
     inline JSObject *getWithThis() const;
     inline void setWithThis(JSObject *thisp);
 
@@ -1489,17 +1455,17 @@ struct JSObject : js::gc::Cell {
     }
 
     inline JSBool deleteProperty(JSContext *cx, jsid id, js::Value *rval, JSBool strict);
 
     inline JSBool deleteElement(JSContext *cx, uint32 index, js::Value *rval, JSBool strict);
 
     JSBool enumerate(JSContext *cx, JSIterateOp iterop, js::Value *statep, jsid *idp) {
         JSNewEnumerateOp op = getOps()->enumerate;
-        return (op ? op : js_Enumerate)(cx, this, iterop, statep, idp);
+        return (op ? op : JS_EnumerateState)(cx, this, iterop, statep, idp);
     }
 
     bool defaultValue(JSContext *cx, JSType hint, js::Value *vp) {
         JSConvertOp op = getClass()->convert;
         bool ok = (op == JS_ConvertStub ? js::DefaultValue : op)(cx, this, hint, vp);
         JS_ASSERT_IF(ok, vp->isPrimitive());
         return ok;
     }
@@ -1512,22 +1478,18 @@ struct JSObject : js::gc::Cell {
     /* These four are time-optimized to avoid stub calls. */
     JSObject *thisObject(JSContext *cx) {
         JSObjectOp op = getOps()->thisObject;
         return op ? op(cx, this) : this;
     }
 
     static bool thisObject(JSContext *cx, const js::Value &v, js::Value *vp);
 
-    inline JSCompartment *getCompartment() const;
-
     inline JSObject *getThrowTypeError() const;
 
-    JS_FRIEND_API(JSObject *) clone(JSContext *cx, JSObject *proto, JSObject *parent);
-    JS_FRIEND_API(bool) copyPropertiesFrom(JSContext *cx, JSObject *obj);
     bool swap(JSContext *cx, JSObject *other);
 
     const js::Shape *defineBlockVariable(JSContext *cx, jsid id, intN index);
 
     inline bool canHaveMethodBarrier() const;
 
     inline bool isArguments() const { return isNormalArguments() || isStrictArguments(); }
     inline bool isArrayBuffer() const { return clasp == &js::ArrayBufferClass; }
@@ -1553,43 +1515,49 @@ struct JSObject : js::gc::Cell {
     inline bool isScript() const { return clasp == &js::ScriptClass; }
     inline bool isGenerator() const { return clasp == &js::GeneratorClass; }
     inline bool isIterator() const { return clasp == &js::IteratorClass; }
     inline bool isStopIteration() const { return clasp == &js::StopIterationClass; }
     inline bool isError() const { return clasp == &js::ErrorClass; }
     inline bool isXML() const { return clasp == &js::XMLClass; }
     inline bool isNamespace() const { return clasp == &js::NamespaceClass; }
     inline bool isWeakMap() const { return clasp == &js::WeakMapClass; }
-    inline bool isFunctionProxy() const { return clasp == &js::FunctionProxyClass; }
-    inline bool isProxy() const { return isObjectProxy() || isFunctionProxy(); }
+    inline bool isProxy() const;
 
     inline bool isXMLId() const {
         return clasp == &js::QNameClass || clasp == &js::AttributeNameClass || clasp == &js::AnyNameClass;
     }
     inline bool isQName() const {
         return clasp == &js::QNameClass || clasp == &js::AttributeNameClass || clasp == &js::AnyNameClass;
     }
-    inline bool isObjectProxy() const {
-        return clasp == &js::ObjectProxyClass || clasp == &js::OuterWindowProxyClass;
-    }
 
-    JS_FRIEND_API(bool) isWrapper() const;
-    bool isCrossCompartmentWrapper() const;
-    JS_FRIEND_API(JSObject *) unwrap(uintN *flagsp = NULL);
+    inline bool isWrapper() const;
+    inline bool isCrossCompartmentWrapper() const;
 
     inline void initArrayClass();
 
+    static void staticAsserts() {
+        /* Check alignment for any fixed slots allocated after the object. */
+        JS_STATIC_ASSERT(sizeof(JSObject) % sizeof(js::Value) == 0);
+
+        JS_STATIC_ASSERT(offsetof(JSObject, clasp) == offsetof(js::shadow::Object, clasp));
+        JS_STATIC_ASSERT(offsetof(JSObject, flags) == offsetof(js::shadow::Object, flags));
+        JS_STATIC_ASSERT(offsetof(JSObject, parent) == offsetof(js::shadow::Object, parent));
+        JS_STATIC_ASSERT(offsetof(JSObject, privateData) == offsetof(js::shadow::Object, privateData));
+        JS_STATIC_ASSERT(offsetof(JSObject, slots) == offsetof(js::shadow::Object, slots));
+        JS_STATIC_ASSERT(offsetof(JSObject, type_) == offsetof(js::shadow::Object, type));
+        JS_STATIC_ASSERT(sizeof(JSObject) == sizeof(js::shadow::Object));
+        JS_STATIC_ASSERT(FIXED_SLOTS_SHIFT == js::shadow::Object::FIXED_SLOTS_SHIFT);
+    }
+
     /*** For jit compiler: ***/
 
     static size_t offsetOfClassPointer() { return offsetof(JSObject, clasp); }
 };
 
-/* Check alignment for any fixed slots allocated after the object. */
-JS_STATIC_ASSERT(sizeof(JSObject) % sizeof(js::Value) == 0);
-
 /*
  * The only sensible way to compare JSObject with == is by identity. We use
  * const& instead of * as a syntactic way to assert non-null. This leads to an
  * abundance of address-of operators to identity. Hence this overload.
  */
 static JS_ALWAYS_INLINE bool
 operator==(const JSObject &lhs, const JSObject &rhs)
 {
@@ -1643,23 +1611,16 @@ struct JSObject_Slots16 : JSObject { js:
 
 inline void
 OBJ_TO_INNER_OBJECT(JSContext *cx, JSObject *&obj)
 {
     if (JSObjectOp op = obj->getClass()->ext.innerObject)
         obj = op(cx, obj);
 }
 
-/*
- * It is safe to call with input obj == NULL. Return true iff output obj is
- * non-NULL.
- */
-extern JS_FRIEND_API(bool)
-NULLABLE_OBJ_TO_INNER_OBJECT(JSContext *cx, JSObject *&obj);
-
 inline void
 OBJ_TO_OUTER_OBJECT(JSContext *cx, JSObject *&obj)
 {
     if (JSObjectOp op = obj->getClass()->ext.outerObject)
         obj = op(cx, obj);
 }
 
 class JSValueArray {
@@ -1732,22 +1693,17 @@ extern JSObject *
 js_CloneBlockObject(JSContext *cx, JSObject *proto, js::StackFrame *fp);
 
 extern JS_REQUIRES_STACK JSBool
 js_PutBlockObject(JSContext *cx, JSBool normalUnwind);
 
 JSBool
 js_XDRBlockObject(JSXDRState *xdr, JSObject **objp);
 
-struct JSSharpObjectMap {
-    jsrefcount  depth;
-    uint32      sharpgen;
-    JSHashTable *table;
-};
-
+/* For manipulating JSContext::sharpObjectMap. */
 #define SHARP_BIT       ((jsatomid) 1)
 #define BUSY_BIT        ((jsatomid) 2)
 #define SHARP_ID_SHIFT  2
 #define IS_SHARP(he)    (uintptr_t((he)->value) & SHARP_BIT)
 #define MAKE_SHARP(he)  ((he)->value = (void *) (uintptr_t((he)->value)|SHARP_BIT))
 #define IS_BUSY(he)     (uintptr_t((he)->value) & BUSY_BIT)
 #define MAKE_BUSY(he)   ((he)->value = (void *) (uintptr_t((he)->value)|BUSY_BIT))
 #define CLEAR_BUSY(he)  ((he)->value = (void *) (uintptr_t((he)->value)&~BUSY_BIT))
@@ -1781,21 +1737,16 @@ js_PropertyIsEnumerable(JSContext *cx, J
 extern JSPropertySpec object_props[];
 #else
 #define object_props NULL
 #endif
 
 extern JSFunctionSpec object_methods[];
 extern JSFunctionSpec object_static_methods[];
 
-#ifdef OLD_GETTER_SETTER_METHODS
-JS_FRIEND_API(JSBool) js_obj_defineGetter(JSContext *cx, uintN argc, js::Value *vp);
-JS_FRIEND_API(JSBool) js_obj_defineSetter(JSContext *cx, uintN argc, js::Value *vp);
-#endif
-
 namespace js {
 
 JSObject *
 DefineConstructorAndPrototype(JSContext *cx, JSObject *obj, JSProtoKey key, JSAtom *atom,
                               JSObject *protoProto, Class *clasp,
                               Native constructor, uintN nargs,
                               JSPropertySpec *ps, JSFunctionSpec *fs,
                               JSPropertySpec *static_ps, JSFunctionSpec *static_fs,
@@ -2051,25 +2002,16 @@ bool
 NewPropertyDescriptorObject(JSContext *cx, const PropertyDescriptor *desc, Value *vp);
 
 } /* namespace js */
 
 extern JSBool
 js_GetMethod(JSContext *cx, JSObject *obj, jsid id, uintN getHow, js::Value *vp);
 
 /*
- * Check whether it is OK to assign an undeclared property with name
- * propname of the global object in the current script on cx.  Reports
- * an error if one needs to be reported (in particular in all cases
- * when it returns false).
- */
-extern JS_FRIEND_API(bool)
-js_CheckUndeclaredVarAssignment(JSContext *cx, JSString *propname);
-
-/*
  * Change attributes for the given native property. The caller must ensure
  * that obj is locked and this function always unlocks obj on return.
  */
 extern JSBool
 js_SetNativeAttributes(JSContext *cx, JSObject *obj, js::Shape *shape,
                        uintN attrs);
 
 namespace js {
@@ -2170,29 +2112,16 @@ extern bool
 js_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, js::Value *vp);
 
 extern bool
 js_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, const js::Value &v);
 
 extern JSBool
 js_ReportGetterOnlyAssignment(JSContext *cx);
 
-extern JS_FRIEND_API(JSBool)
-js_GetterOnlyPropertyStub(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp);
-
-#ifdef DEBUG
-JS_FRIEND_API(void) js_DumpChars(const jschar *s, size_t n);
-JS_FRIEND_API(void) js_DumpString(JSString *str);
-JS_FRIEND_API(void) js_DumpAtom(JSAtom *atom);
-JS_FRIEND_API(void) js_DumpObject(JSObject *obj);
-JS_FRIEND_API(void) js_DumpValue(const js::Value &val);
-JS_FRIEND_API(void) js_DumpId(jsid id);
-JS_FRIEND_API(void) js_DumpStackFrame(JSContext *cx, js::StackFrame *start = NULL);
-#endif
-
 extern uintN
 js_InferFlags(JSContext *cx, uintN defaultFlags);
 
 /* Object constructor native. Exposed only so the JIT can know its address. */
 JSBool
 js_Object(JSContext *cx, uintN argc, js::Value *vp);
 
 namespace js {
@@ -2295,26 +2224,11 @@ HandleNonGenericMethodClassMismatch(JSCo
  * Boolean, Number, and String (e.g., ES5 15.6.4.2). If 'true' is returned, the
  * extracted primitive is stored in |*v|. If 'false' is returned, the caller
  * must immediately 'return *ok'. For details, see NonGenericMethodGuard.
  */
 template <typename T>
 inline bool
 BoxedPrimitiveMethodGuard(JSContext *cx, CallArgs args, T *v, bool *ok);
 
-/*
- * Enumeration describing possible values of the [[Class]] internal property
- * value of objects.
- */
-enum ESClassValue { ESClass_Array, ESClass_Number, ESClass_String, ESClass_Boolean };
-
-/*
- * Return whether the given object has the given [[Class]] internal property
- * value. Beware, this query says nothing about the js::Class of the JSObject
- * so the caller must not assume anything about obj's representation (e.g., obj
- * may be a proxy).
- */
-inline bool
-ObjectClassIs(JSObject &obj, ESClassValue classValue, JSContext *cx);
-
 }  /* namespace js */
 
 #endif /* jsobj_h___ */
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -50,16 +50,17 @@
 #include "jsobj.h"
 #include "jsprobes.h"
 #include "jspropertytree.h"
 #include "jsproxy.h"
 #include "jsscope.h"
 #include "jsstaticcheck.h"
 #include "jstypedarray.h"
 #include "jsxml.h"
+#include "jswrapper.h"
 
 /* Headers included for inline implementations used by this header. */
 #include "jsbool.h"
 #include "jscntxt.h"
 #include "jsnum.h"
 #include "jsinferinlines.h"
 #include "jsscopeinlines.h"
 #include "jsscriptinlines.h"
@@ -82,17 +83,17 @@ JSObject::preventExtensions(JSContext *c
         bool success;
         if (!fix(cx, this, &success, props))
             return false;
         if (!success) {
             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CHANGE_EXTENSIBILITY);
             return false;
         }
     } else {
-        if (!GetPropertyNames(cx, this, JSITER_HIDDEN | JSITER_OWNONLY, props))
+        if (!js::GetPropertyNames(cx, this, JSITER_HIDDEN | JSITER_OWNONLY, props))
             return false;
     }
 
     if (isNative())
         extensibleShapeChange(cx);
 
     flags |= NOT_EXTENSIBLE;
     return true;
@@ -1138,16 +1139,34 @@ JSObject::deleteElement(JSContext *cx, u
 }
 
 inline JSBool
 JSObject::getSpecial(JSContext *cx, js::SpecialId sid, js::Value *vp)
 {
     return getGeneric(cx, SPECIALID_TO_JSID(sid), vp);
 }
 
+inline bool
+JSObject::isProxy() const
+{
+    return js::IsProxy(this);
+}
+
+inline bool
+JSObject::isCrossCompartmentWrapper() const
+{
+    return js::IsCrossCompartmentWrapper(this);
+}
+
+inline bool
+JSObject::isWrapper() const
+{
+    return js::IsWrapper(this);
+}
+
 static inline bool
 js_IsCallable(const js::Value &v)
 {
     return v.isObject() && v.toObject().isCallable();
 }
 
 inline JSObject *
 js_UnwrapWithObject(JSContext *cx, JSObject *withobj)
@@ -1326,18 +1345,18 @@ NewBuiltinClassInstance(JSContext *cx, C
     VOUCH_DOES_NOT_REQUIRE_STACK();
 
     JSProtoKey protoKey = JSCLASS_CACHED_PROTO_KEY(clasp);
     JS_ASSERT(protoKey != JSProto_Null);
 
     /* NB: inline-expanded and specialized version of js_GetClassPrototype. */
     JSObject *global;
     if (!cx->hasfp()) {
-        global = cx->globalObject;
-        if (!NULLABLE_OBJ_TO_INNER_OBJECT(cx, global))
+        global = JS_ObjectToInnerObject(cx, cx->globalObject);
+        if (!global)
             return NULL;
     } else {
         global = cx->fp()->scopeChain().getGlobal();
     }
     JS_ASSERT(global->isGlobal());
 
     const Value &v = global->getReservedSlot(JSProto_LIMIT + protoKey);
     JSObject *proto;
--- a/js/src/jsparse.h
+++ b/js/src/jsparse.h
@@ -43,16 +43,17 @@
 /*
  * JS parser definitions.
  */
 #include "jsversion.h"
 #include "jsprvtd.h"
 #include "jspubtd.h"
 #include "jsatom.h"
 #include "jsscan.h"
+#include "jsscript.h"
 #include "jswin.h"
 
 #include "frontend/ParseMaps.h"
 
 JS_BEGIN_EXTERN_C
 
 /*
  * Parsing builds a tree of nodes that directs code generation.  This tree is
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -54,17 +54,17 @@
 #include "jsinferinlines.h"
 #include "jsobjinlines.h"
 
 using namespace js;
 using namespace js::gc;
 
 static inline const Value &
 GetCall(JSObject *proxy) {
-    JS_ASSERT(proxy->isFunctionProxy());
+    JS_ASSERT(IsFunctionProxy(proxy));
     return proxy->getSlot(JSSLOT_PROXY_CALL);
 }
 
 static inline Value
 GetConstruct(JSObject *proxy) {
     if (proxy->numSlots() <= JSSLOT_PROXY_CONSTRUCT)
         return UndefinedValue();
     return proxy->getSlot(JSSLOT_PROXY_CONSTRUCT);
@@ -151,17 +151,17 @@ ProxyHandler::set(JSContext *cx, JSObjec
     if (desc.obj) {
         if (desc.attrs & JSPROP_READONLY)
             return true;
         if (!desc.setter) {
             desc.setter = JS_StrictPropertyStub;
         } else if ((desc.attrs & JSPROP_SETTER) || desc.setter != JS_StrictPropertyStub) {
             if (!CallSetter(cx, receiver, id, desc.setter, desc.attrs, desc.shortid, strict, vp))
                 return false;
-            if (!proxy->isProxy() || proxy->getProxyHandler() != this)
+            if (!proxy->isProxy() || GetProxyHandler(proxy) != this)
                 return true;
             if (desc.attrs & JSPROP_SHARED)
                 return true;
         }
         if (!desc.getter)
             desc.getter = JS_PropertyStub;
         desc.value = *vp;
         return defineProperty(cx, receiver, id, &desc);
@@ -171,17 +171,17 @@ ProxyHandler::set(JSContext *cx, JSObjec
     if (desc.obj) {
         if (desc.attrs & JSPROP_READONLY)
             return true;
         if (!desc.setter) {
             desc.setter = JS_StrictPropertyStub;
         } else if ((desc.attrs & JSPROP_SETTER) || desc.setter != JS_StrictPropertyStub) {
             if (!CallSetter(cx, receiver, id, desc.setter, desc.attrs, desc.shortid, strict, vp))
                 return false;
-            if (!proxy->isProxy() || proxy->getProxyHandler() != this)
+            if (!proxy->isProxy() || GetProxyHandler(proxy) != this)
                 return true;
             if (desc.attrs & JSPROP_SHARED)
                 return true;
         }
         if (!desc.getter)
             desc.getter = JS_PropertyStub;
         return defineProperty(cx, receiver, id, &desc);
     }
@@ -235,27 +235,27 @@ ProxyHandler::iterate(JSContext *cx, JSO
     return EnumeratedIdVectorToIterator(cx, proxy, flags, props, vp);
 }
 
 JSString *
 ProxyHandler::obj_toString(JSContext *cx, JSObject *proxy)
 {
     JS_ASSERT(proxy->isProxy());
 
-    return JS_NewStringCopyZ(cx, proxy->isFunctionProxy()
+    return JS_NewStringCopyZ(cx, IsFunctionProxy(proxy)
                                  ? "[object Function]"
                                  : "[object Object]");
 }
 
 JSString *
 ProxyHandler::fun_toString(JSContext *cx, JSObject *proxy, uintN indent)
 {
     JS_ASSERT(proxy->isProxy());
     Value fval = GetCall(proxy);
-    if (proxy->isFunctionProxy() &&
+    if (IsFunctionProxy(proxy) &&
         (fval.isPrimitive() || !fval.toObject().isFunction())) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                              JSMSG_INCOMPATIBLE_PROTO,
                              js_Function_str, js_toString_str,
                              "object");
         return NULL;
     }
     return fun_toStringHelper(cx, &fval.toObject(), indent);
@@ -305,17 +305,17 @@ ProxyHandler::hasInstance(JSContext *cx,
                         JSDVG_SEARCH_STACK, ObjectValue(*proxy), NULL);
     return false;
 }
 
 JSType
 ProxyHandler::typeOf(JSContext *cx, JSObject *proxy)
 {
     JS_ASSERT(OperationInProgress(cx, proxy));
-    return proxy->isFunctionProxy() ? JSTYPE_FUNCTION : JSTYPE_OBJECT;
+    return IsFunctionProxy(proxy) ? JSTYPE_FUNCTION : JSTYPE_OBJECT;
 }
 
 bool
 ProxyHandler::objectClassIs(JSObject *proxy, ESClassValue classValue, JSContext *cx)
 {
     JS_ASSERT(OperationInProgress(cx, proxy));
     return false;
 }
@@ -508,17 +508,17 @@ ReturnedValueMustNotBePrimitive(JSContex
     }
     return true;
 }
 
 static JSObject *
 GetProxyHandlerObject(JSContext *cx, JSObject *proxy)
 {
     JS_ASSERT(OperationInProgress(cx, proxy));
-    return proxy->getProxyPrivate().toObjectOrNull();
+    return GetProxyPrivate(proxy).toObjectOrNull();
 }
 
 bool
 ScriptedProxyHandler::getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set,
                                             PropertyDescriptor *desc)
 {
     JSObject *handler = GetProxyHandlerObject(cx, proxy);
     AutoValueRooter tvr(cx);
@@ -698,17 +698,17 @@ class AutoPendingProxyOperation {
 };
 
 bool
 Proxy::getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set,
                              PropertyDescriptor *desc)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->getPropertyDescriptor(cx, proxy, id, set, desc);
+    return GetProxyHandler(proxy)->getPropertyDescriptor(cx, proxy, id, set, desc);
 }
 
 bool
 Proxy::getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, Value *vp)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
     AutoPropertyDescriptorRooter desc(cx);
@@ -717,17 +717,17 @@ Proxy::getPropertyDescriptor(JSContext *
 }
 
 bool
 Proxy::getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set,
                                 PropertyDescriptor *desc)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->getOwnPropertyDescriptor(cx, proxy, id, set, desc);
+    return GetProxyHandler(proxy)->getOwnPropertyDescriptor(cx, proxy, id, set, desc);
 }
 
 bool
 Proxy::getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, Value *vp)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
     AutoPropertyDescriptorRooter desc(cx);
@@ -735,17 +735,17 @@ Proxy::getOwnPropertyDescriptor(JSContex
            NewPropertyDescriptorObject(cx, &desc, vp);
 }
 
 bool
 Proxy::defineProperty(JSContext *cx, JSObject *proxy, jsid id, PropertyDescriptor *desc)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->defineProperty(cx, proxy, id, desc);
+    return GetProxyHandler(proxy)->defineProperty(cx, proxy, id, desc);
 }
 
 bool
 Proxy::defineProperty(JSContext *cx, JSObject *proxy, jsid id, const Value &v)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
     AutoPropertyDescriptorRooter desc(cx);
@@ -753,168 +753,168 @@ Proxy::defineProperty(JSContext *cx, JSO
            Proxy::defineProperty(cx, proxy, id, &desc);
 }
 
 bool
 Proxy::getOwnPropertyNames(JSContext *cx, JSObject *proxy, AutoIdVector &props)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->getOwnPropertyNames(cx, proxy, props);
+    return GetProxyHandler(proxy)->getOwnPropertyNames(cx, proxy, props);
 }
 
 bool
 Proxy::delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->delete_(cx, proxy, id, bp);
+    return GetProxyHandler(proxy)->delete_(cx, proxy, id, bp);
 }
 
 bool
 Proxy::enumerate(JSContext *cx, JSObject *proxy, AutoIdVector &props)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->enumerate(cx, proxy, props);
+    return GetProxyHandler(proxy)->enumerate(cx, proxy, props);
 }
 
 bool
 Proxy::fix(JSContext *cx, JSObject *proxy, Value *vp)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->fix(cx, proxy, vp);
+    return GetProxyHandler(proxy)->fix(cx, proxy, vp);
 }
 
 bool
 Proxy::has(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->has(cx, proxy, id, bp);
+    return GetProxyHandler(proxy)->has(cx, proxy, id, bp);
 }
 
 bool
 Proxy::hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->hasOwn(cx, proxy, id, bp);
+    return GetProxyHandler(proxy)->hasOwn(cx, proxy, id, bp);
 }
 
 bool
 Proxy::get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, Value *vp)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->get(cx, proxy, receiver, id, vp);
+    return GetProxyHandler(proxy)->get(cx, proxy, receiver, id, vp);
 }
 
 bool
 Proxy::set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, bool strict, Value *vp)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->set(cx, proxy, receiver, id, strict, vp);
+    return GetProxyHandler(proxy)->set(cx, proxy, receiver, id, strict, vp);
 }
 
 bool
 Proxy::keys(JSContext *cx, JSObject *proxy, AutoIdVector &props)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->keys(cx, proxy, props);
+    return GetProxyHandler(proxy)->keys(cx, proxy, props);
 }
 
 bool
 Proxy::iterate(JSContext *cx, JSObject *proxy, uintN flags, Value *vp)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->iterate(cx, proxy, flags, vp);
+    return GetProxyHandler(proxy)->iterate(cx, proxy, flags, vp);
 }
 
 bool
 Proxy::call(JSContext *cx, JSObject *proxy, uintN argc, Value *vp)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->call(cx, proxy, argc, vp);
+    return GetProxyHandler(proxy)->call(cx, proxy, argc, vp);
 }
 
 bool
 Proxy::construct(JSContext *cx, JSObject *proxy, uintN argc, Value *argv, Value *rval)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->construct(cx, proxy, argc, argv, rval);
+    return GetProxyHandler(proxy)->construct(cx, proxy, argc, argv, rval);
 }
 
 bool
 Proxy::nativeCall(JSContext *cx, JSObject *proxy, Class *clasp, Native native, CallArgs args)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->nativeCall(cx, proxy, clasp, native, args);
+    return GetProxyHandler(proxy)->nativeCall(cx, proxy, clasp, native, args);
 }
 
 bool
 Proxy::hasInstance(JSContext *cx, JSObject *proxy, const js::Value *vp, bool *bp)
 {
     JS_CHECK_RECURSION(cx, return false);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->hasInstance(cx, proxy, vp, bp);
+    return GetProxyHandler(proxy)->hasInstance(cx, proxy, vp, bp);
 }
 
 JSType
 Proxy::typeOf(JSContext *cx, JSObject *proxy)
 {
     // FIXME: API doesn't allow us to report error (bug 618906).
     JS_CHECK_RECURSION(cx, return JSTYPE_OBJECT);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->typeOf(cx, proxy);
+    return GetProxyHandler(proxy)->typeOf(cx, proxy);
 }
 
 bool
 Proxy::objectClassIs(JSObject *proxy, ESClassValue classValue, JSContext *cx)
 {
     JS_CHECK_RECURSION(cx, JS_NOT_REACHED("cannot reenter"));
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->objectClassIs(proxy, classValue, cx);
+    return GetProxyHandler(proxy)->objectClassIs(proxy, classValue, cx);
 }
 
 JSString *
 Proxy::obj_toString(JSContext *cx, JSObject *proxy)
 {
     JS_CHECK_RECURSION(cx, return NULL);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->obj_toString(cx, proxy);
+    return GetProxyHandler(proxy)->obj_toString(cx, proxy);
 }
 
 JSString *
 Proxy::fun_toString(JSContext *cx, JSObject *proxy, uintN indent)
 {
     JS_CHECK_RECURSION(cx, return NULL);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->fun_toString(cx, proxy, indent);
+    return GetProxyHandler(proxy)->fun_toString(cx, proxy, indent);
 }
 
 bool
 Proxy::defaultValue(JSContext *cx, JSObject *proxy, JSType hint, Value *vp)
 {
     JS_CHECK_RECURSION(cx, return NULL);
     AutoPendingProxyOperation pending(cx, proxy);
-    return proxy->getProxyHandler()->defaultValue(cx, proxy, hint, vp);
+    return GetProxyHandler(proxy)->defaultValue(cx, proxy, hint, vp);
 }
 
 static JSObject *
 proxy_innerObject(JSContext *cx, JSObject *obj)
 {
-    return obj->getProxyPrivate().toObjectOrNull();
+    return GetProxyPrivate(obj).toObjectOrNull();
 }
 
 static JSBool
 proxy_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
                      JSProperty **propp)
 {
     id = js_CheckForStringIndex(id);
 
@@ -1114,20 +1114,20 @@ static JSBool
 proxy_DeleteSpecial(JSContext *cx, JSObject *obj, SpecialId sid, Value *rval, JSBool strict)
 {
     return proxy_DeleteProperty(cx, obj, SPECIALID_TO_JSID(sid), rval, strict);
 }
 
 static void
 proxy_TraceObject(JSTracer *trc, JSObject *obj)
 {
-    obj->getProxyHandler()->trace(trc, obj);
-    MarkCrossCompartmentValue(trc, obj->getProxyPrivate(), "private");
-    MarkCrossCompartmentValue(trc, obj->getProxyExtra(), "extra");
-    if (obj->isFunctionProxy()) {
+    GetProxyHandler(obj)->trace(trc, obj);
+    MarkCrossCompartmentValue(trc, GetProxyPrivate(obj), "private");
+    MarkCrossCompartmentValue(trc, GetProxyExtra(obj), "extra");
+    if (IsFunctionProxy(obj)) {
         MarkCrossCompartmentValue(trc, GetCall(obj), "call");
         MarkCrossCompartmentValue(trc, GetConstruct(obj), "construct");
     }
 }
 
 static void
 proxy_TraceFunction(JSTracer *trc, JSObject *obj)
 {
@@ -1156,17 +1156,17 @@ proxy_Fix(JSContext *cx, JSObject *obj, 
     return false;
 }
 
 static void
 proxy_Finalize(JSContext *cx, JSObject *obj)
 {
     JS_ASSERT(obj->isProxy());
     if (!obj->getSlot(JSSLOT_PROXY_HANDLER).isUndefined())
-        obj->getProxyHandler()->finalize(cx, obj);
+        GetProxyHandler(obj)->finalize(cx, obj);
 }
 
 static JSBool
 proxy_HasInstance(JSContext *cx, JSObject *proxy, const Value *v, JSBool *bp)
 {
     AutoPendingProxyOperation pending(cx, proxy);
     bool b;
     if (!Proxy::hasInstance(cx, proxy, v, &b))
@@ -1626,17 +1626,17 @@ js::FixProxy(JSContext *cx, JSObject *pr
     }
 
     JSObject *props = NonNullObject(cx, tvr.value());
     if (!props)
         return false;
 
     JSObject *proto = proxy->getProto();
     JSObject *parent = proxy->getParent();
-    Class *clasp = proxy->isFunctionProxy() ? &CallableObjectClass : &ObjectClass;
+    Class *clasp = IsFunctionProxy(proxy) ? &CallableObjectClass : &ObjectClass;
 
     /*
      * Make a blank object from the recipe fix provided to us.  This must have
      * number of fixed slots as the proxy so that we can swap their contents.
      */
     gc::AllocKind kind = proxy->getAllocKind();
     JSObject *newborn = NewNonFunction<WithProto::Given>(cx, clasp, proto, parent, kind);
     if (!newborn)
--- a/js/src/jsproxy.h
+++ b/js/src/jsproxy.h
@@ -39,17 +39,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef jsproxy_h___
 #define jsproxy_h___
 
 #include "jsapi.h"
 #include "jscntxt.h"
-#include "jsobj.h"
+#include "jsfriendapi.h"
 
 namespace js {
 
 /* Base class for all C++ proxy handlers. */
 class JS_FRIEND_API(ProxyHandler) {
     void *mFamily;
   public:
     explicit ProxyHandler(void *family);
@@ -132,72 +132,85 @@ class Proxy {
     static bool hasInstance(JSContext *cx, JSObject *proxy, const Value *vp, bool *bp);
     static JSType typeOf(JSContext *cx, JSObject *proxy);
     static bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx);
     static JSString *obj_toString(JSContext *cx, JSObject *proxy);
     static JSString *fun_toString(JSContext *cx, JSObject *proxy, uintN indent);
     static bool defaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp);
 };
 
+inline bool IsObjectProxy(const JSObject *obj)
+{
+    Class *clasp = GetObjectClass(obj);
+    return clasp == &js::ObjectProxyClass || clasp == &js::OuterWindowProxyClass;
+}
+
+inline bool IsFunctionProxy(const JSObject *obj)
+{
+    Class *clasp = GetObjectClass(obj);
+    return clasp == &js::FunctionProxyClass;
+}
+
+inline bool IsProxy(const JSObject *obj)
+{
+    return IsObjectProxy(obj) || IsFunctionProxy(obj);
+}
+
 /* Shared between object and function proxies. */
 const uint32 JSSLOT_PROXY_HANDLER = 0;
 const uint32 JSSLOT_PROXY_PRIVATE = 1;
 const uint32 JSSLOT_PROXY_EXTRA   = 2;
 /* Function proxies only. */
 const uint32 JSSLOT_PROXY_CALL = 3;
 const uint32 JSSLOT_PROXY_CONSTRUCT = 4;
 
-}  /* namespace js */
-
-inline js::ProxyHandler *
-JSObject::getProxyHandler() const
+inline ProxyHandler *
+GetProxyHandler(const JSObject *obj)
 {
-    JS_ASSERT(isProxy());
-    return (js::ProxyHandler *) getSlot(js::JSSLOT_PROXY_HANDLER).toPrivate();
+    JS_ASSERT(IsProxy(obj));
+    return (ProxyHandler *) GetReservedSlot(obj, JSSLOT_PROXY_HANDLER).toPrivate();
 }
 
-inline const js::Value &
-JSObject::getProxyPrivate() const
+inline const Value &
+GetProxyPrivate(const JSObject *obj)
 {
-    JS_ASSERT(isProxy());
-    return getSlot(js::JSSLOT_PROXY_PRIVATE);
+    JS_ASSERT(IsProxy(obj));
+    return GetReservedSlot(obj, JSSLOT_PROXY_PRIVATE);
 }
 
 inline void
-JSObject::setProxyPrivate(const js::Value &priv)
+SetProxyPrivate(JSObject *obj, const Value &priv)
 {
-    JS_ASSERT(isProxy());
-    setSlot(js::JSSLOT_PROXY_PRIVATE, priv);
+    JS_ASSERT(IsProxy(obj));
+    SetReservedSlot(obj, JSSLOT_PROXY_PRIVATE, priv);
 }
 
-inline const js::Value &
-JSObject::getProxyExtra() const
+inline const Value &
+GetProxyExtra(const JSObject *obj)
 {
-    JS_ASSERT(isProxy());
-    return getSlot(js::JSSLOT_PROXY_EXTRA);
+    JS_ASSERT(IsProxy(obj));
+    return GetReservedSlot(obj, JSSLOT_PROXY_EXTRA);
 }
 
 inline void
-JSObject::setProxyExtra(const js::Value &extra)
+SetProxyExtra(JSObject *obj, const Value &extra)
 {
-    JS_ASSERT(isProxy());
-    setSlot(js::JSSLOT_PROXY_EXTRA, extra);
+    JS_ASSERT(IsProxy(obj));
+    SetReservedSlot(obj, JSSLOT_PROXY_EXTRA, extra);
 }
 
-namespace js {
-
 JS_FRIEND_API(JSObject *)
-NewProxyObject(JSContext *cx, ProxyHandler *handler, const js::Value &priv,
+NewProxyObject(JSContext *cx, ProxyHandler *handler, const Value &priv,
                JSObject *proto, JSObject *parent,
                JSObject *call = NULL, JSObject *construct = NULL);
 
 JS_FRIEND_API(JSBool)
 FixProxy(JSContext *cx, JSObject *proxy, JSBool *bp);
 
-}
+} /* namespace js */
 
 JS_BEGIN_EXTERN_C
 
 extern JS_FRIEND_API(JSObject *)
 js_InitProxyClass(JSContext *cx, JSObject *obj);
 
 JS_END_EXTERN_C
 
--- a/js/src/jsprvtd.h
+++ b/js/src/jsprvtd.h
@@ -394,18 +394,11 @@ typedef JSObject *
  * treat char[] as utf-8 or simply as bytes that need to be inflated/deflated.
  */
 #ifdef JS_C_STRINGS_ARE_UTF8
 # define js_CStringsAreUTF8 JS_TRUE
 #else
 extern JSBool js_CStringsAreUTF8;
 #endif
 
-/*
- * Hack to expose obj->getOps()->outer to the C implementation of the debugger
- * interface.
- */
-extern JS_FRIEND_API(JSObject *)
-js_ObjectToOuterObject(JSContext *cx, JSObject *obj);
-
 JS_END_EXTERN_C
 
 #endif /* jsprvtd_h___ */
--- a/js/src/jsregexp.h
+++ b/js/src/jsregexp.h
@@ -39,16 +39,17 @@
 
 #ifndef jsregexp_h___
 #define jsregexp_h___
 /*
  * JS regular expression interface.
  */
 #include <stddef.h>
 #include "jsprvtd.h"
+#include "jsobj.h"
 #include "jsstr.h"
 #include "jscntxt.h"
 #include "jsvector.h"
 
 #ifdef JS_THREADSAFE
 #include "jsdhash.h"
 #endif
 
--- a/js/src/jsregexpinlines.h
+++ b/js/src/jsregexpinlines.h
@@ -579,17 +579,17 @@ RegExp::decref(JSContext *cx)
 
 inline RegExp *
 RegExp::extractFrom(JSObject *obj)
 {
     JS_ASSERT_IF(obj, obj->isRegExp());
     RegExp *re = static_cast<RegExp *>(obj->getPrivate());
 #ifdef DEBUG
     if (re)
-        CompartmentChecker::check(obj->getCompartment(), re->compartment);
+        CompartmentChecker::check(obj->compartment(), re->compartment);
 #endif
     return re;
 }
 
 /* RegExpStatics inlines. */
 
 inline RegExpStatics *
 RegExpStatics::extractFrom(js::GlobalObject *globalObj)
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -68,16 +68,17 @@
 #if JS_HAS_XDR
 #include "jsxdrapi.h"
 #endif
 #include "methodjit/MethodJIT.h"
 #include "methodjit/Retcon.h"
 #include "vm/Debugger.h"
 
 #include "jsinferinlines.h"
+#include "jsinterpinlines.h"
 #include "jsobjinlines.h"
 #include "jsscriptinlines.h"
 
 using namespace js;
 using namespace js::gc;
 
 namespace js {
 
@@ -764,17 +765,17 @@ script_trace(JSTracer *trc, JSObject *ob
 {
     JSScript *script = (JSScript *) obj->getPrivate();
     if (script) {
         CheckScriptOwner(script, obj);
         MarkScript(trc, script, "script");
     }
 }
 
-Class js::ScriptClass = {
+JS_FRIEND_DATA(Class) js::ScriptClass = {
     "Script",
     JSCLASS_HAS_PRIVATE |
     JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
     JS_PropertyStub,         /* addProperty */
     JS_PropertyStub,         /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -961,16 +961,9 @@ js_CloneScript(JSContext *cx, JSScript *
 /*
  * NB: after a successful JSXDR_DECODE, js_XDRScript callers must do any
  * required subsequent set-up of owning function or script object and then call
  * js_CallNewScriptHook.
  */
 extern JSBool
 js_XDRScript(JSXDRState *xdr, JSScript **scriptp);
 
-inline JSScript *
-JSObject::getScript() const
-{
-    JS_ASSERT(isScript());
-    return static_cast<JSScript *>(getPrivate());
-}
-
 #endif /* jsscript_h___ */
--- a/js/src/jsscriptinlines.h
+++ b/js/src/jsscriptinlines.h
@@ -216,9 +216,16 @@ JSScript::clearNesting()
 {
     js::types::TypeScriptNesting *nesting = this->nesting();
     if (nesting) {
         js::Foreground::delete_(nesting);
         types->nesting = NULL;
     }
 }
 
+inline JSScript *
+JSObject::getScript() const
+{
+    JS_ASSERT(isScript());
+    return static_cast<JSScript *>(getPrivate());
+}
+
 #endif /* jsscriptinlines_h___ */
--- a/js/src/jsstr.h
+++ b/js/src/jsstr.h
@@ -37,20 +37,20 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef jsstr_h___
 #define jsstr_h___
 
 #include <ctype.h>
 #include "jsapi.h"
+#include "jsatom.h"
 #include "jsprvtd.h"
 #include "jshashtable.h"
 #include "jslock.h"
-#include "jsobj.h"
 #include "jscell.h"
 
 #include "vm/Unicode.h"
 
 namespace js {
 
 /* Implemented in jsstrinlines.h */
 class StringBuffer;
@@ -176,29 +176,16 @@ ValueToStringBuffer(JSContext *cx, const
  * an error, otherwise returning a new string reference.
  */
 extern JS_FRIEND_API(JSString *)
 js_ValueToSource(JSContext *cx, const js::Value &v);
 
 namespace js {
 
 /*
- * Compute a hash function from str. The caller can call this function even if
- * str is not a GC-allocated thing.
- */
-inline uint32
-HashChars(const jschar *chars, size_t length)
-{
-    uint32 h = 0;
-    for (; length; chars++, length--)
-        h = JS_ROTATE_LEFT32(h, 4) ^ *chars;
-    return h;
-}
-
-/*
  * Test if strings are equal. The caller can call the function even if str1
  * or str2 are not GC-allocated things.
  */
 extern bool
 EqualStrings(JSContext *cx, JSString *str1, JSString *str2, JSBool *result);
 
 /* EqualStrings is infallible on linear strings. */
 extern bool
@@ -228,39 +215,16 @@ js_strchr(const jschar *s, jschar c);
 extern jschar *
 js_strchr_limit(const jschar *s, jschar c, const jschar *limit);
 
 #define js_strncpy(t, s, n)     memcpy((t), (s), (n) * sizeof(jschar))
 
 namespace js {
 
 /*
- * On encodings:
- *
- * - Some string functions have an optional FlationCoding argument that allow
- *   the caller to force CESU-8 encoding handling. 
- * - Functions that don't take a FlationCoding base their NormalEncoding
- *   behavior on the js_CStringsAreUTF8 value. NormalEncoding is either raw
- *   (simple zero-extension) or UTF-8 depending on js_CStringsAreUTF8.
- * - Functions that explicitly state their encoding do not use the
- *   js_CStringsAreUTF8 value.
- *
- * CESU-8 (Compatibility Encoding Scheme for UTF-16: 8-bit) is a variant of
- * UTF-8 that allows us to store any wide character string as a narrow
- * character string. For strings containing mostly ascii, it saves space.
- * http://www.unicode.org/reports/tr26/
- */
-
-enum FlationCoding
-{
-    NormalEncoding,
-    CESU8Encoding
-};
-
-/*
  * Inflate bytes to jschars. Return null on error, otherwise return the jschar
  * or byte vector that was malloc'ed. length is updated to the length of the
  * new string (in jschars).
  */
 extern jschar *
 InflateString(JSContext *cx, const char *bytes, size_t *length,
               FlationCoding fc = NormalEncoding);
 
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -12202,17 +12202,17 @@ TraceRecorder::nativeSet(JSObject* obj, 
 JS_REQUIRES_STACK RecordingStatus
 TraceRecorder::addDataProperty(JSObject* obj)
 {
     if (!obj->isExtensible())
         RETURN_STOP("assignment adds property to non-extensible object");
 
     // If obj is the global, the global shape is about to change. Note also
     // that since we do not record this case, SETNAME and SETPROP are identical
-    // as far as the tracer is concerned. (js_CheckUndeclaredVarAssignment
+    // as far as the tracer is concerned. (CheckUndeclaredVarAssignment
     // distinguishes the two, in the interpreter.)
     if (obj == globalObj)
         RETURN_STOP("set new property of global object"); // global shape change
 
     // js_AddProperty does not call the addProperty hook.
     Class* clasp = obj->getClass();
     if (clasp->addProperty != JS_PropertyStub)
         RETURN_STOP("set new property of object with addProperty hook");
--- a/js/src/jsval.h
+++ b/js/src/jsval.h
@@ -289,17 +289,17 @@ typedef uint64 JSValueShiftedTag;
 
 #endif /* JS_BITS_PER_WORD */
 
 typedef enum JSWhyMagic
 {
     JS_ARRAY_HOLE,               /* a hole in a dense array */
     JS_ARGS_HOLE,                /* a hole in the args object's array */
     JS_NATIVE_ENUMERATE,         /* indicates that a custom enumerate hook forwarded
-                                  * to js_Enumerate, which really means the object can be
+                                  * to JS_EnumerateState, which really means the object can be
                                   * enumerated like a native object. */
     JS_NO_ITER_VALUE,            /* there is not a pending iterator value */
     JS_GENERATOR_CLOSING,        /* exception value thrown when closing a generator */
     JS_NO_CONSTANT,              /* compiler sentinel value */
     JS_THIS_POISON,              /* used in debug builds to catch tracing errors */
     JS_ARG_POISON,               /* used in debug builds to catch tracing errors */
     JS_SERIALIZE_NO_NODE,        /* an empty subnode in the AST serializer */
     JS_LAZY_ARGUMENTS,           /* lazy arguments value on the stack */
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -63,51 +63,44 @@ using namespace js::gc;
 static int sWrapperFamily;
 
 void *
 Wrapper::getWrapperFamily()
 {
     return &sWrapperFamily;
 }
 
-bool
-JSObject::isWrapper() const
+JS_FRIEND_API(bool)
+js::IsWrapper(const JSObject *wrapper)
 {
-    return isProxy() && getProxyHandler()->family() == &sWrapperFamily;
-}
-
-bool
-JSObject::isCrossCompartmentWrapper() const
-{
-    return isWrapper() && !!(getWrapperHandler()->flags() & Wrapper::CROSS_COMPARTMENT);
+    return wrapper->isProxy() && GetProxyHandler(wrapper)->family() == &sWrapperFamily;
 }
 
-Wrapper *
-JSObject::getWrapperHandler() const
+JS_FRIEND_API(JSObject *)
+js::UnwrapObject(JSObject *wrapped, uintN *flagsp)
 {
-    JS_ASSERT(isWrapper());
-    return static_cast<Wrapper *>(getProxyHandler());
-}
-
-JSObject *
-JSObject::unwrap(uintN *flagsp)
-{
-    JSObject *wrapped = this;
     uintN flags = 0;
     while (wrapped->isWrapper()) {
-        flags |= static_cast<Wrapper *>(wrapped->getProxyHandler())->flags();
-        wrapped = wrapped->getProxyPrivate().toObjectOrNull();
+        flags |= static_cast<Wrapper *>(GetProxyHandler(wrapped))->flags();
+        wrapped = GetProxyPrivate(wrapped).toObjectOrNull();
         if (wrapped->getClass()->ext.innerObject)
             break;
     }
     if (flagsp)
         *flagsp = flags;
     return wrapped;
 }
 
+bool
+js::IsCrossCompartmentWrapper(const JSObject *wrapper)
+{
+    return wrapper->isWrapper() &&
+           !!(Wrapper::wrapperHandler(wrapper)->flags() & Wrapper::CROSS_COMPARTMENT);
+}
+
 Wrapper::Wrapper(uintN flags) : ProxyHandler(&sWrapperFamily), mFlags(flags)
 {
 }
 
 Wrapper::~Wrapper()
 {
 }
 
@@ -346,23 +339,23 @@ void
 Wrapper::trace(JSTracer *trc, JSObject *wrapper)
 {
     MarkObject(trc, *wrappedObject(wrapper), "wrappedObject");
 }
 
 JSObject *
 Wrapper::wrappedObject(const JSObject *wrapper)
 {
-    return wrapper->getProxyPrivate().toObjectOrNull();
+    return GetProxyPrivate(wrapper).toObjectOrNull();
 }
 
 Wrapper *
 Wrapper::wrapperHandler(const JSObject *wrapper)
 {
-    return static_cast<Wrapper *>(wrapper->getProxyHandler());
+    return static_cast<Wrapper *>(GetProxyHandler(wrapper));
 }
 
 bool
 Wrapper::enter(JSContext *cx, JSObject *wrapper, jsid id, Action act, bool *bp)
 {
     *bp = true;
     return true;
 }
@@ -429,17 +422,17 @@ ForceFrame::enter()
 
     return context->stack.pushDummyFrame(context, destination, *scopeChain, frame);
 }
 
 AutoCompartment::AutoCompartment(JSContext *cx, JSObject *target)
     : context(cx),
       origin(cx->compartment),
       target(target),
-      destination(target->getCompartment()),
+      destination(target->compartment()),
       entered(false)
 {
 }
 
 AutoCompartment::~AutoCompartment()
 {
     if (entered)
         leave();
@@ -741,17 +734,17 @@ CrossCompartmentWrapper::construct(JSCon
 }
 
 bool
 CrossCompartmentWrapper::nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs srcArgs)
 {
     JS_ASSERT_IF(!srcArgs.calleev().isUndefined(),
                  srcArgs.callee().getFunctionPrivate()->native() == native);
     JS_ASSERT(&srcArgs.thisv().toObject() == wrapper);
-    JS_ASSERT(!wrapper->unwrap(NULL)->isProxy());
+    JS_ASSERT(!UnwrapObject(wrapper)->isProxy());
 
     JSObject *wrapped = wrappedObject(wrapper);
     AutoCompartment call(cx, wrapped);
     if (!call.enter())
         return false;
 
     InvokeArgsGuard dstArgs;
     if (!cx->stack.pushInvokeArgs(cx, srcArgs.length(), &dstArgs))
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -170,56 +170,19 @@ class JS_FRIEND_API(ForceFrame)
     DummyFrameGuard *frame;
 
   public:
     ForceFrame(JSContext *cx, JSObject *target);
     ~ForceFrame();
     bool enter();
 };
 
-class AutoCompartment
-{
-  public:
-    JSContext * const context;
-    JSCompartment * const origin;
-    JSObject * const target;
-    JSCompartment * const destination;
-  private:
-    Maybe<DummyFrameGuard> frame;
-    bool entered;
-
-  public:
-    AutoCompartment(JSContext *cx, JSObject *target);
-    ~AutoCompartment();
-
-    bool enter();
-    void leave();
-
-  private:
-    // Prohibit copying.
-    AutoCompartment(const AutoCompartment &);
-    AutoCompartment & operator=(const AutoCompartment &);
-};
-
-/*
- * Use this to change the behavior of an AutoCompartment slightly on error. If
- * the exception happens to be an Error object, copy it to the origin compartment
- * instead of wrapping it.
- */
-class ErrorCopier
-{
-    AutoCompartment &ac;
-    JSObject *scope;
-
-  public:
-    ErrorCopier(AutoCompartment &ac, JSObject *scope) : ac(ac), scope(scope) {
-        JS_ASSERT(scope->compartment() == ac.origin);
-    }
-    ~ErrorCopier();
-};
-
 extern JSObject *
 TransparentObjectWrapper(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSObject *parent,
                          uintN flags);
 
-}
+JS_FRIEND_API(bool) IsWrapper(const JSObject *obj);
+JS_FRIEND_API(JSObject *) UnwrapObject(JSObject *obj, uintN *flagsp = NULL);
+bool IsCrossCompartmentWrapper(const JSObject *obj);
+
+} /* namespace js */
 
 #endif
--- a/js/src/methodjit/RematInfo.h
+++ b/js/src/methodjit/RematInfo.h
@@ -38,16 +38,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #if !defined jsjaeger_remat_h__ && defined JS_METHODJIT
 #define jsjaeger_remat_h__
 
 #include "jscntxt.h"
 #include "MachineRegs.h"
 #include "assembler/assembler/MacroAssembler.h"
+#include "vm/Stack.h"
 
 namespace js {
 namespace mjit {
 
 // Lightweight, union-able components of FrameEntry.
 struct StateRemat {
     typedef JSC::MacroAssembler::RegisterID RegisterID;
     typedef JSC::MacroAssembler::Address Address;
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -1194,17 +1194,17 @@ AssertJit(JSContext *cx, uintN argc, jsv
 
 static JSBool
 GC(JSContext *cx, uintN argc, jsval *vp)
 {
     JSCompartment *comp = NULL;
     if (argc == 1) {
         Value arg = vp[2];
         if (arg.isObject())
-            comp = arg.toObject().unwrap()->compartment();
+            comp = UnwrapObject(&arg.toObject())->compartment();
     }
 
     size_t preBytes = cx->runtime->gcBytes;
     JS_CompartmentGC(cx, comp);
 
     char buf[256];
     JS_snprintf(buf, sizeof(buf), "before %lu, after %lu, break %08lx\n",
                 (unsigned long)preBytes, (unsigned long)cx->runtime->gcBytes,
@@ -2713,19 +2713,19 @@ Clone(JSContext *cx, uintN argc, jsval *
         JS_ReportError(cx, "Invalid arguments to clone");
         return JS_FALSE;
     }
 
     jsval *argv = JS_ARGV(cx, vp);
     {
         JSAutoEnterCompartment ac;
         if (!JSVAL_IS_PRIMITIVE(argv[0]) &&
-            JSVAL_TO_OBJECT(argv[0])->isCrossCompartmentWrapper())
+            IsCrossCompartmentWrapper(JSVAL_TO_OBJECT(argv[0])))
         {
-            JSObject *obj = JSVAL_TO_OBJECT(argv[0])->unwrap();
+            JSObject *obj = UnwrapObject(JSVAL_TO_OBJECT(argv[0]));
             if (!ac.enter(cx, obj))
                 return JS_FALSE;
             argv[0] = OBJECT_TO_JSVAL(obj);
         }
         if (!JSVAL_IS_PRIMITIVE(argv[0]) && JSVAL_TO_OBJECT(argv[0])->isFunction()) {
             funobj = JSVAL_TO_OBJECT(argv[0]);
         } else {
             JSFunction *fun = JS_ValueToFunction(cx, argv[0]);
@@ -3002,17 +3002,17 @@ EvalInContext(JSContext *cx, uintN argc,
 
     JSStackFrame *fp = JS_GetScriptedCaller(cx, NULL);
     JSScript *script = JS_GetFrameScript(cx, fp);
     jsbytecode *pc = JS_GetFramePC(cx, fp);
     jsval rval;
     {
         JSAutoEnterCompartment ac;
         uintN flags;
-        JSObject *unwrapped = sobj->unwrap(&flags);
+        JSObject *unwrapped = UnwrapObject(sobj, &flags);
         if (flags & Wrapper::CROSS_COMPARTMENT) {
             sobj = unwrapped;
             if (!ac.enter(cx, sobj))
                 return false;
         }
 
         OBJ_TO_INNER_OBJECT(cx, sobj);
         if (!sobj)
@@ -3145,17 +3145,17 @@ CopyProperty(JSContext *cx, JSObject *ob
         desc.getter = shape->getter();
         if (!desc.getter && !(desc.attrs & JSPROP_GETTER))
             desc.getter = JS_PropertyStub;
         desc.setter = shape->setter();
         if (!desc.setter && !(desc.attrs & JSPROP_SETTER))
             desc.setter = JS_StrictPropertyStub;
         desc.shortid = shape->shortid;
         propFlags = shape->getFlags();
-   } else if (referent->isProxy()) {
+   } else if (IsProxy(referent)) {
         PropertyDescriptor desc;
         if (!Proxy::getOwnPropertyDescriptor(cx, referent, id, false, &desc))
             return false;
         if (!desc.obj)
             return true;
     } else {
         if (!referent->lookupProperty(cx, id, objp, &prop))
             return false;
--- a/js/src/shell/jsworkers.cpp
+++ b/js/src/shell/jsworkers.cpp
@@ -41,16 +41,17 @@
 #ifdef JS_THREADSAFE
 
 #include <string.h>
 #include "prthread.h"
 #include "prlock.h"
 #include "prcvar.h"
 #include "jsapi.h"
 #include "jscntxt.h"
+#include "jsdbgapi.h"
 #include "jshashtable.h"
 #include "jsstdint.h"
 #include "jslock.h"
 #include "jsvector.h"
 #include "jsworkers.h"
 
 extern size_t gMaxStackSize;
 
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -1482,18 +1482,18 @@ Debugger::unwrapDebuggeeArgument(JSConte
     JSObject *obj = NonNullObject(cx, v);
     if (obj) {
         if (obj->getClass() == &DebuggerObject_class) {
             Value rv = v;
             if (!unwrapDebuggeeValue(cx, &rv))
                 return NULL;
             return &rv.toObject();
         }
-        if (obj->isCrossCompartmentWrapper())
-            return &obj->getProxyPrivate().toObject();
+        if (IsCrossCompartmentWrapper(obj))
+            return &GetProxyPrivate(obj).toObject();
     }
     return obj;
 }
 
 JSBool
 Debugger::addDebuggee(JSContext *cx, uintN argc, Value *vp)
 {
     REQUIRE_ARGC("Debugger.addDebuggee", 1);
@@ -1590,17 +1590,17 @@ Debugger::construct(JSContext *cx, uintN
     CallArgs args = CallArgsFromVp(argc, vp);
 
     /* Check that the arguments, if any, are cross-compartment wrappers. */
     for (uintN i = 0; i < argc; i++) {
         const Value &arg = args[i];
         if (!arg.isObject())
             return ReportObjectRequired(cx);
         JSObject *argobj = &arg.toObject();
-        if (!argobj->isCrossCompartmentWrapper()) {
+        if (!IsCrossCompartmentWrapper(argobj)) {
             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CCW_REQUIRED, "Debugger");
             return false;
         }
     }
 
     /* Get Debugger.prototype. */
     Value v;
     if (!args.callee().getProperty(cx, cx->runtime->atomState.classPrototypeAtom, &v))
@@ -1625,17 +1625,17 @@ Debugger::construct(JSContext *cx, uintN
     obj->setPrivate(dbg);
     if (!dbg->init(cx)) {
         cx->delete_(dbg);
         return false;
     }
 
     /* Add the initial debuggees, if any. */
     for (uintN i = 0; i < argc; i++) {
-        GlobalObject *debuggee = args[i].toObject().getProxyPrivate().toObject().getGlobal();
+        GlobalObject *debuggee = GetProxyPrivate(&args[i].toObject()).toObject().getGlobal();
         if (!dbg->addDebuggeeGlobal(cx, debuggee))
             return false;
     }
 
     args.rval().setObject(*obj);
     return true;
 }
 
@@ -3321,17 +3321,17 @@ UnwrapPropDesc(JSContext *cx, Debugger *
 static bool
 WrapIdAndPropDesc(JSContext *cx, JSObject *obj, jsid *idp, PropDesc *desc)
 {
     JSCompartment *comp = cx->compartment;
     return comp->wrapId(cx, idp) &&
            comp->wrap(cx, &desc->value) &&
            comp->wrap(cx, &desc->get) &&
            comp->wrap(cx, &desc->set) &&
-           (!obj->isProxy() || desc->makeObject(cx));
+           (!IsProxy(obj) || desc->makeObject(cx));
 }
 
 static JSBool
 DebuggerObject_defineProperty(JSContext *cx, uintN argc, Value *vp)
 {
     THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "defineProperty", args, dbg, obj);
     REQUIRE_ARGC("Debugger.Object.defineProperty", 2);
 
--- a/js/src/vm/Stack-inl.h
+++ b/js/src/vm/Stack-inl.h
@@ -481,17 +481,17 @@ StackSpace::getStackLimit(JSContext *cx,
            ? conservativeEnd_
            : NULL;
 }
 
 /*****************************************************************************/
 
 JS_ALWAYS_INLINE StackFrame *
 ContextStack::getCallFrame(JSContext *cx, MaybeReportError report, const CallArgs &args,
-                           JSFunction *fun, JSScript *script, StackFrame::Flags *flags) const
+                           JSFunction *fun, JSScript *script, /*StackFrame::Flags*/ uint32 *flags) const
 {
     JS_ASSERT(fun->script() == script);
     uintN nformal = fun->nargs;
 
     Value *firstUnused = args.end();
     JS_ASSERT(firstUnused == space().firstUnused());
 
     /* Include extra space to satisfy the method-jit stackLimit invariant. */
@@ -530,23 +530,23 @@ ContextStack::pushInlineFrame(JSContext 
                               InitialFrameFlags initial)
 {
     JS_ASSERT(onTop());
     JS_ASSERT(regs.sp == args.end());
     /* Cannot assert callee == args.callee() since this is called from LeaveTree. */
     JS_ASSERT(callee.getFunctionPrivate() == fun);
     JS_ASSERT(fun->script() == script);
 
-    StackFrame::Flags flags = ToFrameFlags(initial);
+    /*StackFrame::Flags*/ uint32 flags = ToFrameFlags(initial);
     StackFrame *fp = getCallFrame(cx, REPORT_ERROR, args, fun, script, &flags);
     if (!fp)
         return false;
 
     /* Initialize frame, locals, regs. */
-    fp->initCallFrame(cx, callee, fun, script, args.length(), flags);
+    fp->initCallFrame(cx, callee, fun, script, args.length(), (StackFrame::Flags) flags);
 
     /*
      * N.B. regs may differ from the active registers, if the parent is about
      * to repoint the active registers to regs. See UncachedInlineCall.
      */
     regs.prepareToRun(*fp, script);
     return true;
 }
@@ -566,23 +566,23 @@ JS_ALWAYS_INLINE StackFrame *
 ContextStack::getFixupFrame(JSContext *cx, MaybeReportError report,
                             const CallArgs &args, JSFunction *fun, JSScript *script,
                             void *ncode, InitialFrameFlags initial, Value **stackLimit)
 {
     JS_ASSERT(onTop());
     JS_ASSERT(args.callee().getFunctionPrivate() == fun);
     JS_ASSERT(fun->script() == script);
 
-    StackFrame::Flags flags = ToFrameFlags(initial);
+    /*StackFrame::Flags*/ uint32 flags = ToFrameFlags(initial);
     StackFrame *fp = getCallFrame(cx, report, args, fun, script, &flags);
     if (!fp)
         return NULL;
 
     /* Do not init late prologue or regs; this is done by jit code. */
-    fp->initJitFrameCallerHalf(cx->fp(), flags, ncode);
+    fp->initJitFrameCallerHalf(cx->fp(), (StackFrame::Flags) flags, ncode);
     fp->initJitFrameEarlyPrologue(fun, args.length());
 
     *stackLimit = space().conservativeEnd_;
     return fp;
 }
 
 JS_ALWAYS_INLINE void
 ContextStack::popInlineFrame(FrameRegs &regs)
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -678,22 +678,22 @@ ContextStack::pushInvokeFrame(JSContext 
 {
     JS_ASSERT(onTop());
     JS_ASSERT(space().firstUnused() == args.end());
 
     JSObject &callee = args.callee();
     JSFunction *fun = callee.getFunctionPrivate();
     JSScript *script = fun->script();
 
-    StackFrame::Flags flags = ToFrameFlags(initial);
+    /*StackFrame::Flags*/ uint32 flags = ToFrameFlags(initial);
     StackFrame *fp = getCallFrame(cx, REPORT_ERROR, args, fun, script, &flags);
     if (!fp)
         return false;
 
-    fp->initCallFrame(cx, callee, fun, script, args.length(), flags);
+    fp->initCallFrame(cx, callee, fun, script, args.length(), (StackFrame::Flags) flags);
     ifg->regs_.prepareToRun(*fp, script);
 
     ifg->prevRegs_ = seg_->pushRegs(ifg->regs_);
     JS_ASSERT(space().firstUnused() == ifg->regs_.sp);
     ifg->setPushed(*this);
     return true;
 }
 
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -306,32 +306,16 @@ CallArgsListFromArgv(uintN argc, Value *
 JS_ALWAYS_INLINE CallArgsList
 CallArgsListFromVp(uintN argc, Value *vp, CallArgsList *prev)
 {
     return CallArgsListFromArgv(argc, vp + 2, prev);
 }
 
 /*****************************************************************************/
 
-/* Flags specified for a frame as it is constructed. */
-enum InitialFrameFlags {
-    INITIAL_NONE           =          0,
-    INITIAL_CONSTRUCT      =       0x80, /* == StackFrame::CONSTRUCTING, asserted below */
-    INITIAL_LOWERED        =   0x400000  /* == StackFrame::LOWERED_CALL_APPLY, asserted below */
-};
-
-enum ExecuteType {
-    EXECUTE_GLOBAL         =        0x1, /* == StackFrame::GLOBAL */
-    EXECUTE_DIRECT_EVAL    =        0x8, /* == StackFrame::EVAL */
-    EXECUTE_INDIRECT_EVAL  =        0x9, /* == StackFrame::GLOBAL | EVAL */
-    EXECUTE_DEBUG          =       0x18  /* == StackFrame::EVAL | DEBUGGER */
-};
-
-/*****************************************************************************/
-
 class StackFrame
 {
   public:
     enum Flags {
         /* Primary frame type */
         GLOBAL             =        0x1,  /* frame pushed for a global script */
         FUNCTION           =        0x2,  /* frame pushed for a scripted call */
         DUMMY              =        0x4,  /* frame pushed for bookkeeping */
@@ -1429,325 +1413,37 @@ class StackSegment
     /* For jit access: */
 
     static const size_t offsetOfRegs() { return offsetof(StackSegment, regs_); }
 };
 
 static const size_t VALUES_PER_STACK_SEGMENT = sizeof(StackSegment) / sizeof(Value);
 JS_STATIC_ASSERT(sizeof(StackSegment) % sizeof(Value) == 0);
 
-/*****************************************************************************/
-
-class StackSpace
-{
-    StackSegment  *seg_;
-    Value         *base_;
-    mutable Value *conservativeEnd_;
-#ifdef XP_WIN
-    mutable Value *commitEnd_;
-#endif
-    Value         *defaultEnd_;
-    Value         *trustedEnd_;
-
-    void assertInvariants() const {
-        JS_ASSERT(base_ <= conservativeEnd_);
-#ifdef XP_WIN
-        JS_ASSERT(conservativeEnd_ <= commitEnd_);
-        JS_ASSERT(commitEnd_ <= trustedEnd_);
-#endif
-        JS_ASSERT(conservativeEnd_ <= defaultEnd_);
-        JS_ASSERT(defaultEnd_ <= trustedEnd_);
-    }
-
-    /* The total number of values/bytes reserved for the stack. */
-    static const size_t CAPACITY_VALS  = 512 * 1024;
-    static const size_t CAPACITY_BYTES = CAPACITY_VALS * sizeof(Value);
-
-    /* How much of the stack is initially committed. */
-    static const size_t COMMIT_VALS    = 16 * 1024;
-    static const size_t COMMIT_BYTES   = COMMIT_VALS * sizeof(Value);
-
-    /* How much space is reserved at the top of the stack for trusted JS. */
-    static const size_t BUFFER_VALS    = 16 * 1024;
-    static const size_t BUFFER_BYTES   = BUFFER_VALS * sizeof(Value);
-
-    static void staticAsserts() {
-        JS_STATIC_ASSERT(CAPACITY_VALS % COMMIT_VALS == 0);
-    }
-
-    friend class AllFramesIter;
-    friend class ContextStack;
-    friend class StackFrame;
-
-    /*
-     * Except when changing compartment (see pushDummyFrame), the 'dest'
-     * parameter of ensureSpace is cx->compartment. Ideally, we'd just pass
-     * this directly (and introduce a helper that supplies cx->compartment when
-     * no 'dest' is given). For some compilers, this really hurts performance,
-     * so, instead, a trivially sinkable magic constant is used to indicate
-     * that dest should be cx->compartment.
-     */
-    static const size_t CX_COMPARTMENT = 0xc;
-
-    inline bool ensureSpace(JSContext *cx, MaybeReportError report,
-                            Value *from, ptrdiff_t nvals,
-                            JSCompartment *dest = (JSCompartment *)CX_COMPARTMENT) const;
-    JS_FRIEND_API(bool) ensureSpaceSlow(JSContext *cx, MaybeReportError report,
-                                        Value *from, ptrdiff_t nvals,
-                                        JSCompartment *dest) const;
-
-    StackSegment &findContainingSegment(const StackFrame *target) const;
-
-  public:
-    StackSpace();
-    bool init();
-    ~StackSpace();
+inline Value *
+StackSpace::firstUnused() const { return seg_ ? seg_->end() : base_; }
 
-    /*
-     * Maximum supported value of arguments.length. This bounds the maximum
-     * number of arguments that can be supplied to Function.prototype.apply.
-     * This value also bounds the number of elements parsed in an array
-     * initialiser.
-     *
-     * Since arguments are copied onto the stack, the stack size is the
-     * limiting factor for this constant. Use the max stack size (available to
-     * untrusted code) with an extra buffer so that, after such an apply, the
-     * callee can do a little work without OOMing.
-     */
-    static const uintN ARGS_LENGTH_MAX = CAPACITY_VALS - (2 * BUFFER_VALS);
-
-    /* See stack layout comment above. */
-    Value *firstUnused() const { return seg_ ? seg_->end() : base_; }
-
-    StackSegment &containingSegment(const StackFrame *target) const;
-
-#ifdef JS_TRACER
-    /*
-     * LeaveTree requires stack allocation to rebuild the stack. There is no
-     * good way to handle an OOM for these allocations, so this function checks
-     * that OOM cannot occur using the size of the TraceNativeStorage as a
-     * conservative upper bound.
-     *
-     * Despite taking a 'cx', this function does not report an error if it
-     * returns 'false'.
-     */
-    inline bool ensureEnoughSpaceToEnterTrace(JSContext *cx);
-#endif
-
-    /*
-     * Extra space to reserve on the stack for method JIT frames, beyond the
-     * frame's nslots. This may be used for inlined stack frames, slots storing
-     * loop invariant code, or to reserve space for pushed callee frames. Note
-     * that this space should be reserved when pushing interpreter frames as
-     * well, so that we don't need to check the stack when entering the method
-     * JIT at loop heads or safe points.
-     */
-    static const size_t STACK_JIT_EXTRA = (VALUES_PER_STACK_FRAME + 18) * 10;
+inline bool         ContextStack::hasfp() const     { return seg_ && seg_->maybeRegs(); }
+inline FrameRegs *  ContextStack::maybeRegs() const { return seg_ ? seg_->maybeRegs() : NULL; }
+inline StackFrame * ContextStack::maybefp() const   { return seg_ ? seg_->maybefp() : NULL; }
+inline FrameRegs &  ContextStack::regs() const      { JS_ASSERT(hasfp()); return seg_->regs(); }
+inline StackFrame * ContextStack::fp() const        { JS_ASSERT(hasfp()); return seg_->fp(); }
 
-    /*
-     * Return a limit against which jit code can check for. This limit is not
-     * necessarily the end of the stack since we lazily commit stack memory on
-     * some platforms. Thus, when the stack limit is exceeded, the caller should
-     * use tryBumpLimit to attempt to increase the stack limit by committing
-     * more memory. If the stack is truly exhausted, tryBumpLimit will report an
-     * error and return NULL.
-     *
-     * An invariant of the methodjit is that there is always space to push a
-     * frame on top of the current frame's expression stack (which can be at
-     * most script->nslots deep). getStackLimit ensures that the returned limit
-     * does indeed have this required space and reports an error and returns
-     * NULL if this reserve space cannot be allocated.
-     */
-    inline Value *getStackLimit(JSContext *cx, MaybeReportError report);
-    bool tryBumpLimit(JSContext *cx, Value *from, uintN nvals, Value **limit);
-
-    /* Called during GC: mark segments, frames, and slots under firstUnused. */
-    void mark(JSTracer *trc);
-
-    /* We only report the committed size;  uncommitted size is uninteresting. */
-    JS_FRIEND_API(size_t) committedSize();
-};
-
-/*****************************************************************************/
-
-class ContextStack
-{
-    StackSegment *seg_;
-    StackSpace *space_;
-    JSContext *cx_;
-
-    /*
-     * Return whether this ContextStack is at the top of the contiguous stack.
-     * This is a precondition for extending the current segment by pushing
-     * stack frames or overrides etc.
-     *
-     * NB: Just because a stack is onTop() doesn't mean there is necessarily
-     * a frame pushed on the stack. For this, use hasfp().
-     */
-    bool onTop() const;
+} /* namespace js */
 
-#ifdef DEBUG
-    void assertSpaceInSync() const;
-#else
-    void assertSpaceInSync() const {}
-#endif
-
-    /* Implementation details of push* public interface. */
-    StackSegment *pushSegment(JSContext *cx);
-    enum MaybeExtend { CAN_EXTEND = true, CANT_EXTEND = false };
-    Value *ensureOnTop(JSContext *cx, MaybeReportError report, uintN nvars,
-                       MaybeExtend extend, bool *pushedSeg,
-                       JSCompartment *dest = (JSCompartment *)StackSpace::CX_COMPARTMENT);
-
-    inline StackFrame *
-    getCallFrame(JSContext *cx, MaybeReportError report, const CallArgs &args,
-                 JSFunction *fun, JSScript *script, StackFrame::Flags *pflags) const;
-
-    /* Make pop* functions private since only called by guard classes. */
-    void popSegment();
-    friend class InvokeArgsGuard;
-    void popInvokeArgs(const InvokeArgsGuard &iag);
-    friend class FrameGuard;
-    void popFrame(const FrameGuard &fg);
-    friend class GeneratorFrameGuard;
-    void popGeneratorFrame(const GeneratorFrameGuard &gfg);
-
-    friend class StackIter;
-
-  public:
-    ContextStack(JSContext *cx);
-    ~ContextStack();
-
-    /*** Stack accessors ***/
-
-    /*
-     * A context's stack is "empty" if there are no scripts or natives
-     * executing. Note that JS_SaveFrameChain does factor into this definition.
-     */
-    bool empty() const                { return !seg_; }
-
-    /*
-     * Return whether there has been at least one frame pushed since the most
-     * recent call to JS_SaveFrameChain. Note that natives do not have frames
-     * and dummy frames are frames that do not represent script execution hence
-     * this query has little semantic meaning past "you can call fp()".
-     */
-    bool hasfp() const                { return seg_ && seg_->maybeRegs(); }
-
-    /*
-     * Return the most recent script activation's registers with the same
-     * caveat as hasfp regarding JS_SaveFrameChain.
-     */
-    FrameRegs *maybeRegs() const      { return seg_ ? seg_->maybeRegs() : NULL; }
-    StackFrame *maybefp() const       { return seg_ ? seg_->maybefp() : NULL; }
-
-    /* Faster alternatives to maybe* functions. */
-    FrameRegs &regs() const           { JS_ASSERT(hasfp()); return seg_->regs(); }
-    StackFrame *fp() const            { JS_ASSERT(hasfp()); return seg_->fp(); }
-
-    /* The StackSpace currently hosting this ContextStack. */
-    StackSpace &space() const    { assertSpaceInSync(); return *space_; }
-
-    /* Return whether the given frame is in this context's stack. */
-    bool containsSlow(const StackFrame *target) const;
-
-    /*** Stack manipulation ***/
-
-    /*
-     * pushInvokeArgs allocates |argc + 2| rooted values that will be passed as
-     * the arguments to Invoke. A single allocation can be used for multiple
-     * Invoke calls. The InvokeArgumentsGuard passed to Invoke must come from
-     * an immediately-enclosing (stack-wise) call to pushInvokeArgs.
-     */
-    bool pushInvokeArgs(JSContext *cx, uintN argc, InvokeArgsGuard *ag);
-
-    /* Called by Invoke for a scripted function call. */
-    bool pushInvokeFrame(JSContext *cx, const CallArgs &args,
-                         InitialFrameFlags initial, InvokeFrameGuard *ifg);
+inline bool            JSContext::hasfp() const      { return stack.hasfp(); }
+inline js::StackFrame* JSContext::fp() const         { return stack.fp(); }
+inline js::StackFrame* JSContext::maybefp() const    { return stack.maybefp(); }
+inline js::FrameRegs&  JSContext::regs() const       { return stack.regs(); }
+inline js::FrameRegs*  JSContext::maybeRegs() const  { return stack.maybeRegs(); }
 
-    /* Called by Execute for execution of eval or global code. */
-    bool pushExecuteFrame(JSContext *cx, JSScript *script, const Value &thisv,
-                          JSObject &scopeChain, ExecuteType type,
-                          StackFrame *evalInFrame, ExecuteFrameGuard *efg);
-
-    /*
-     * Called by SendToGenerator to resume a yielded generator. In addition to
-     * pushing a frame onto the VM stack, this function copies over the
-     * floating frame stored in 'gen'. When 'gfg' is destroyed, the destructor
-     * will copy the frame back to the floating frame.
-     */
-    bool pushGeneratorFrame(JSContext *cx, JSGenerator *gen, GeneratorFrameGuard *gfg);
-
-    /*
-     * When changing the compartment of a cx, it is necessary to immediately
-     * change the scope chain to a global in the right compartment since any
-     * amount of general VM code can run before the first scripted frame is
-     * pushed (if at all). This is currently and hackily accomplished by
-     * pushing a "dummy frame" with the correct scope chain. On success, this
-     * function will change the compartment to 'scopeChain.compartment()' and
-     * push a dummy frame for 'scopeChain'. On failure, nothing is changed.
-     */
-    bool pushDummyFrame(JSContext *cx, JSCompartment *dest, JSObject &scopeChain, DummyFrameGuard *dfg);
-
-    /*
-     * An "inline frame" may only be pushed from within the top, active
-     * segment. This is the case for calls made inside mjit code and Interpret.
-     * The 'stackLimit' overload updates 'stackLimit' if it changes.
-     */
-    bool pushInlineFrame(JSContext *cx, FrameRegs &regs, const CallArgs &args,
-                         JSObject &callee, JSFunction *fun, JSScript *script,
-                         InitialFrameFlags initial);
-    bool pushInlineFrame(JSContext *cx, FrameRegs &regs, const CallArgs &args,
-                         JSObject &callee, JSFunction *fun, JSScript *script,
-                         InitialFrameFlags initial, Value **stackLimit);
-    void popInlineFrame(FrameRegs &regs);
-
-    /* Pop a partially-pushed frame after hitting the limit before throwing. */
-    void popFrameAfterOverflow();
+namespace js {
 
-    /* Get the topmost script and optional pc on the stack. */
-    inline JSScript *currentScript(jsbytecode **pc = NULL) const;
-
-    /* Get the scope chain for the topmost scripted call on the stack. */
-    inline JSObject *currentScriptedScopeChain() const;
-
-    /*
-     * Called by the methodjit for an arity mismatch. Arity mismatch can be
-     * hot, so getFixupFrame avoids doing call setup performed by jit code when
-     * FixupArity returns. In terms of work done:
-     *
-     *   getFixupFrame = pushInlineFrame -
-     *                   (fp->initJitFrameLatePrologue + regs->prepareToRun)
-     */
-    StackFrame *getFixupFrame(JSContext *cx, MaybeReportError report,
-                              const CallArgs &args, JSFunction *fun, JSScript *script,
-                              void *ncode, InitialFrameFlags initial, Value **stackLimit);
-
-    bool saveFrameChain();
-    void restoreFrameChain();
-
-    /*
-     * As an optimization, the interpreter/mjit can operate on a local
-     * FrameRegs instance repoint the ContextStack to this local instance.
-     */
-    void repointRegs(FrameRegs *regs) { JS_ASSERT(hasfp()); seg_->repointRegs(regs); }
-
-    /*** For JSContext: ***/
-
-    /*
-     * To avoid indirection, ContextSpace caches a pointer to the StackSpace.
-     * This must be kept coherent with cx->thread->data.space by calling
-     * 'threadReset' whenver cx->thread changes.
-     */
-    void threadReset();
-
-    /*** For jit compiler: ***/
-
-    static size_t offsetOfSeg() { return offsetof(ContextStack, seg_); }
-};
+inline void
+ContextStack::repointRegs(FrameRegs *regs) { JS_ASSERT(hasfp()); seg_->repointRegs(regs); }
 
 /*****************************************************************************/
 
 class InvokeArgsGuard : public CallArgsList
 {
     friend class ContextStack;
     ContextStack *stack_;
     bool pushedSeg_;
new file mode 100644
--- /dev/null
+++ b/js/src/vm/StackSpace.h
@@ -0,0 +1,380 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=4 sw=4 et tw=79 ft=cpp:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is SpiderMonkey JavaScript engine.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Luke Wagner <luke@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef StackSpace_h__
+#define StackSpace_h__
+
+#include "jsprvtd.h"
+
+namespace js {
+
+/* Forward declarations. */
+class FrameGuard;
+class DummyFrameGuard;
+class ExecuteFrameGuard;
+class GeneratorFrameGuard;
+
+/* Flags specified for a frame as it is constructed. */
+enum InitialFrameFlags {
+    INITIAL_NONE           =          0,
+    INITIAL_CONSTRUCT      =       0x80, /* == StackFrame::CONSTRUCTING, asserted in Stack.h */
+    INITIAL_LOWERED        =   0x400000  /* == StackFrame::LOWERED_CALL_APPLY, asserted in Stack.h */
+};
+
+enum ExecuteType {
+    EXECUTE_GLOBAL         =        0x1, /* == StackFrame::GLOBAL */
+    EXECUTE_DIRECT_EVAL    =        0x8, /* == StackFrame::EVAL */
+    EXECUTE_INDIRECT_EVAL  =        0x9, /* == StackFrame::GLOBAL | EVAL */
+    EXECUTE_DEBUG          =       0x18  /* == StackFrame::EVAL | DEBUGGER */
+};
+
+/*****************************************************************************/
+
+class StackSpace
+{
+    StackSegment  *seg_;
+    Value         *base_;
+    mutable Value *conservativeEnd_;
+#ifdef XP_WIN
+    mutable Value *commitEnd_;
+#endif
+    Value         *defaultEnd_;
+    Value         *trustedEnd_;
+
+    void assertInvariants() const {
+        JS_ASSERT(base_ <= conservativeEnd_);
+#ifdef XP_WIN
+        JS_ASSERT(conservativeEnd_ <= commitEnd_);
+        JS_ASSERT(commitEnd_ <= trustedEnd_);
+#endif
+        JS_ASSERT(conservativeEnd_ <= defaultEnd_);
+        JS_ASSERT(defaultEnd_ <= trustedEnd_);
+    }
+
+    /* The total number of values/bytes reserved for the stack. */
+    static const size_t CAPACITY_VALS  = 512 * 1024;
+    static const size_t CAPACITY_BYTES = CAPACITY_VALS * sizeof(Value);
+
+    /* How much of the stack is initially committed. */
+    static const size_t COMMIT_VALS    = 16 * 1024;
+    static const size_t COMMIT_BYTES   = COMMIT_VALS * sizeof(Value);
+
+    /* How much space is reserved at the top of the stack for trusted JS. */
+    static const size_t BUFFER_VALS    = 16 * 1024;
+    static const size_t BUFFER_BYTES   = BUFFER_VALS * sizeof(Value);
+
+    static void staticAsserts() {
+        JS_STATIC_ASSERT(CAPACITY_VALS % COMMIT_VALS == 0);
+    }
+
+    friend class AllFramesIter;
+    friend class ContextStack;
+    friend class StackFrame;
+
+    /*
+     * Except when changing compartment (see pushDummyFrame), the 'dest'
+     * parameter of ensureSpace is cx->compartment. Ideally, we'd just pass
+     * this directly (and introduce a helper that supplies cx->compartment when
+     * no 'dest' is given). For some compilers, this really hurts performance,
+     * so, instead, a trivially sinkable magic constant is used to indicate
+     * that dest should be cx->compartment.
+     */
+    static const size_t CX_COMPARTMENT = 0xc;
+
+    inline bool ensureSpace(JSContext *cx, MaybeReportError report,
+                            Value *from, ptrdiff_t nvals,
+                            JSCompartment *dest = (JSCompartment *)CX_COMPARTMENT) const;
+    JS_FRIEND_API(bool) ensureSpaceSlow(JSContext *cx, MaybeReportError report,
+                                        Value *from, ptrdiff_t nvals,
+                                        JSCompartment *dest) const;
+
+    StackSegment &findContainingSegment(const StackFrame *target) const;
+
+  public:
+    StackSpace();
+    bool init();
+    ~StackSpace();
+
+    /*
+     * Maximum supported value of arguments.length. This bounds the maximum
+     * number of arguments that can be supplied to Function.prototype.apply.
+     * This value also bounds the number of elements parsed in an array
+     * initialiser.
+     *
+     * Since arguments are copied onto the stack, the stack size is the
+     * limiting factor for this constant. Use the max stack size (available to
+     * untrusted code) with an extra buffer so that, after such an apply, the
+     * callee can do a little work without OOMing.
+     */
+    static const uintN ARGS_LENGTH_MAX = CAPACITY_VALS - (2 * BUFFER_VALS);
+
+    /* See stack layout comment in Stack.h. */
+    inline Value *firstUnused() const;
+
+    StackSegment &containingSegment(const StackFrame *target) const;
+
+#ifdef JS_TRACER
+    /*
+     * LeaveTree requires stack allocation to rebuild the stack. There is no
+     * good way to handle an OOM for these allocations, so this function checks
+     * that OOM cannot occur using the size of the TraceNativeStorage as a
+     * conservative upper bound.
+     *
+     * Despite taking a 'cx', this function does not report an error if it
+     * returns 'false'.
+     */
+    inline bool ensureEnoughSpaceToEnterTrace(JSContext *cx);
+#endif
+
+    /*
+     * Extra space to reserve on the stack for method JIT frames, beyond the
+     * frame's nslots. This may be used for inlined stack frames, slots storing
+     * loop invariant code, or to reserve space for pushed callee frames. Note
+     * that this space should be reserved when pushing interpreter frames as
+     * well, so that we don't need to check the stack when entering the method
+     * JIT at loop heads or safe points.
+     */
+    static const size_t STACK_JIT_EXTRA = (/*~VALUES_PER_STACK_FRAME*/ 8 + 18) * 10;
+
+    /*
+     * Return a limit against which jit code can check for. This limit is not
+     * necessarily the end of the stack since we lazily commit stack memory on
+     * some platforms. Thus, when the stack limit is exceeded, the caller should
+     * use tryBumpLimit to attempt to increase the stack limit by committing
+     * more memory. If the stack is truly exhausted, tryBumpLimit will report an
+     * error and return NULL.
+     *
+     * An invariant of the methodjit is that there is always space to push a
+     * frame on top of the current frame's expression stack (which can be at
+     * most script->nslots deep). getStackLimit ensures that the returned limit
+     * does indeed have this required space and reports an error and returns
+     * NULL if this reserve space cannot be allocated.
+     */
+    inline Value *getStackLimit(JSContext *cx, MaybeReportError report);
+    bool tryBumpLimit(JSContext *cx, Value *from, uintN nvals, Value **limit);
+
+    /* Called during GC: mark segments, frames, and slots under firstUnused. */
+    void mark(JSTracer *trc);
+
+    /* We only report the committed size;  uncommitted size is uninteresting. */
+    JS_FRIEND_API(size_t) committedSize();
+};
+
+/*****************************************************************************/
+
+class ContextStack
+{
+    StackSegment *seg_;
+    StackSpace *space_;
+    JSContext *cx_;
+
+    /*
+     * Return whether this ContextStack is at the top of the contiguous stack.
+     * This is a precondition for extending the current segment by pushing
+     * stack frames or overrides etc.
+     *
+     * NB: Just because a stack is onTop() doesn't mean there is necessarily
+     * a frame pushed on the stack. For this, use hasfp().
+     */
+    bool onTop() const;
+
+#ifdef DEBUG
+    void assertSpaceInSync() const;
+#else
+    void assertSpaceInSync() const {}
+#endif
+
+    /* Implementation details of push* public interface. */
+    StackSegment *pushSegment(JSContext *cx);
+    enum MaybeExtend { CAN_EXTEND = true, CANT_EXTEND = false };
+    Value *ensureOnTop(JSContext *cx, MaybeReportError report, uintN nvars,
+                       MaybeExtend extend, bool *pushedSeg,
+                       JSCompartment *dest = (JSCompartment *)StackSpace::CX_COMPARTMENT);
+
+    inline StackFrame *
+    getCallFrame(JSContext *cx, MaybeReportError report, const CallArgs &args,
+                 JSFunction *fun, JSScript *script, /*StackFrame::Flags*/ uint32 *pflags) const;
+
+    /* Make pop* functions private since only called by guard classes. */
+    void popSegment();
+    friend class InvokeArgsGuard;
+    void popInvokeArgs(const InvokeArgsGuard &iag);
+    friend class FrameGuard;
+    void popFrame(const FrameGuard &fg);
+    friend class GeneratorFrameGuard;
+    void popGeneratorFrame(const GeneratorFrameGuard &gfg);
+
+    friend class StackIter;
+
+  public:
+    ContextStack(JSContext *cx);
+    ~ContextStack();
+
+    /*** Stack accessors ***/
+
+    /*
+     * A context's stack is "empty" if there are no scripts or natives
+     * executing. Note that JS_SaveFrameChain does factor into this definition.
+     */
+    bool empty() const                { return !seg_; }
+
+    /*
+     * Return whether there has been at least one frame pushed since the most
+     * recent call to JS_SaveFrameChain. Note that natives do not have frames
+     * and dummy frames are frames that do not represent script execution hence
+     * this query has little semantic meaning past "you can call fp()".
+     */
+    inline bool hasfp() const;
+
+    /*
+     * Return the most recent script activation's registers with the same
+     * caveat as hasfp regarding JS_SaveFrameChain.
+     */
+    inline FrameRegs *maybeRegs() const;
+    inline StackFrame *maybefp() const;
+
+    /* Faster alternatives to maybe* functions. */
+    inline FrameRegs &regs() const;
+    inline StackFrame *fp() const;
+
+    /* The StackSpace currently hosting this ContextStack. */
+    StackSpace &space() const    { assertSpaceInSync(); return *space_; }
+
+    /* Return whether the given frame is in this context's stack. */
+    bool containsSlow(const StackFrame *target) const;
+
+    /*** Stack manipulation ***/
+
+    /*
+     * pushInvokeArgs allocates |argc + 2| rooted values that will be passed as
+     * the arguments to Invoke. A single allocation can be used for multiple
+     * Invoke calls. The InvokeArgumentsGuard passed to Invoke must come from
+     * an immediately-enclosing (stack-wise) call to pushInvokeArgs.
+     */
+    bool pushInvokeArgs(JSContext *cx, uintN argc, InvokeArgsGuard *ag);
+
+    /* Called by Invoke for a scripted function call. */
+    bool pushInvokeFrame(JSContext *cx, const CallArgs &args,
+                         InitialFrameFlags initial, InvokeFrameGuard *ifg);
+
+    /* Called by Execute for execution of eval or global code. */
+    bool pushExecuteFrame(JSContext *cx, JSScript *script, const Value &thisv,
+                          JSObject &scopeChain, ExecuteType type,
+                          StackFrame *evalInFrame, ExecuteFrameGuard *efg);
+
+    /*
+     * Called by SendToGenerator to resume a yielded generator. In addition to
+     * pushing a frame onto the VM stack, this function copies over the
+     * floating frame stored in 'gen'. When 'gfg' is destroyed, the destructor
+     * will copy the frame back to the floating frame.
+     */
+    bool pushGeneratorFrame(JSContext *cx, JSGenerator *gen, GeneratorFrameGuard *gfg);
+
+    /*
+     * When changing the compartment of a cx, it is necessary to immediately
+     * change the scope chain to a global in the right compartment since any
+     * amount of general VM code can run before the first scripted frame is
+     * pushed (if at all). This is currently and hackily accomplished by
+     * pushing a "dummy frame" with the correct scope chain. On success, this
+     * function will change the compartment to 'scopeChain.compartment()' and
+     * push a dummy frame for 'scopeChain'. On failure, nothing is changed.
+     */
+    bool pushDummyFrame(JSContext *cx, JSCompartment *dest, JSObject &scopeChain, DummyFrameGuard *dfg);
+
+    /*
+     * An "inline frame" may only be pushed from within the top, active
+     * segment. This is the case for calls made inside mjit code and Interpret.
+     * The 'stackLimit' overload updates 'stackLimit' if it changes.
+     */
+    bool pushInlineFrame(JSContext *cx, FrameRegs &regs, const CallArgs &args,
+                         JSObject &callee, JSFunction *fun, JSScript *script,
+                         InitialFrameFlags initial);
+    bool pushInlineFrame(JSContext *cx, FrameRegs &regs, const CallArgs &args,
+                         JSObject &callee, JSFunction *fun, JSScript *script,
+                         InitialFrameFlags initial, Value **stackLimit);
+    void popInlineFrame(FrameRegs &regs);
+
+    /* Pop a partially-pushed frame after hitting the limit before throwing. */
+    void popFrameAfterOverflow();
+
+    /* Get the topmost script and optional pc on the stack. */
+    inline JSScript *currentScript(jsbytecode **pc = NULL) const;
+
+    /* Get the scope chain for the topmost scripted call on the stack. */
+    inline JSObject *currentScriptedScopeChain() const;
+
+    /*
+     * Called by the methodjit for an arity mismatch. Arity mismatch can be
+     * hot, so getFixupFrame avoids doing call setup performed by jit code when
+     * FixupArity returns. In terms of work done:
+     *
+     *   getFixupFrame = pushInlineFrame -
+     *                   (fp->initJitFrameLatePrologue + regs->prepareToRun)
+     */
+    StackFrame *getFixupFrame(JSContext *cx, MaybeReportError report,
+                              const CallArgs &args, JSFunction *fun, JSScript *script,
+                              void *ncode, InitialFrameFlags initial, Value **stackLimit);
+
+    bool saveFrameChain();
+    void restoreFrameChain();
+
+    /*
+     * As an optimization, the interpreter/mjit can operate on a local
+     * FrameRegs instance repoint the ContextStack to this local instance.
+     */
+    inline void repointRegs(FrameRegs *regs);
+
+    /*** For JSContext: ***/
+
+    /*
+     * To avoid indirection, ContextSpace caches a pointer to the StackSpace.
+     * This must be kept coherent with cx->thread->data.space by calling
+     * 'threadReset' whenver cx->thread changes.
+     */
+    void threadReset();
+
+    /*** For jit compiler: ***/
+
+    static size_t offsetOfSeg() { return offsetof(ContextStack, seg_); }
+};
+
+} /* namespace js */
+
+#endif /* StackSpace_h__ */
--- a/js/src/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/src/xpconnect/loader/mozJSComponentLoader.cpp
@@ -746,17 +746,17 @@ mozJSComponentLoader::GlobalForLocation(
                                         jsval *exception)
 {
     nsresult rv;
 
     JSPrincipals* jsPrincipals = nsnull;
     JSCLContextHelper cx(this);
 
     // preserve caller's compartment
-    JS::AutoPreserveCompartment pc(cx);
+    js::AutoPreserveCompartment pc(cx);
 
     rv = mSystemPrincipal->GetJSPrincipals(cx, &jsPrincipals);
     NS_ENSURE_SUCCESS(rv, rv);
 
     JSPrincipalsHolder princHolder(mContext, jsPrincipals);
 
     nsCOMPtr<nsIXPCScriptable> backstagePass;
     rv = mRuntimeService->GetBackstagePass(getter_AddRefs(backstagePass));
--- a/js/src/xpconnect/loader/mozJSSubScriptLoader.cpp
+++ b/js/src/xpconnect/loader/mozJSSubScriptLoader.cpp
@@ -393,17 +393,17 @@ mozJSSubScriptLoader::LoadSubScript (con
         nsCAutoString tmp(JS_GetScriptFilename(cx, script));
         tmp.AppendLiteral(" -> ");
         tmp.Append(uriStr);
 
         uriStr = tmp;
     }
 
     bool writeScript = false;
-    JSVersion version = cx->findVersion();
+    JSVersion version = JS_GetVersion(cx);
     nsCAutoString cachePath;
     cachePath.AppendPrintf("jssubloader/%d", version);
     PathifyURI(uri, cachePath);
 
     script = nsnull;
     if (cache)
         rv = ReadCachedScript(cache, cachePath, cx, &script);
     if (!script) {
--- a/js/src/xpconnect/src/XPCWrapper.cpp
+++ b/js/src/xpconnect/src/XPCWrapper.cpp
@@ -63,17 +63,17 @@ UnwrapNW(JSContext *cx, uintN argc, jsva
   }
 
   jsval v = JS_ARGV(cx, vp)[0];
   if (JSVAL_IS_PRIMITIVE(v)) {
     return ThrowException(NS_ERROR_INVALID_ARG, cx);
   }
 
   JSObject *obj = JSVAL_TO_OBJECT(v);
-  if (!obj->isWrapper()) {
+  if (!js::IsWrapper(obj)) {
     JS_SET_RVAL(cx, vp, v);
     return JS_TRUE;
   }
 
   if (xpc::WrapperFactory::IsXrayWrapper(obj) &&
       !xpc::WrapperFactory::IsPartiallyTransparent(obj)) {
     return JS_GetProperty(cx, obj, "wrappedJSObject", vp);
   }
@@ -89,59 +89,59 @@ XrayWrapperConstructor(JSContext *cx, ui
     return ThrowException(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx);
   }
 
   if (JSVAL_IS_PRIMITIVE(vp[2])) {
     return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx);
   }
 
   JSObject *obj = JSVAL_TO_OBJECT(vp[2]);
-  if (!obj->isWrapper()) {
+  if (!js::IsWrapper(obj)) {
     *vp = OBJECT_TO_JSVAL(obj);
     return JS_TRUE;
   }
 
-  obj = obj->unwrap();
+  obj = js::UnwrapObject(obj);
 
   *vp = OBJECT_TO_JSVAL(obj);
   return JS_WrapValue(cx, vp);
 }
 // static
 bool
 AttachNewConstructorObject(XPCCallContext &ccx, JSObject *aGlobalObject)
 {
-  JSObject *xpcnativewrapper =
+  JSFunction *xpcnativewrapper =
     JS_DefineFunction(ccx, aGlobalObject, "XPCNativeWrapper",
                       XrayWrapperConstructor, 1,
                       JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_STUB_GSOPS | JSFUN_CONSTRUCTOR);
   if (!xpcnativewrapper) {
     return PR_FALSE;
   }
-  return JS_DefineFunction(ccx, xpcnativewrapper, "unwrap", UnwrapNW, 1,
+  return JS_DefineFunction(ccx, JS_GetFunctionObject(xpcnativewrapper), "unwrap", UnwrapNW, 1,
                            JSPROP_READONLY | JSPROP_PERMANENT) != nsnull;
 }
 }
 
 namespace XPCWrapper {
 
 JSObject *
 Unwrap(JSContext *cx, JSObject *wrapper)
 {
-  if (wrapper->isWrapper()) {
+  if (js::IsWrapper(wrapper)) {
     if (xpc::AccessCheck::isScriptAccessOnly(cx, wrapper))
       return nsnull;
-    return wrapper->unwrap();
+    return js::UnwrapObject(wrapper);
   }
 
   return nsnull;
 }
 
 JSObject *
 UnsafeUnwrapSecurityWrapper(JSObject *obj)
 {
-  if (obj->isProxy()) {
-    return obj->unwrap();
+  if (js::IsProxy(obj)) {
+    return js::UnwrapObject(obj);
   }
 
   return obj;
 }
 
 }
--- a/js/src/xpconnect/src/XPCWrapper.h
+++ b/js/src/xpconnect/src/XPCWrapper.h
@@ -74,17 +74,17 @@ inline nsIScriptSecurityManager *
 GetSecurityManager()
 {
   return nsXPConnect::gScriptSecurityManager;
 }
 
 inline JSBool
 IsSecurityWrapper(JSObject *wrapper)
 {
-  return wrapper->isWrapper();
+  return js::IsWrapper(wrapper);
 }
 
 /**
  * Given an arbitrary object, Unwrap will return the wrapped object if the
  * passed-in object is a wrapper that Unwrap knows about *and* the
  * currently running code has permission to access both the wrapper and
  * wrapped object.
  *
--- a/js/src/xpconnect/src/nsXPConnect.cpp
+++ b/js/src/xpconnect/src/nsXPConnect.cpp
@@ -1060,17 +1060,17 @@ CreateNewCompartment(JSContext *cx, JSCl
         JSPRINCIPALS_DROP(cx, principals);
 
     if(!tempGlobal)
         return false;
 
     *global = tempGlobal;
     *compartment = tempGlobal->compartment();
 
-    JS::AutoSwitchCompartment sc(cx, *compartment);
+    js::AutoSwitchCompartment sc(cx, *compartment);
     JS_SetCompartmentPrivate(cx, *compartment, priv_holder.forget());
     return true;
 }
 
 nsresult
 xpc_CreateGlobalObject(JSContext *cx, JSClass *clasp,
                        nsIPrincipal *principal, nsISupports *ptr,
                        bool wantXrays, JSObject **global,
@@ -1092,17 +1092,17 @@ xpc_CreateGlobalObject(JSContext *cx, JS
         {
             return UnexpectedFailure(NS_ERROR_FAILURE);
         }
 
         map.Put(&key, *compartment);
     }
     else
     {
-        JS::AutoSwitchCompartment sc(cx, *compartment);
+        js::AutoSwitchCompartment sc(cx, *compartment);
 
         JSObject *tempGlobal = JS_NewGlobalObject(cx, clasp);
         if(!tempGlobal)
             return UnexpectedFailure(NS_ERROR_FAILURE);
         *global = tempGlobal;
     }
 
     return NS_OK;
@@ -1129,17 +1129,17 @@ xpc_CreateMTGlobalObject(JSContext *cx, 
         {
             return UnexpectedFailure(NS_ERROR_UNEXPECTED);
         }
 
         map.Put(ptr, *compartment);
     }
     else
     {
-        JS::AutoSwitchCompartment sc(cx, *compartment);
+        js::AutoSwitchCompartment sc(cx, *compartment);
 
         JSObject *tempGlobal = JS_NewGlobalObject(cx, clasp);
         if(!tempGlobal)
             return UnexpectedFailure(NS_ERROR_FAILURE);
         *global = tempGlobal;
     }
 
     return NS_OK;
--- a/js/src/xpconnect/src/xpccomponents.cpp
+++ b/js/src/xpconnect/src/xpccomponents.cpp
@@ -2752,28 +2752,28 @@ nsXPCComponents_Utils::LookupMethod()
     if(NS_FAILED(rv) || !argv)
         return NS_ERROR_FAILURE;
 
     // first param must be a JSObject
     if(JSVAL_IS_PRIMITIVE(argv[0]))
         return NS_ERROR_XPC_BAD_CONVERT_JS;
 
     JSObject* obj = JSVAL_TO_OBJECT(argv[0]);
-    while(obj && !obj->isWrapper() && !IS_WRAPPER_CLASS(obj->getClass()))
+    while(obj && !js::IsWrapper(obj) && !IS_WRAPPER_CLASS(js::GetObjectClass(obj)))
         obj = JS_GetPrototype(cx, obj);
 
     if(!obj)
         return NS_ERROR_XPC_BAD_CONVERT_JS;
 
     argv[0] = OBJECT_TO_JSVAL(obj);
     rv = nsXPConnect::GetXPConnect()->GetJSObjectOfWrapper(cx, obj, &obj);
     if(NS_FAILED(rv))
         return rv;
 
-    OBJ_TO_INNER_OBJECT(cx, obj);
+    obj = JS_ObjectToInnerObject(cx, obj);
     if(!obj)
         return NS_ERROR_XPC_BAD_CONVERT_JS;
 
     // second param must be a string
     if(!JSVAL_IS_STRING(argv[1]))
         return NS_ERROR_XPC_BAD_CONVERT_JS;
 
     // Make sure the name (argv[1]) that we use for looking up the
@@ -3033,17 +3033,17 @@ SandboxImport(JSContext *cx, uintN argc,
         // Use the second parameter as the function name.
         funname = JS_ValueToString(cx, argv[1]);
         if (!funname)
             return JS_FALSE;
         argv[1] = STRING_TO_JSVAL(funname);
     } else {
         // NB: funobj must only be used to get the JSFunction out.
         JSObject *funobj = JSVAL_TO_OBJECT(argv[0]);
-        if (funobj->isProxy()) {
+        if (js::IsProxy(funobj)) {
             funobj = XPCWrapper::UnsafeUnwrapSecurityWrapper(funobj);
         }
 
         JSAutoEnterCompartment ac;
         if (!ac.enter(cx, funobj)) {
             return JS_FALSE;
         }
 
@@ -3602,17 +3602,17 @@ xpc_EvalInSandbox(JSContext *cx, JSObjec
                 ssm->IsCapabilityEnabled("UniversalXPConnect", &system);
                 NS_ASSERTION(system, "Bad caller!");
             }
         }
     }
 #endif
 
     sandbox = XPCWrapper::UnsafeUnwrapSecurityWrapper(sandbox);
-    if (!sandbox || sandbox->getJSClass() != &SandboxClass) {
+    if (!sandbox || js::GetObjectJSClass(sandbox) != &SandboxClass) {
         return NS_ERROR_INVALID_ARG;
     }
 
     nsIScriptObjectPrincipal *sop =
         (nsIScriptObjectPrincipal*)xpc_GetJSPrivate(sandbox);
     NS_ASSERTION(sop, "Invalid sandbox passed");
     nsCOMPtr<nsIPrincipal> prin = sop->GetPrincipal();
 
@@ -3732,17 +3732,17 @@ xpc_EvalInSandbox(JSContext *cx, JSObjec
             JSAutoRequest req(cx);
             JSAutoEnterCompartment ac;
             if (str) {
                 v = STRING_TO_JSVAL(str);
             }
 
             xpc::CompartmentPrivate *sandboxdata =
                 static_cast<xpc::CompartmentPrivate *>
-                           (JS_GetCompartmentPrivate(cx, sandbox->compartment()));
+                           (JS_GetCompartmentPrivate(cx, js::GetObjectCompartment(sandbox)));
             if (!ac.enter(cx, callingScope) ||
                 !WrapForSandbox(cx, sandboxdata->wantXrays, &v)) {
                 rv = NS_ERROR_FAILURE;
             }
 
             if (NS_SUCCEEDED(rv)) {
                 *rval = v;
             }
@@ -3907,17 +3907,17 @@ nsXPCComponents_Utils::GetGlobalForObjec
   // first argument must be an object
   if(JSVAL_IS_PRIMITIVE(argv[0]))
     return NS_ERROR_XPC_BAD_CONVERT_JS;
 
   JSObject *obj = JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(argv[0]));
   *rval = OBJECT_TO_JSVAL(obj);
 
   // Outerize if necessary.
-  if (JSObjectOp outerize = obj->getClass()->ext.outerObject)
+  if (JSObjectOp outerize = js::GetObjectClass(obj)->ext.outerObject)
       *rval = OBJECT_TO_JSVAL(outerize(cx, obj));
 
   cc->SetReturnValueWasSet(PR_TRUE);
   return NS_OK;
 }
 
 /* jsval createObjectIn(in jsval vobj); */
 NS_IMETHODIMP
@@ -3925,17 +3925,17 @@ nsXPCComponents_Utils::CreateObjectIn(co
 {
     if (!cx)
         return NS_ERROR_FAILURE;
 
     // first argument must be an object
     if(JSVAL_IS_PRIMITIVE(vobj))
         return NS_ERROR_XPC_BAD_CONVERT_JS;
 
-    JSObject *scope = JSVAL_TO_OBJECT(vobj)->unwrap();
+    JSObject *scope = js::UnwrapObject(JSVAL_TO_OBJECT(vobj));
     JSObject *obj;
     {
         JSAutoEnterCompartment ac;
         if(!ac.enter(cx, scope))
             return NS_ERROR_FAILURE;
 
         obj = JS_NewObject(cx, nsnull, nsnull, scope);
         if (!obj)
@@ -3981,17 +3981,17 @@ nsXPCComponents_Utils::MakeObjectPropsNo
 {
     if (!cx)
         return NS_ERROR_FAILURE;
 
     // first argument must be an object
     if(JSVAL_IS_PRIMITIVE(vobj))
         return NS_ERROR_XPC_BAD_CONVERT_JS;
 
-    JSObject *obj = JSVAL_TO_OBJECT(vobj)->unwrap();
+    JSObject *obj = js::UnwrapObject(JSVAL_TO_OBJECT(vobj));
 
     JSAutoEnterCompartment ac;
     if (!ac.enter(cx, obj))
         return NS_ERROR_FAILURE;
 
     js::AutoIdArray ida(cx, JS_Enumerate(cx, obj));
     if (!ida)
         return NS_ERROR_FAILURE;
@@ -4003,17 +4003,17 @@ nsXPCComponents_Utils::MakeObjectPropsNo
         if (!JS_GetPropertyById(cx, obj, id, &v))
             return NS_ERROR_FAILURE;
 
         if (JSVAL_IS_PRIMITIVE(v))
             continue;
 
         JSObject *propobj = JSVAL_TO_OBJECT(v);
         // TODO Deal with non-functions.
-        if (!propobj->isWrapper() || !JS_ObjectIsCallable(cx, propobj))
+        if (!js::IsWrapper(propobj) || !JS_ObjectIsCallable(cx, propobj))
             continue;
 
         if (!WrapCallable(cx, obj, id, propobj, &v) ||
             !JS_SetPropertyById(cx, obj, id, &v))
             return NS_ERROR_FAILURE;
     }
 
     return NS_OK;
--- a/js/src/xpconnect/src/xpcconvert.cpp
+++ b/js/src/xpconnect/src/xpcconvert.cpp
@@ -151,17 +151,17 @@ XPCConvert::IsMethodReflectable(const XP
 }
 
 /***************************************************************************/
 
 // static
 JSBool
 XPCConvert::GetISupportsFromJSObject(JSObject* obj, nsISupports** iface)
 {
-    JSClass* jsclass = obj->getJSClass();
+    JSClass* jsclass = js::GetObjectJSClass(obj);
     NS_ASSERTION(jsclass, "obj has no class");
     if(jsclass &&
        (jsclass->flags & JSCLASS_HAS_PRIVATE) &&
        (jsclass->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS))
     {
         *iface = (nsISupports*) xpc_GetJSPrivate(obj);
         return JS_TRUE;
     }
@@ -244,17 +244,17 @@ XPCConvert::NativeData2JS(XPCLazyCallCon
     NS_PRECONDITION(s, "bad param");
     NS_PRECONDITION(d, "bad param");
 
    JSContext* cx = lccx.GetJSContext();
 
     // Allow wrong compartment or unset ScopeForNewObject when the caller knows
     // the value is primitive (viz., XPCNativeMember::GetConstantValue).
     NS_ABORT_IF_FALSE(type.IsArithmetic() ||
-                      cx->compartment == lccx.GetScopeForNewJSObjects()->compartment(),
+                      cx->compartment == js::GetObjectCompartment(lccx.GetScopeForNewJSObjects()),
                       "bad scope for new JSObjects");
 
     if(pErr)
         *pErr = NS_ERROR_XPC_BAD_CONVERT_NATIVE;
 
     switch(type.TagPart())
     {
     case nsXPTType::T_I8    : *d = INT_TO_JSVAL((int32)*((int8*)s));                 break;
@@ -492,18 +492,18 @@ XPCConvert::NativeData2JS(XPCLazyCallCon
                     xpcObjectHelper helper(iface);
                     if(!NativeInterface2JSObject(lccx, d, nsnull, helper, iid,
                                                  nsnull, PR_TRUE,
                                                  OBJ_IS_NOT_GLOBAL, pErr))
                         return JS_FALSE;
 
 #ifdef DEBUG
                     JSObject* jsobj = JSVAL_TO_OBJECT(*d);
-                    if(jsobj && !jsobj->getParent())
-                        NS_ASSERTION(jsobj->getClass()->flags & JSCLASS_IS_GLOBAL,
+                    if(jsobj && !js::GetObjectParent(jsobj))
+                        NS_ASSERTION(js::GetObjectClass(jsobj)->flags & JSCLASS_IS_GLOBAL,
                                      "Why did we recreate this wrapper?");
 #endif
                 }
                 break;
             }
 
         default:
             NS_ERROR("bad type");
@@ -1133,17 +1133,17 @@ XPCConvert::NativeInterface2JSObject(XPC
     // We used to have code here that unwrapped and simply exposed the
     // underlying JSObject. That caused anomolies when JSComponents were
     // accessed from other JS code - they didn't act like other xpconnect
     // wrapped components. So, instead, we create "double wrapped" objects
     // (that means an XPCWrappedNative around an nsXPCWrappedJS). This isn't
     // optimal -- we could detect this and roll the functionality into a
     // single wrapper, but the current solution is good enough for now.
     JSContext* cx = lccx.GetJSContext();
-    NS_ABORT_IF_FALSE(lccx.GetScopeForNewJSObjects()->compartment() == cx->compartment,
+    NS_ABORT_IF_FALSE(js::GetObjectCompartment(lccx.GetScopeForNewJSObjects()) == cx->compartment,
                       "bad scope for new JSObjects");
 
     JSObject *jsscope = lccx.GetScopeForNewJSObjects();
     XPCWrappedNativeScope* xpcscope =
         XPCWrappedNativeScope::FindInJSObjectScope(cx, jsscope);
     if(!xpcscope)
         return JS_FALSE;
 
@@ -1178,17 +1178,17 @@ XPCConvert::NativeInterface2JSObject(XPC
         if(!dest)
         {
             if(!flat)
             {
                 tryConstructSlimWrapper = PR_TRUE;
             }
             else if(IS_SLIM_WRAPPER_OBJECT(flat))
             {
-                if(flat->compartment() == cx->compartment)
+                if(js::GetObjectCompartment(flat) == cx->compartment)
                 {
                     *d = OBJECT_TO_JSVAL(flat);
                     return JS_TRUE;
                 }
             }
         }
     }
     else
@@ -1241,17 +1241,17 @@ XPCConvert::NativeInterface2JSObject(XPC
             if(!iface)
                 return JS_FALSE;
 
             if(Interface)
                 *Interface = iface;
         }
     }
 
-    NS_ASSERTION(!flat || IS_WRAPPER_CLASS(flat->getClass()),
+    NS_ASSERTION(!flat || IS_WRAPPER_CLASS(js::GetObjectClass(flat)),
                  "What kind of wrapper is this?");
 
     nsresult rv;
     XPCWrappedNative* wrapper;
     nsRefPtr<XPCWrappedNative> strongWrapper;
     if(!flat)
     {
         XPCCallContext &ccx = lccx.GetXPCCallContext();
@@ -1363,19 +1363,19 @@ XPCConvert::NativeInterface2JSObject(XPC
                 // the identity of this node.
                 wrapper->SetWrapper(sowWrapper);
             }
 
             flat = sowWrapper;
         }
         else
         {
-            OBJ_TO_OUTER_OBJECT(cx, flat);
+            flat = JS_ObjectToOuterObject(cx, flat);
             NS_ASSERTION(flat, "bad outer object hook!");
-            NS_ASSERTION(flat->compartment() == cx->compartment,
+            NS_ASSERTION(js::GetObjectCompartment(flat) == cx->compartment,
                          "bad compartment");
         }
     }
 
     *d = OBJECT_TO_JSVAL(flat);
 
     if(dest)
     {
@@ -1837,17 +1837,17 @@ XPCConvert::NativeArray2JS(XPCLazyCallCo
     NS_PRECONDITION(s, "bad param");
     NS_PRECONDITION(d, "bad param");
 
     XPCCallContext& ccx = lccx.GetXPCCallContext();
     if(!ccx.IsValid())
         return JS_FALSE;
 
     JSContext* cx = ccx.GetJSContext();
-    NS_ABORT_IF_FALSE(lccx.GetScopeForNewJSObjects()->compartment() == cx->compartment,
+    NS_ABORT_IF_FALSE(js::GetObjectCompartment(lccx.GetScopeForNewJSObjects()) == cx->compartment,
                       "bad scope for new JSObjects");
 
     // XXX add support for putting chars in a string rather than an array
 
     // XXX add support to indicate *which* array element was not convertable
 
     JSObject *array = JS_NewArrayObject(cx, count, nsnull);
 
--- a/js/src/xpconnect/src/xpcdebug.cpp
+++ b/js/src/xpconnect/src/xpcdebug.cpp
@@ -443,17 +443,17 @@ private:
 
 static const int tab_width = 2;
 #define INDENT(_d) (_d)*tab_width, " "
 
 static void PrintObjectBasics(JSObject* obj)
 {
     if (JS_IsNative(obj))
         printf("%p 'native' <%s>",
-               (void *)obj, obj->getClass()->name);
+               (void *)obj, js::GetObjectClass(obj)->name);
     else
         printf("%p 'host'", (void *)obj);
 }
 
 static void PrintObject(JSObject* obj, int depth, ObjectPile* pile)
 {
     PrintObjectBasics(obj);
 
@@ -468,18 +468,18 @@ static void PrintObject(JSObject* obj, i
     case ObjectPile::overflow:
         puts(" (TOO MANY OBJECTS)");
         return;
     }
 
     if(!JS_IsNative(obj))
         return;
 
-    JSObject* parent = obj->getParent();
-    JSObject* proto  = obj->getProto();
+    JSObject* parent = js::GetObjectParent(obj);
+    JSObject* proto  = js::GetObjectProto(obj);
 
     printf("%*sparent: ", INDENT(depth+1));
     if(parent)
         PrintObject(parent, depth+1, pile);
     else
         puts("null");
     printf("%*sproto: ", INDENT(depth+1));
     if(proto)
--- a/js/src/xpconnect/src/xpcinlines.h
+++ b/js/src/xpconnect/src/xpcinlines.h
@@ -160,17 +160,17 @@ XPCCallContext::GetScopeForNewJSObjects(
     CHECK_STATE(HAVE_SCOPE);
     return mScopeForNewJSObjects;
 }
 
 inline void
 XPCCallContext::SetScopeForNewJSObjects(JSObject *scope)
 {
     NS_ABORT_IF_FALSE(mState == HAVE_CONTEXT, "wrong call context state");
-    NS_ABORT_IF_FALSE(scope->compartment() == mJSContext->compartment, "wrong compartment");
+    NS_ABORT_IF_FALSE(js::GetObjectCompartment(scope) == mJSContext->compartment, "wrong compartment");
     mScopeForNewJSObjects = scope;
     mState = HAVE_SCOPE;
 }
 
 inline JSObject*
 XPCCallContext::GetFlattenedJSObject() const
 {
     CHECK_STATE(HAVE_OBJECT);
--- a/js/src/xpconnect/src/xpcjsruntime.cpp
+++ b/js/src/xpconnect/src/xpcjsruntime.cpp
@@ -103,17 +103,17 @@ WrappedJSDyingJSObjectFinder(JSDHashTabl
     nsXPCWrappedJS* wrapper = ((JSObject2WrappedJSMap::Entry*)hdr)->value;
     NS_ASSERTION(wrapper, "found a null JS wrapper!");
 
     // walk the wrapper chain and find any whose JSObject is to be finalized
     while(wrapper)
     {
         if(wrapper->IsSubjectToFinalization())
         {
-            JS::AutoSwitchCompartment sc(data->cx,
+            js::AutoSwitchCompartment sc(data->cx,
                                          wrapper->GetJSObjectPreserveColor());
             if(JS_IsAboutToBeFinalized(data->cx,
                                        wrapper->GetJSObjectPreserveColor()))
                 data->array->AppendElement(wrapper);
         }
         wrapper = wrapper->GetNextWrapper();
     }
     return JS_DHASH_NEXT;
--- a/js/src/xpconnect/src/xpcprivate.h
+++ b/js/src/xpconnect/src/xpcprivate.h
@@ -50,21 +50,21 @@
 #include <stdlib.h>
 #include <stdarg.h>
 #include <math.h>
 #include "xpcpublic.h"
 #include "jsapi.h"
 #include "jsdhash.h"
 #include "jsprf.h"
 #include "prprf.h"
-#include "jsinterp.h"
 #include "jscntxt.h"
 #include "jsdbgapi.h"
 #include "jsfriendapi.h"
 #include "jsgc.h"
+#include "jswrapper.h"
 #include "nscore.h"
 #include "nsXPCOM.h"
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsCycleCollector.h"
 #include "nsDebug.h"
 #include "nsISupports.h"
 #include "nsIServiceManager.h"
@@ -2345,17 +2345,17 @@ extern JSBool ConstructSlimWrapper(XPCCa
                                    xpcObjectHelper &aHelper,
                                    XPCWrappedNativeScope* xpcScope,
                                    jsval *rval);
 extern JSBool MorphSlimWrapper(JSContext *cx, JSObject *obj);
 
 static inline XPCWrappedNativeProto*
 GetSlimWrapperProto(JSObject *obj)
 {
-  const js::Value &v = obj->getSlot(0);
+  const js::Value &v = js::GetReservedSlot(obj, 0);
   return static_cast<XPCWrappedNativeProto*>(v.toPrivate());
 }
 
 
 /***********************************************/
 // XPCWrappedNativeTearOff represents the info needed to make calls to one
 // interface on the underlying native object of a XPCWrappedNative.
 
@@ -4334,17 +4334,17 @@ private:
 NS_DEFINE_STATIC_IID_ACCESSOR(PrincipalHolder, PRINCIPALHOLDER_IID)
 
 /***************************************************************************/
 // Utilities
 
 inline void *
 xpc_GetJSPrivate(JSObject *obj)
 {
-    return obj->getPrivate();
+    return js::GetObjectPrivate(obj);
 }
 
 
 // Helper for creating a sandbox object to use for evaluating
 // untrusted code completely separated from all other code in the
 // system using xpc_EvalInSandbox(). Takes the JSContext on which to
 // do setup etc on, puts the sandbox object in *vp (which must be
 // rooted by the caller), and uses the principal that's either
--- a/js/src/xpconnect/src/xpcpublic.h
+++ b/js/src/xpconnect/src/xpcpublic.h
@@ -36,18 +36,18 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef xpcpublic_h
 #define xpcpublic_h
 
 #include "jsapi.h"
+#include "jsclass.h"
 #include "jsfriendapi.h"
-#include "jsobj.h"
 #include "jsgc.h"
 #include "jspubtd.h"
 
 #include "nsISupports.h"
 #include "nsIPrincipal.h"
 #include "nsWrapperCache.h"
 #include "nsStringGlue.h"
 #include "nsTArray.h"
@@ -76,45 +76,45 @@ nsresult
 xpc_MorphSlimWrapper(JSContext *cx, nsISupports *tomorph);
 
 #define IS_WRAPPER_CLASS(clazz)                                               \
     ((clazz)->ext.isWrappedNative)
 
 inline JSBool
 DebugCheckWrapperClass(JSObject* obj)
 {
-    NS_ASSERTION(IS_WRAPPER_CLASS(obj->getClass()),
+    NS_ASSERTION(IS_WRAPPER_CLASS(js::GetObjectClass(obj)),
                  "Forgot to check if this is a wrapper?");
     return JS_TRUE;
 }
 
 // If IS_WRAPPER_CLASS for the JSClass of an object is true, the object can be
 // a slim wrapper, holding a native in its private slot, or a wrappednative
 // wrapper, holding the XPCWrappedNative in its private slot. A slim wrapper
 // also holds a pointer to its XPCWrappedNativeProto in a reserved slot, we can
 // check that slot for a non-void value to distinguish between the two.
 
-// Only use these macros if IS_WRAPPER_CLASS(obj->getClass()) is true.
+// Only use these macros if IS_WRAPPER_CLASS(GetObjectClass(obj)) is true.
 #define IS_WN_WRAPPER_OBJECT(obj)                                             \
-    (DebugCheckWrapperClass(obj) && obj->getSlot(0).isUndefined())
+    (DebugCheckWrapperClass(obj) && js::GetReservedSlot(obj, 0).isUndefined())
 #define IS_SLIM_WRAPPER_OBJECT(obj)                                           \
-    (DebugCheckWrapperClass(obj) && !obj->getSlot(0).isUndefined())
+    (DebugCheckWrapperClass(obj) && !js::GetReservedSlot(obj, 0).isUndefined())
 
-// Use these macros if IS_WRAPPER_CLASS(obj->getClass()) might be false.
-// Avoid calling them if IS_WRAPPER_CLASS(obj->getClass()) can only be
+// Use these macros if IS_WRAPPER_CLASS(GetObjectClass(obj)) might be false.
+// Avoid calling them if IS_WRAPPER_CLASS(GetObjectClass(obj)) can only be
 // true, as we'd do a redundant call to IS_WRAPPER_CLASS.
 #define IS_WN_WRAPPER(obj)                                                    \
-    (IS_WRAPPER_CLASS(obj->getClass()) && IS_WN_WRAPPER_OBJECT(obj))
+    (IS_WRAPPER_CLASS(js::GetObjectClass(obj)) && IS_WN_WRAPPER_OBJECT(obj))
 #define IS_SLIM_WRAPPER(obj)                                                  \
-    (IS_WRAPPER_CLASS(obj->getClass()) && IS_SLIM_WRAPPER_OBJECT(obj))
+    (IS_WRAPPER_CLASS(js::GetObjectClass(obj)) && IS_SLIM_WRAPPER_OBJECT(obj))
 
 inline JSObject *
 xpc_GetGlobalForObject(JSObject *obj)
 {
-    while(JSObject *parent = obj->getParent())
+    while(JSObject *parent = js::GetObjectParent(obj))
         obj = parent;
     return obj;
 }
 
 extern bool
 xpc_OkToHandOutWrapper(nsWrapperCache *cache);
 
 inline JSObject*
@@ -122,17 +122,17 @@ xpc_FastGetCachedWrapper(nsWrapperCache 
 {
     if (cache) {
         JSObject* wrapper = cache->GetWrapper();
         NS_ASSERTION(!wrapper ||
                      !cache->IsProxy() ||
                      !IS_SLIM_WRAPPER_OBJECT(wrapper),
                      "Should never have a slim wrapper when IsProxy()");
         if (wrapper &&
-            wrapper->compartment() == scope->getCompartment() &&
+            js::GetObjectCompartment(wrapper) == js::GetObjectCompartment(scope) &&
             (IS_SLIM_WRAPPER_OBJECT(wrapper) ||
              xpc_OkToHandOutWrapper(cache))) {
             *vp = OBJECT_TO_JSVAL(wrapper);
             return wrapper;
         }
     }
 
     return nsnull;
--- a/js/src/xpconnect/src/xpcquickstubs.cpp
+++ b/js/src/xpconnect/src/xpcquickstubs.cpp
@@ -307,20 +307,20 @@ LookupGetterOrSetter(JSContext *cx, JSBo
     }
 
     // Since XPConnect doesn't use JSPropertyOps in any other contexts,
     // ensuring that we have an XPConnect prototype object ensures that
     // we are only going to expose quickstubbed properties to script.
     // Also be careful not to overwrite existing properties!
 
     if(!JSID_IS_STRING(id) ||
-       !IS_PROTO_CLASS(desc.obj->getClass()) ||
+       !IS_PROTO_CLASS(js::GetObjectClass(desc.obj)) ||
        (desc.attrs & (JSPROP_GETTER | JSPROP_SETTER)) ||
        !(desc.getter || desc.setter) ||
-       desc.setter == desc.obj->getJSClass()->setProperty)
+       desc.setter == js::GetObjectJSClass(desc.obj)->setProperty)
     {
         JS_SET_RVAL(cx, vp, JSVAL_VOID);
         return JS_TRUE;
     }
 
     JSObject *getterobj, *setterobj;
     if(!ReifyPropertyOps(cx, desc.obj, id, desc.attrs, desc.getter, desc.setter,
                          &getterobj, &setterobj))
@@ -356,17 +356,17 @@ DefineGetterOrSetter(JSContext *cx, uint
     JSObject *obj2;
     jsval v;
     jsid id;
 
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
-    JSNative forward = wantGetter ? js_obj_defineGetter : js_obj_defineSetter;
+    JSNative forward = wantGetter ? js::obj_defineGetter : js::obj_defineSetter;
     jsval idval = (argc >= 1) ? JS_ARGV(cx, vp)[0] : JSVAL_VOID;
     if(!JSVAL_IS_STRING(idval))
         return forward(cx, argc, vp);
 
     if(!JS_ValueToId(cx, idval, &id) ||
        !JS_LookupPropertyWithFlagsById(cx, obj, id,
                                        JSRESOLVE_QUALIFIED, &obj2, &v) ||
        (obj2 &&
@@ -374,17 +374,17 @@ DefineGetterOrSetter(JSContext *cx, uint
                                                 &found, &getter, &setter)))
         return JS_FALSE;
 
     // The property didn't exist, already has a getter or setter, or is not
     // our property, then just forward now.
     if(!obj2 ||
        (attrs & (JSPROP_GETTER | JSPROP_SETTER)) ||
        !(getter || setter) ||
-       !IS_PROTO_CLASS(obj2->getClass()))
+       !IS_PROTO_CLASS(js::GetObjectClass(obj2)))
         return forward(cx, argc, vp);
 
     // Reify the getter and setter...
     if(!ReifyPropertyOps(cx, obj2, id, attrs, getter, setter, nsnull, nsnull))
         return JS_FALSE;
 
     return forward(cx, argc, vp);
 }
@@ -510,27 +510,27 @@ GetMemberInfo(JSObject *obj, jsid member
 {
     // Get the interface name.  From DefinePropertyIfFound (in
     // xpcwrappednativejsops.cpp) and XPCThrower::Verbosify.
     //
     // We could instead make the quick stub could pass in its interface name,
     // but this code often produces a more specific error message, e.g.
     *ifaceName = "Unknown";
 
-    NS_ASSERTION(IS_WRAPPER_CLASS(obj->getClass()) ||
-                 obj->getClass() == &XPC_WN_Tearoff_JSClass,
+    NS_ASSERTION(IS_WRAPPER_CLASS(js::GetObjectClass(obj)) ||
+                 js::GetObjectClass(obj) == &XPC_WN_Tearoff_JSClass,
                  "obj must be a wrapper");
     XPCWrappedNativeProto *proto;
     if(IS_SLIM_WRAPPER(obj))
     {
         proto = GetSlimWrapperProto(obj);
     }
     else
     {
-        XPCWrappedNative *wrapper = (XPCWrappedNative *) obj->getPrivate();
+        XPCWrappedNative *wrapper = (XPCWrappedNative *) js::GetObjectPrivate(obj);
         proto = wrapper->GetProto();
     }
     if(proto)
     {
         XPCNativeSet *set = proto->GetSet();
         if(set)
         {
             XPCNativeMember *member;
@@ -1147,18 +1147,18 @@ xpc_qsXPCOMObjectToJsval(XPCLazyCallCont
         // method really ought to be fixed to behave consistently.
         if(!JS_IsExceptionPending(cx))
             xpc_qsThrow(cx, NS_FAILED(rv) ? rv : NS_ERROR_UNEXPECTED);
         return JS_FALSE;
     }
 
 #ifdef DEBUG
     JSObject* jsobj = JSVAL_TO_OBJECT(*rval);
-    if(jsobj && !jsobj->getParent())
-        NS_ASSERTION(jsobj->getClass()->flags & JSCLASS_IS_GLOBAL,
+    if(jsobj && !js::GetObjectParent(jsobj))
+        NS_ASSERTION(js::GetObjectClass(jsobj)->flags & JSCLASS_IS_GLOBAL,
                      "Why did we recreate this wrapper?");
 #endif
 
     return JS_TRUE;
 }
 
 JSBool
 xpc_qsVariantToJsval(XPCLazyCallContext &lccx,
--- a/js/src/xpconnect/src/xpcquickstubs.h
+++ b/js/src/xpconnect/src/xpcquickstubs.h
@@ -563,17 +563,17 @@ castNativeFromWrapper(JSContext *cx,
                       jsval *pVal,
                       XPCLazyCallContext *lccx,
                       nsresult *rv NS_OUTPARAM)
 {
     XPCWrappedNative *wrapper;
     XPCWrappedNativeTearOff *tearoff;
     JSObject *cur;
 
-    if(!callee && IS_WRAPPER_CLASS(obj->getClass()))
+    if(!callee && IS_WRAPPER_CLASS(js::GetObjectClass(obj)))
     {
         cur = obj;
         wrapper = IS_WN_WRAPPER_OBJECT(cur) ?
                   (XPCWrappedNative*)xpc_GetJSPrivate(obj) :
                   nsnull;
         tearoff = nsnull;
     }
     else
@@ -596,20 +596,20 @@ castNativeFromWrapper(JSContext *cx,
                  nsnull;
     }
 
     *rv = NS_ERROR_XPC_BAD_CONVERT_JS;
 
     if(!native)
         return nsnull;
 
-    NS_ASSERTION(IS_WRAPPER_CLASS(cur->getClass()), "Not a wrapper?");
+    NS_ASSERTION(IS_WRAPPER_CLASS(js::GetObjectClass(cur)), "Not a wrapper?");
 
     XPCNativeScriptableSharedJSClass *clasp =
-      (XPCNativeScriptableSharedJSClass*)cur->getClass();
+      (XPCNativeScriptableSharedJSClass*)js::GetObjectClass(cur);
     if(!(clasp->interfacesBitmap & (1 << interfaceBit)))
         return nsnull;
 
     *pRef = nsnull;
     *pVal = OBJECT_TO_JSVAL(cur);
 
     if(lccx)
     {
--- a/js/src/xpconnect/src/xpcvariant.cpp
+++ b/js/src/xpconnect/src/xpcvariant.cpp
@@ -58,18 +58,17 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(XPCVaria
 NS_IMPL_CYCLE_COLLECTING_RELEASE(XPCVariant)
 
 XPCVariant::XPCVariant(XPCCallContext& ccx, jsval aJSVal)
     : mJSVal(aJSVal)
 {
     nsVariant::Initialize(&mData);
     if(!JSVAL_IS_PRIMITIVE(mJSVal))
     {
-        JSObject *obj = JSVAL_TO_OBJECT(mJSVal);
-        OBJ_TO_INNER_OBJECT(ccx, obj);
+        JSObject *obj = JS_ObjectToInnerObject(ccx, JSVAL_TO_OBJECT(mJSVal));
 
         mJSVal = OBJECT_TO_JSVAL(obj);
 
         // If the incoming object is an XPCWrappedNative, then it could be a
         // double-wrapped object, and we should return the double-wrapped
         // object back out to script.
 
         JSObject* proto;
@@ -476,17 +475,17 @@ XPCVariant::VariantDataToJS(XPCLazyCallC
     nsAutoString astring;
     nsCAutoString cString;
     nsUTF8String utf8String;
     PRUint32 size;
     xpctvar.flags = 0;
     JSBool success;
 
     JSContext* cx = lccx.GetJSContext();
-    NS_ABORT_IF_FALSE(lccx.GetScopeForNewJSObjects()->compartment() == cx->compartment,
+    NS_ABORT_IF_FALSE(js::GetObjectCompartment(lccx.GetScopeForNewJSObjects()) == cx->compartment,
                       "bad scope for new JSObjects");
 
     switch(type)
     {
         case nsIDataType::VTYPE_INT8:        
         case nsIDataType::VTYPE_INT16:        
         case nsIDataType::VTYPE_INT32:        
         case nsIDataType::VTYPE_INT64:        
--- a/js/src/xpconnect/src/xpcwrappedjsclass.cpp
+++ b/js/src/xpconnect/src/xpcwrappedjsclass.cpp
@@ -258,17 +258,17 @@ nsXPCWrappedJSClass::CallQueryInterfaceO
     jsid funid;
     jsval fun;
 
     // Don't call the actual function on a content object. We'll determine
     // whether or not a content object is capable of implementing the
     // interface (i.e. whether the interface is scriptable) and most content
     // objects don't have QI implementations anyway. Also see bug 503926.
     if(XPCPerThreadData::IsMainThread(ccx) &&
-       !xpc::AccessCheck::isChrome(jsobj->compartment()))
+       !xpc::AccessCheck::isChrome(js::GetObjectCompartment(jsobj)))
     {
         return nsnull;
     }
 
     // OK, it looks like we'll be calling into JS code.
     AutoScriptEvaluate scriptEval(cx);
 
     // XXX we should install an error reporter that will send reports to
@@ -773,17 +773,17 @@ nsXPCWrappedJSClass::DelegatedQueryInter
         nsresult rv = secMan->GetObjectPrincipal(ccx, selfObj,
                                                  getter_AddRefs(objPrin));
         if(NS_FAILED(rv))
             return rv;
 
         bool isSystem;
         rv = secMan->IsSystemPrincipal(objPrin, &isSystem);
         if((NS_FAILED(rv) || !isSystem) &&
-           !IS_WRAPPER_CLASS(selfObj->getClass()))
+           !IS_WRAPPER_CLASS(js::GetObjectClass(selfObj)))
         {
             // A content object.
             nsRefPtr<SameOriginCheckedComponent> checked =
                 new SameOriginCheckedComponent(self);
             if(!checked)
                 return NS_ERROR_OUT_OF_MEMORY;
             *aInstancePtr = checked.forget().get();
             return NS_OK;
@@ -1326,17 +1326,17 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra
 
     if(XPCPerThreadData::IsMainThread(ccx))
     {
         // TODO Remove me in favor of security wrappers.
         nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
         if(ssm)
         {
             nsIPrincipal *objPrincipal =
-                xpc::AccessCheck::getPrincipal(obj->compartment());
+                xpc::AccessCheck::getPrincipal(js::GetObjectCompartment(obj));
             if(objPrincipal)
             {
                 JSStackFrame* fp = nsnull;
                 nsresult rv =
                     ssm->PushContextPrincipal(ccx, JS_FrameIterator(ccx, &fp),
                                               objPrincipal);
                 if(NS_FAILED(rv))
                 {
--- a/js/src/xpconnect/src/xpcwrappednative.cpp
+++ b/js/src/xpconnect/src/xpcwrappednative.cpp
@@ -526,18 +526,18 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
             return NS_ERROR_FAILURE;
 
         nsISupports *Object = helper.Object();
         if(nsXPCWrappedJSClass::IsWrappedJS(Object))
         {
             nsCOMPtr<nsIXPConnectWrappedJS> wrappedjs(do_QueryInterface(Object));
             JSObject *obj;
             wrappedjs->GetJSObject(&obj);
-            if(xpc::AccessCheck::isChrome(obj->compartment()) &&
-               !xpc::AccessCheck::isChrome(Scope->GetGlobalJSObject()->compartment()))
+            if(xpc::AccessCheck::isChrome(js::GetObjectCompartment(obj)) &&
+               !xpc::AccessCheck::isChrome(js::GetObjectCompartment(Scope->GetGlobalJSObject())))
             {
                 needsCOW = JS_TRUE;
             }
         }
     }
 
     AutoMarkingWrappedNativeProtoPtr proto(ccx);
 
@@ -759,17 +759,17 @@ XPCWrappedNative::Morph(XPCCallContext& 
 #endif
 
     wrapper = new XPCWrappedNative(dont_AddRef(identity), proto);
     if(!wrapper)
         return NS_ERROR_FAILURE;
 
     NS_ADDREF(wrapper);
 
-    NS_ASSERTION(!xpc::WrapperFactory::IsXrayWrapper(existingJSObject->getParent()),
+    NS_ASSERTION(!xpc::WrapperFactory::IsXrayWrapper(js::GetObjectParent(existingJSObject)),
                  "Xray wrapper being used to parent XPCWrappedNative?");
 
     JSAutoEnterCompartment ac;
     if(!ac.enter(ccx, existingJSObject) || !wrapper->Init(ccx, existingJSObject))
     {
         NS_RELEASE(wrapper);
         return NS_ERROR_FAILURE;
     }
@@ -1490,18 +1490,18 @@ XPCWrappedNative::ReparentWrapperIfFound
     }
 
     if(!flat)
     {
         *aWrapper = nsnull;
         return NS_OK;
     }
 
-    bool crosscompartment = aOldScope->GetGlobalJSObject()->compartment() !=
-                            aNewScope->GetGlobalJSObject()->compartment();
+    bool crosscompartment = js::GetObjectCompartment(aOldScope->GetGlobalJSObject()) !=
+                            js::GetObjectCompartment(aNewScope->GetGlobalJSObject());
 #ifdef DEBUG
     if(crosscompartment)
     {
         NS_ASSERTION(aNewParent, "won't be able to find the new parent");
         NS_ASSERTION(wrapper, "can't transplant slim wrappers");
     }
 #endif
 
@@ -1588,26 +1588,27 @@ XPCWrappedNative::ReparentWrapperIfFound
                 (void) newMap->Add(wrapper);
             }
 
             // We only try to fixup the __proto__ JSObject if the wrapper
             // is directly using that of its XPCWrappedNativeProto.
 
             if(crosscompartment)
             {
-                JSObject *newobj = flat->clone(ccx, newProto->GetJSProtoObject(),
-                                               aNewParent);
+                JSObject *newobj = JS_CloneObject(ccx, flat,
+                                                  newProto->GetJSProtoObject(),
+                                                  aNewParent);
                 if(!newobj)
                     return NS_ERROR_FAILURE;
 
                 JS_SetPrivate(ccx, flat, nsnull);
 
                 JSObject *propertyHolder =
                     JS_NewObjectWithGivenProto(ccx, NULL, NULL, aNewParent);
-                if(!propertyHolder || !propertyHolder->copyPropertiesFrom(ccx, flat))
+                if(!propertyHolder || !JS_CopyPropertiesFrom(ccx, propertyHolder, flat))
                     return NS_ERROR_OUT_OF_MEMORY;
 
                 JSObject *ww = wrapper->GetWrapper();
                 if(ww)
                 {
                     JSObject *newwrapper;
                     if(xpc::WrapperFactory::IsLocationObject(flat))
                     {
@@ -1635,23 +1636,23 @@ XPCWrappedNative::ReparentWrapperIfFound
                     flat = JS_TransplantObject(ccx, flat, newobj);
                     if(!flat)
                         return NS_ERROR_FAILURE;
                 }
 
                 wrapper->mFlatJSObject = flat;
                 if(cache)
                     cache->SetWrapper(flat);
-                if (!flat->copyPropertiesFrom(ccx, propertyHolder))
+                if (!JS_CopyPropertiesFrom(ccx, flat, propertyHolder))
                     return NS_ERROR_FAILURE;
             }
             else
             {
                 if(wrapper->HasProto() &&
-                   flat->getProto() == oldProto->GetJSProtoObject())
+                   js::GetObjectProto(flat) == oldProto->GetJSProtoObject())
                 {
                     if(!JS_SetPrototype(ccx, flat, newProto->GetJSProtoObject()))
                     {
                         // this is bad, very bad
                         NS_ERROR("JS_SetPrototype failed");
                         return NS_ERROR_FAILURE;
                     }
                 }
@@ -1722,60 +1723,60 @@ XPCWrappedNative::GetWrappedNativeOfJSOb
     XPCWrappedNativeProto* proto = nsnull;
     nsIClassInfo* protoClassInfo = nsnull;
 
     // If we were passed a function object then we need to find the correct
     // wrapper out of those that might be in the callee obj's proto chain.
 
     if(funobj)
     {
-        JSObject* funObjParent = funobj->getParent()->unwrap();
-        OBJ_TO_INNER_OBJECT(cx, funObjParent);
+        JSObject* funObjParent = js::UnwrapObject(js::GetObjectParent(funobj));
+        funObjParent = JS_ObjectToInnerObject(cx, funObjParent);
         NS_ASSERTION(funObjParent, "funobj has no parent");
 
-        js::Class* funObjParentClass = funObjParent->getClass();
+        js::Class* funObjParentClass = js::GetObjectClass(funObjParent);
 
         if(IS_PROTO_CLASS(funObjParentClass))
         {
-            NS_ASSERTION(funObjParent->getParent(), "funobj's parent (proto) is global");
-            proto = (XPCWrappedNativeProto*) funObjParent->getPrivate();
+            NS_ASSERTION(js::GetObjectParent(funObjParent), "funobj's parent (proto) is global");
+            proto = (XPCWrappedNativeProto*) js::GetObjectPrivate(funObjParent);
             if(proto)
                 protoClassInfo = proto->GetClassInfo();
         }
         else if(IS_WRAPPER_CLASS(funObjParentClass))
         {
             cur = funObjParent;
             goto return_wrapper;
         }
         else if(IS_TEAROFF_CLASS(funObjParentClass))
         {
-            NS_ASSERTION(funObjParent->getParent(), "funobj's parent (tearoff) is global");
+            NS_ASSERTION(js::GetObjectParent(funObjParent), "funobj's parent (tearoff) is global");
             cur = funObjParent;
             goto return_tearoff;
         }
         else
         {
             NS_ERROR("function object has parent of unknown class!");
             return nsnull;
         }
     }
 
   restart:
-    for(cur = obj; cur; cur = cur->getProto())
+    for(cur = obj; cur; cur = js::GetObjectProto(cur))
     {
         // this is on two lines to make the compiler happy given the goto.
         js::Class* clazz;
-        clazz = cur->getClass();
+        clazz = js::GetObjectClass(cur);
 
         if(IS_WRAPPER_CLASS(clazz))
         {
 return_wrapper:
             JSBool isWN = IS_WN_WRAPPER_OBJECT(cur);
             XPCWrappedNative* wrapper =
-                isWN ? (XPCWrappedNative*) cur->getPrivate() : nsnull;
+                isWN ? (XPCWrappedNative*) js::GetObjectPrivate(cur) : nsnull;
             if(proto)
             {
                 XPCWrappedNativeProto* wrapper_proto =
                     isWN ? wrapper->GetProto() : GetSlimWrapperProto(cur);
                 if(proto != wrapper_proto &&
                    (!protoClassInfo || !wrapper_proto ||
                     protoClassInfo != wrapper_proto->GetClassInfo()))
                     continue;
@@ -1784,25 +1785,25 @@ return_wrapper:
                 *pobj2 = isWN ? nsnull : cur;
             return wrapper;
         }
 
         if(IS_TEAROFF_CLASS(clazz))
         {
 return_tearoff:
             XPCWrappedNative* wrapper =
-                (XPCWrappedNative*) cur->getParent()->getPrivate();
+                (XPCWrappedNative*) js::GetObjectPrivate(js::GetObjectParent(cur));
             if(proto && proto != wrapper->GetProto() &&
                (proto->GetScope() != wrapper->GetScope() ||
                 !protoClassInfo || !wrapper->GetProto() ||
                 protoClassInfo != wrapper->GetProto()->GetClassInfo()))
                 continue;
             if(pobj2)
                 *pobj2 = nsnull;
-            XPCWrappedNativeTearOff* to = (XPCWrappedNativeTearOff*) cur->getPrivate();
+            XPCWrappedNativeTearOff* to = (XPCWrappedNativeTearOff*) js::GetObjectPrivate(cur);
             if(!to)
                 return nsnull;
             if(pTearOff)
                 *pTearOff = to;
             return wrapper;
         }
 
         // Unwrap any wrapper wrappers.
@@ -3982,17 +3983,17 @@ ConstructSlimWrapper(XPCCallContext &ccx
     rv = classInfoHelper->PreCreate(identityObj, ccx, parent, &parent);
     if(rv != NS_SUCCESS_ALLOW_SLIM_WRAPPERS)
     {
         SLIM_LOG_NOT_CREATED(ccx, identityObj, "PreCreate hook refused");
 
         return JS_FALSE;
     }
 
-    if(ccx.GetJSContext()->compartment != parent->compartment())
+    if(ccx.GetJSContext()->compartment != js::GetObjectCompartment(parent))
     {
         SLIM_LOG_NOT_CREATED(ccx, identityObj, "wrong compartment");
 
         return JS_FALSE;
     }
 
     JSAutoEnterCompartment ac;
     if(!ac.enter(ccx, parent))
--- a/js/src/xpconnect/src/xpcwrappednativeinfo.cpp
+++ b/js/src/xpconnect/src/xpcwrappednativeinfo.cpp
@@ -88,19 +88,19 @@ xpc_CloneJSFunction(XPCCallContext &ccx,
 
 // static
 JSBool
 XPCNativeMember::GetCallInfo(XPCCallContext& ccx,
                              JSObject* funobj,
                              XPCNativeInterface** pInterface,
                              XPCNativeMember**    pMember)
 {
-    funobj = funobj->unwrap();
-    jsval ifaceVal = funobj->getSlot(0);
-    jsval memberVal = funobj->getSlot(1);
+    funobj = js::UnwrapObject(funobj);
+    jsval ifaceVal = js::GetReservedSlot(funobj, 0);
+    jsval memberVal = js::GetReservedSlot(funobj, 1);
 
     *pInterface = (XPCNativeInterface*) JSVAL_TO_PRIVATE(ifaceVal);
     *pMember = (XPCNativeMember*) JSVAL_TO_PRIVATE(memberVal);
 
     return JS_TRUE;
 }
 
 JSBool
--- a/js/src/xpconnect/src/xpcwrappednativejsops.cpp
+++ b/js/src/xpconnect/src/xpcwrappednativejsops.cpp
@@ -829,17 +829,17 @@ XPC_WN_Equality(JSContext *cx, JSObject 
 
     return JS_TRUE;
 }
 
 static JSObject *
 XPC_WN_OuterObject(JSContext *cx, JSObject *obj)
 {
     XPCWrappedNative *wrapper =
-        static_cast<XPCWrappedNative *>(obj->getPrivate());
+        static_cast<XPCWrappedNative *>(js::GetObjectPrivate(obj));
     if(!wrapper)
     {
         Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx);
 
         return nsnull;
     }
 
     if(!wrapper->IsValid())
@@ -1268,24 +1268,24 @@ XPC_WN_Helper_NewResolve(JSContext *cx, 
         else
             do shared enumerate - don't use this JSOp thing at all
 */
 
 JSBool
 XPC_WN_JSOp_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
                       jsval *statep, jsid *idp)
 {
-    js::Class *clazz = obj->getClass();
+    js::Class *clazz = js::GetObjectClass(obj);
     if(!IS_WRAPPER_CLASS(clazz) || clazz == &XPC_WN_NoHelper_JSClass)
     {
         // obj must be a prototype object or a wrapper w/o a
         // helper. Short circuit this call to the default
         // implementation.
 
-        return js_Enumerate(cx, obj, enum_op, statep, idp);
+        return JS_EnumerateState(cx, obj, enum_op, statep, idp);
     }
 
     MORPH_SLIM_WRAPPER(cx, obj);
 
     XPCCallContext ccx(JS_CALLER, cx, obj);
     XPCWrappedNative* wrapper = ccx.GetWrapper();
     THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper);
 
@@ -1348,17 +1348,17 @@ XPC_WN_JSOp_Enumerate(JSContext *cx, JSO
             if(!retval)
                 return JS_FALSE;
             // Then fall through and call the default implementation...
         }
     }
 
     // else call js_ObjectOps.enumerate...
 
-    return js_Enumerate(cx, obj, enum_op, statep, idp);
+    return JS_EnumerateState(cx, obj, enum_op, statep, idp);
 }
 
 JSType
 XPC_WN_JSOp_TypeOf_Object(JSContext *cx, JSObject *obj)
 {
     return JSTYPE_OBJECT;
 }
 
@@ -1413,18 +1413,17 @@ private:
 JSObject*
 XPC_WN_JSOp_ThisObject(JSContext *cx, JSObject *obj)
 {
     // None of the wrappers we could potentially hand out are threadsafe so
     // just hand out the given object.
     if(!XPCPerThreadData::IsMainThread(cx))
         return obj;
 
-    OBJ_TO_OUTER_OBJECT(cx, obj);
-    return obj;
+    return JS_ObjectToOuterObject(cx, obj);
 }
 
 /***************************************************************************/
 
 // static
 XPCNativeScriptableInfo*
 XPCNativeScriptableInfo::Construct(XPCCallContext& ccx,
                                    JSBool isGlobal,
@@ -1680,20 +1679,20 @@ XPC_WN_GetterSetter(JSContext *cx, uintN
 }
 
 /***************************************************************************/
 
 static JSBool
 XPC_WN_Shared_Proto_Enumerate(JSContext *cx, JSObject *obj)
 {
     NS_ASSERTION(
-        obj->getClass() == &XPC_WN_ModsAllowed_WithCall_Proto_JSClass ||
-        obj->getClass() == &XPC_WN_ModsAllowed_NoCall_Proto_JSClass ||
-        obj->getClass() == &XPC_WN_NoMods_WithCall_Proto_JSClass ||
-        obj->getClass() == &XPC_WN_NoMods_NoCall_Proto_JSClass,
+        js::GetObjectClass(obj) == &XPC_WN_ModsAllowed_WithCall_Proto_JSClass ||
+        js::GetObjectClass(obj) == &XPC_WN_ModsAllowed_NoCall_Proto_JSClass ||
+        js::GetObjectClass(obj) == &XPC_WN_NoMods_WithCall_Proto_JSClass ||
+        js::GetObjectClass(obj) == &XPC_WN_NoMods_NoCall_Proto_JSClass,
         "bad proto");
     XPCWrappedNativeProto* self =
         (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
     if(!self)
         return JS_FALSE;
 
     if(self->GetScriptableInfo() &&
        self->GetScriptableInfo()->GetFlags().DontEnumStaticProps())
@@ -1745,18 +1744,18 @@ XPC_WN_Shared_Proto_Trace(JSTracer *trc,
 }
 
 /*****************************************************/
 
 static JSBool
 XPC_WN_ModsAllowed_Proto_Resolve(JSContext *cx, JSObject *obj, jsid id)
 {
     NS_ASSERTION(
-        obj->getClass() == &XPC_WN_ModsAllowed_WithCall_Proto_JSClass ||
-        obj->getClass() == &XPC_WN_ModsAllowed_NoCall_Proto_JSClass,
+        js::GetObjectClass(obj) == &XPC_WN_ModsAllowed_WithCall_Proto_JSClass ||
+        js::GetObjectClass(obj) == &XPC_WN_ModsAllowed_NoCall_Proto_JSClass,
         "bad proto");
 
     XPCWrappedNativeProto* self =
         (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
     if(!self)
         return JS_FALSE;
 
     XPCCallContext ccx(JS_CALLER, cx);
@@ -1829,18 +1828,18 @@ js::Class XPC_WN_ModsAllowed_NoCall_Prot
     XPC_WN_NoCall_ObjectOps
 };
 
 /***************************************************************************/
 
 static JSBool
 XPC_WN_OnlyIWrite_Proto_AddPropertyStub(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
 {
-    NS_ASSERTION(obj->getClass() == &XPC_WN_NoMods_WithCall_Proto_JSClass ||
-                 obj->getClass() == &XPC_WN_NoMods_NoCall_Proto_JSClass,
+    NS_ASSERTION(js::GetObjectClass(obj) == &XPC_WN_NoMods_WithCall_Proto_JSClass ||
+                 js::GetObjectClass(obj) == &XPC_WN_NoMods_NoCall_Proto_JSClass,
                  "bad proto");
 
     XPCWrappedNativeProto* self =
         (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
     if(!self)
         return JS_FALSE;
 
     XPCCallContext ccx(JS_CALLER, cx);
@@ -1860,18 +1859,18 @@ XPC_WN_OnlyIWrite_Proto_SetPropertyStub(
                                         jsval *vp)
 {
     return XPC_WN_OnlyIWrite_Proto_AddPropertyStub(cx, obj, id, vp);
 }
 
 static JSBool
 XPC_WN_NoMods_Proto_Resolve(JSContext *cx, JSObject *obj, jsid id)
 {
-    NS_ASSERTION(obj->getClass() == &XPC_WN_NoMods_WithCall_Proto_JSClass ||
-                 obj->getClass() == &XPC_WN_NoMods_NoCall_Proto_JSClass,
+    NS_ASSERTION(js::GetObjectClass(obj) == &XPC_WN_NoMods_WithCall_Proto_JSClass ||
+                 js::GetObjectClass(obj) == &XPC_WN_NoMods_NoCall_Proto_JSClass,
                  "bad proto");
 
     XPCWrappedNativeProto* self =
         (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
     if(!self)
         return JS_FALSE;
 
     XPCCallContext ccx(JS_CALLER, cx);
--- a/js/src/xpconnect/src/xpcwrappednativescope.cpp
+++ b/js/src/xpconnect/src/xpcwrappednativescope.cpp
@@ -232,17 +232,17 @@ XPCWrappedNativeScope::SetGlobal(XPCCall
 {
     // We allow for calling this more than once. This feature is used by
     // nsXPConnect::InitClassesWithNewWrappedGlobal.
 
     mGlobalJSObject = aGlobal;
     mScriptObjectPrincipal = nsnull;
     // Now init our script object principal, if the new global has one
 
-    const JSClass* jsClass = aGlobal->getJSClass();
+    const JSClass* jsClass = js::GetObjectJSClass(aGlobal);
     if(!(~jsClass->flags & (JSCLASS_HAS_PRIVATE |
                             JSCLASS_PRIVATE_IS_NSISUPPORTS)))
     {
         // Our global has an nsISupports native pointer.  Let's
         // see whether it's what we want.
         nsISupports* priv = (nsISupports*)xpc_GetJSPrivate(aGlobal);
         nsCOMPtr<nsIXPConnectWrappedNative> native =
             do_QueryInterface(priv);
@@ -437,17 +437,17 @@ XPCWrappedNativeScope::FinishedMarkPhase
 
     XPCWrappedNativeScope* prev = nsnull;
     XPCWrappedNativeScope* cur = gScopes;
 
     while(cur)
     {
         XPCWrappedNativeScope* next = cur->mNext;
 
-        JS::AutoSwitchCompartment sc(cx, cur->mGlobalJSObject);
+        js::AutoSwitchCompartment sc(cx, cur->mGlobalJSObject);
 
         if(cur->mGlobalJSObject &&
            JS_IsAboutToBeFinalized(cx, cur->mGlobalJSObject))
         {
             cur->mGlobalJSObject = nsnull;
             cur->mScriptObjectPrincipal = nsnull;
             // Move this scope from the live list to the dying list.
             if(prev)
@@ -702,17 +702,17 @@ XPCWrappedNativeScope::SystemIsBeingShut
 
 /***************************************************************************/
 
 static
 XPCWrappedNativeScope*
 GetScopeOfObject(JSObject* obj)
 {
     nsISupports* supports;
-    js::Class* clazz = obj->getClass();
+    js::Class* clazz = js::GetObjectClass(obj);
     JSBool isWrapper = IS_WRAPPER_CLASS(clazz);
 
     if(isWrapper && IS_SLIM_WRAPPER_OBJECT(obj))
         return GetSlimWrapperProto(obj)->GetScope();
 
     if(!isWrapper || !(supports = (nsISupports*) xpc_GetJSPrivate(obj)))
         return nsnull;
 
@@ -755,19 +755,19 @@ void DEBUG_CheckForComponentsInScope(JSC
     NS_ERROR("XPConnect is being called on a scope without a 'Components' property!  (stack and details follow)");
     printf("The current JS stack is:\n");
     xpc_DumpJSStack(cx, JS_TRUE, JS_TRUE, JS_TRUE);
 
     printf("And the object whose scope lacks a 'Components' property is:\n");
     js_DumpObject(startingObj);
 
     JSObject *p = startingObj;
-    while(p->isWrapper())
+    while(js::IsWrapper(p))
     {
-        p = p->getProxyPrivate().toObjectOrNull();
+        p = js::GetProxyPrivate(p).toObjectOrNull();
         if(!p)
             break;
         printf("which is a wrapper for:\n");
         js_DumpObject(p);
     }
 }
 #else
 #define DEBUG_CheckForComponentsInScope(ccx, obj, startingObj, OKIfNotInitialized, runtime) \
--- a/js/src/xpconnect/wrappers/AccessCheck.cpp
+++ b/js/src/xpconnect/wrappers/AccessCheck.cpp
@@ -82,24 +82,25 @@ AccessCheck::isSameOrigin(JSCompartment 
     }
 
     return equals;
 }
 
 bool
 AccessCheck::isLocationObjectSameOrigin(JSContext *cx, JSObject *wrapper)
 {
-    JSObject *obj = wrapper->unwrap()->getParent();
-    if (!obj->getClass()->ext.innerObject) {
-        obj = obj->unwrap();
-        JS_ASSERT(obj->getClass()->ext.innerObject);
+    JSObject *obj = js::GetObjectParent(js::UnwrapObject(wrapper));
+    if (!js::GetObjectClass(obj)->ext.innerObject) {
+        obj = js::UnwrapObject(obj);
+        JS_ASSERT(js::GetObjectClass(obj)->ext.innerObject);
     }
-    OBJ_TO_INNER_OBJECT(cx, obj);
+    obj = JS_ObjectToInnerObject(cx, obj);
     return obj &&
-           (isSameOrigin(wrapper->compartment(), obj->compartment()) ||
+           (isSameOrigin(js::GetObjectCompartment(wrapper),
+                         js::GetObjectCompartment(obj)) ||
             documentDomainMakesSameOrigin(cx, obj));
 }
 
 bool
 AccessCheck::isChrome(JSCompartment *compartment)
 {
     nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
     if (!ssm) {
@@ -215,17 +216,17 @@ IsLocation(const char *name)
     return name[0] == 'L' && !strcmp(name, "Location");
 }
 
 static nsIPrincipal *
 GetPrincipal(JSObject *obj)
 {
     NS_ASSERTION(!IS_SLIM_WRAPPER(obj), "global object is a slim wrapper?");
     if (!IS_WN_WRAPPER(obj)) {
-        NS_ASSERTION(!(~obj->getClass()->flags &
+        NS_ASSERTION(!(~js::GetObjectClass(obj)->flags &
                        (JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_HAS_PRIVATE)),
                      "bad object");
         nsCOMPtr<nsIScriptObjectPrincipal> objPrin =
             do_QueryInterface((nsISupports*)xpc_GetJSPrivate(obj));
         NS_ASSERTION(objPrin, "global isn't nsIScriptObjectPrincipal?");
         return objPrin->GetPrincipal();
     }
 
@@ -288,17 +289,17 @@ AccessCheck::isCrossOriginAccessPermitte
         return true;
 
     if (act == Wrapper::CALL)
         return true;
 
     JSObject *obj = Wrapper::wrappedObject(wrapper);
 
     const char *name;
-    js::Class *clasp = obj->getClass();
+    js::Class *clasp = js::GetObjectClass(obj);
     NS_ASSERTION(Jsvalify(clasp) != &XrayUtils::HolderClass, "shouldn't have a holder here");
     if (clasp->ext.innerObject)
         name = "Window";
     else
         name = clasp->name;
 
     if (JSID_IS_ATOM(id)) {
         if (IsPermitted(name, JSID_TO_FLAT_STRING(id), act == Wrapper::SET))
@@ -352,41 +353,41 @@ AccessCheck::isSystemOnlyAccessPermitted
         return true;
     }
 
     // Allow any code loaded from chrome://global/ to touch us, even if it was
     // cloned into a less privileged context.
     static const char prefix[] = "chrome://global/";
     const char *filename;
     if (fp &&
-        (filename = JS_GetFrameScript(cx, fp)->filename) &&
+        (filename = JS_GetScriptFilename(cx, JS_GetFrameScript(cx, fp))) &&
         !strncmp(filename, prefix, NS_ARRAY_LENGTH(prefix) - 1)) {
         return true;
     }
 
     return NS_SUCCEEDED(ssm->IsCapabilityEnabled("UniversalXPConnect", &privileged)) && privileged;
 }
 
 bool
 AccessCheck::needsSystemOnlyWrapper(JSObject *obj)
 {
     if (!IS_WN_WRAPPER(obj))
         return false;
 
-    XPCWrappedNative *wn = static_cast<XPCWrappedNative *>(obj->getPrivate());
+    XPCWrappedNative *wn = static_cast<XPCWrappedNative *>(js::GetObjectPrivate(obj));
     return wn->NeedsSOW();
 }
 
 bool
 AccessCheck::isScriptAccessOnly(JSContext *cx, JSObject *wrapper)
 {
-    JS_ASSERT(wrapper->isWrapper());
+    JS_ASSERT(js::IsWrapper(wrapper));
 
     uintN flags;
-    JSObject *obj = wrapper->unwrap(&flags);
+    JSObject *obj = js::UnwrapObject(wrapper, &flags);
 
     // If the wrapper indicates script-only access, we are done.
     if (flags & WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG) {
         if (flags & WrapperFactory::SOW_FLAG)
             return !isSystemOnlyAccessPermitted(cx);
 
         if (flags & WrapperFactory::PARTIALLY_TRANSPARENT)
             return !XrayUtils::IsTransparent(cx, wrapper);
@@ -397,17 +398,17 @@ AccessCheck::isScriptAccessOnly(JSContex
 
         // Bypass script-only status if UniversalXPConnect is enabled.
         bool privileged;
         return !NS_SUCCEEDED(ssm->IsCapabilityEnabled("UniversalXPConnect", &privileged)) ||
                !privileged;
     }
 
     // In addition, chrome objects can explicitly opt-in by setting .scriptOnly to true.
-    if (wrapper->getProxyHandler() == &FilteringWrapper<CrossCompartmentWrapper,
+    if (js::GetProxyHandler(wrapper) == &FilteringWrapper<CrossCompartmentWrapper,
         CrossOriginAccessiblePropertiesOnly>::singleton) {
         jsid scriptOnlyId = GetRTIdByIndex(cx, XPCJSRuntime::IDX_SCRIPTONLY);
         jsval scriptOnly;
         if (JS_LookupPropertyById(cx, obj, scriptOnlyId, &scriptOnly) &&
             scriptOnly == JSVAL_TRUE)
             return true; // script-only
     }
 
--- a/js/src/xpconnect/wrappers/CrossOriginWrapper.cpp
+++ b/js/src/xpconnect/wrappers/CrossOriginWrapper.cpp
@@ -110,17 +110,17 @@ NoWaiverWrapper::enter(JSContext *cx, JS
     if (!ssm) {
         return true;
     }
 
     // Note: By the time enter is called here, CrossCompartmentWrapper has
     // already pushed the fake stack frame onto cx. Because of this, the frame
     // that we're clamping is the one that we want (the one in our compartment).
     JSStackFrame *fp = NULL;
-    nsIPrincipal *principal = GetCompartmentPrincipal(wrappedObject(wrapper)->compartment());
+    nsIPrincipal *principal = GetCompartmentPrincipal(js::GetObjectCompartment(wrappedObject(wrapper)));
     nsresult rv = ssm->PushContextPrincipal(cx, JS_FrameIterator(cx, &fp), principal);
     if (NS_FAILED(rv)) {
         NS_WARNING("Not allowing call because we're out of memory");
         JS_ReportOutOfMemory(cx);
         return false;
     }
     return true;
 }
--- a/js/src/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/src/xpconnect/wrappers/WrapperFactory.cpp
@@ -32,18 +32,16 @@
  * 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 "jsobj.h"
-
 #include "WrapperFactory.h"
 #include "CrossOriginWrapper.h"
 #include "FilteringWrapper.h"
 #include "XrayWrapper.h"
 #include "AccessCheck.h"
 #include "XPCWrapper.h"
 
 #include "xpcprivate.h"
@@ -73,46 +71,46 @@ NoWaiverWrapper NoWaiverWrapper::singlet
 // chrome, we wrap them into a special cross-compartment wrapper
 // that transitively extends the waiver to all properties we get
 // off it.
 CrossOriginWrapper CrossOriginWrapper::singleton(0);
 
 static JSObject *
 GetCurrentOuter(JSContext *cx, JSObject *obj)
 {
-    OBJ_TO_OUTER_OBJECT(cx, obj);
-    if (obj->isWrapper() && !obj->getClass()->ext.innerObject) {
-        obj = obj->unwrap();
-        NS_ASSERTION(obj->getClass()->ext.innerObject,
+    obj = JS_ObjectToOuterObject(cx, obj);
+    if (IsWrapper(obj) && !js::GetObjectClass(obj)->ext.innerObject) {
+        obj = UnwrapObject(obj);
+        NS_ASSERTION(js::GetObjectClass(obj)->ext.innerObject,
                      "weird object, expecting an outer window proxy");
     }
 
     return obj;
 }
 
 JSObject *
 WrapperFactory::WaiveXray(JSContext *cx, JSObject *obj)
 {
-    obj = obj->unwrap();
+    obj = UnwrapObject(obj);
 
     // We have to make sure that if we're wrapping an outer window, that
     // the .wrappedJSObject also wraps the outer window.
     obj = GetCurrentOuter(cx, obj);
 
     {
         // See if we already have a waiver wrapper for this object.
         CompartmentPrivate *priv =
-            (CompartmentPrivate *)JS_GetCompartmentPrivate(cx, obj->compartment());
+            (CompartmentPrivate *)JS_GetCompartmentPrivate(cx, js::GetObjectCompartment(obj));
         JSObject *wobj = nsnull;
         if (priv && priv->waiverWrapperMap)
             wobj = priv->waiverWrapperMap->Find(obj);
 
         // No wrapper yet, make one.
         if (!wobj) {
-            JSObject *proto = obj->getProto();
+            JSObject *proto = js::GetObjectProto(obj);
             if (proto && !(proto = WaiveXray(cx, proto)))
                 return nsnull;
 
             JSAutoEnterCompartment ac;
             if (!ac.enter(cx, obj) || !JS_WrapObject(cx, &proto))
                 return nsnull;
             wobj = Wrapper::New(cx, obj, proto, JS_GetGlobalForObject(cx, obj),
                                 &WaiveXrayWrapperWrapper);
@@ -153,39 +151,39 @@ WrapperFactory::DoubleWrap(JSContext *cx
     }
     return obj;
 }
 
 JSObject *
 WrapperFactory::PrepareForWrapping(JSContext *cx, JSObject *scope, JSObject *obj, uintN flags)
 {
     // Don't unwrap an outer window, just double wrap it if needed.
-    if (obj->getClass()->ext.innerObject)
+    if (js::GetObjectClass(obj)->ext.innerObject)
         return DoubleWrap(cx, obj, flags);
 
     // Here are the rules for wrapping:
     // We should never get a proxy here (the JS engine unwraps those for us).
-    JS_ASSERT(!obj->isWrapper());
+    JS_ASSERT(!IsWrapper(obj));
 
     // As soon as an object is wrapped in a security wrapper, it morphs to be
     // a fat wrapper. (see also: bug XXX).
     if (IS_SLIM_WRAPPER(obj) && !MorphSlimWrapper(cx, obj))
         return nsnull;
 
     // We only hand out outer objects to script.
     obj = GetCurrentOuter(cx, obj);
-    if (obj->getClass()->ext.innerObject)
+    if (js::GetObjectClass(obj)->ext.innerObject)
         return DoubleWrap(cx, obj, flags);
 
     // Now, our object is ready to be wrapped, but several objects (notably
     // nsJSIIDs) have a wrapper per scope. If we are about to wrap one of
     // those objects in a security wrapper, then we need to hand back the
     // wrapper for the new scope instead. Also, global objects don't move
     // between scopes so for those we also want to return the wrapper. So...
-    if (!IS_WN_WRAPPER(obj) || !obj->getParent())
+    if (!IS_WN_WRAPPER(obj) || !js::GetObjectParent(obj))
         return DoubleWrap(cx, obj, flags);
 
     XPCWrappedNative *wn = static_cast<XPCWrappedNative *>(xpc_GetJSPrivate(obj));
 
     // If the object doesn't have classinfo we want to return the same
     // XPCWrappedNative so that we keep the same set of interfaces.
     if (!wn->GetClassInfo())
         return DoubleWrap(cx, obj, flags);
@@ -203,17 +201,17 @@ WrapperFactory::PrepareForWrapping(JSCon
             nsresult rv = wn->GetScriptableInfo()->GetCallback()->
                 PreCreate(wn->Native(), cx, scope, &scope);
             NS_ENSURE_SUCCESS(rv, DoubleWrap(cx, obj, flags));
 
             // If the handed back scope differs from the passed-in scope and is in
             // a separate compartment, then this object is explicitly requesting
             // that we don't create a second JS object for it: create a security
             // wrapper.
-            if (originalScope->compartment() != scope->getCompartment())
+            if (js::GetObjectCompartment(originalScope) != js::GetObjectCompartment(scope))
                 return DoubleWrap(cx, obj, flags);
 
             // Note: this penalizes objects that only have one wrapper, but are
             // being accessed across compartments. We would really prefer to
             // replace the above code with a test that says "do you only have one
             // wrapper?"
         }
     }
@@ -239,34 +237,33 @@ WrapperFactory::PrepareForWrapping(JSCon
     }
 
     return DoubleWrap(cx, obj, flags);
 }
 
 static XPCWrappedNative *
 GetWrappedNative(JSContext *cx, JSObject *obj)
 {
-    OBJ_TO_INNER_OBJECT(cx, obj);
+    obj = JS_ObjectToInnerObject(cx, obj);
     return IS_WN_WRAPPER(obj)
-           ? static_cast<XPCWrappedNative *>(obj->getPrivate())
+           ? static_cast<XPCWrappedNative *>(js::GetObjectPrivate(obj))
            : nsnull;
 }
 
 JSObject *
 WrapperFactory::Rewrap(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSObject *parent,
                        uintN flags)
 {
-    NS_ASSERTION(!obj->isWrapper() ||
-                 (obj->isWrapper() &&
-                  obj->getProxyHandler() == &WaiveXrayWrapperWrapper) ||
-                 obj->getClass()->ext.innerObject,
+    NS_ASSERTION(!IsWrapper(obj) ||
+                 GetProxyHandler(obj) == &WaiveXrayWrapperWrapper ||
+                 js::GetObjectClass(obj)->ext.innerObject,
                  "wrapped object passed to rewrap");
     NS_ASSERTION(JS_GET_CLASS(cx, obj) != &XrayUtils::HolderClass, "trying to wrap a holder");
 
-    JSCompartment *origin = obj->compartment();
+    JSCompartment *origin = js::GetObjectCompartment(obj);
     JSCompartment *target = cx->compartment;
     JSObject *xrayHolder = nsnull;
 
     Wrapper *wrapper;
     CompartmentPrivate *targetdata =
         static_cast<CompartmentPrivate *>(JS_GetCompartmentPrivate(cx, target));
     if (AccessCheck::isChrome(target)) {
         if (AccessCheck::isChrome(origin)) {
@@ -285,30 +282,30 @@ WrapperFactory::Rewrap(JSContext *cx, JS
             if (isSystem) {
                 wrapper = &CrossCompartmentWrapper::singleton;
             } else if (flags & WAIVE_XRAY_WRAPPER_FLAG) {
                 // If we waived the X-ray wrapper for this object, wrap it into a
                 // special wrapper to transitively maintain the X-ray waiver.
                 wrapper = &CrossOriginWrapper::singleton;
             } else {
                 // Native objects must be wrapped into an X-ray wrapper.
-                if (IS_WN_WRAPPER(obj) || obj->getClass()->ext.innerObject) {
+                if (IS_WN_WRAPPER(obj) || js::GetObjectClass(obj)->ext.innerObject) {
                     typedef XrayWrapper<CrossCompartmentWrapper> Xray;
                     wrapper = &Xray::singleton;
                     xrayHolder = Xray::createHolder(cx, obj, parent);
                     if (!xrayHolder)
                         return nsnull;
                 } else {
                     wrapper = &NoWaiverWrapper::singleton;
                 }
             }
         }
     } else if (AccessCheck::isChrome(origin)) {
-        if (obj->isFunction()) {
-            JSFunction *fun = obj->getFunctionPrivate();
+        JSFunction *fun = JS_GetObjectFunction(obj);
+        if (fun) {
             if (JS_IsBuiltinEvalFunction(fun) || JS_IsBuiltinFunctionConstructor(fun)) {
                 JS_ReportError(cx, "Not allowed to access chrome eval or Function from content");
                 return nsnull;
             }
         }
 
         XPCWrappedNative *wn;
         if (targetdata &&
@@ -326,34 +323,34 @@ WrapperFactory::Rewrap(JSContext *cx, JS
         }
     } else if (AccessCheck::isSameOrigin(origin, target)) {
         // Same origin we use a transparent wrapper, unless the compartment asks
         // for an Xray or the wrapper needs a SOW.
         if (AccessCheck::needsSystemOnlyWrapper(obj)) {
             wrapper = &FilteringWrapper<CrossCompartmentWrapper,
                                         OnlyIfSubjectIsSystem>::singleton;
         } else if (targetdata && targetdata->wantXrays &&
-                   (IS_WN_WRAPPER(obj) || obj->getClass()->ext.innerObject)) {
+                   (IS_WN_WRAPPER(obj) || js::GetObjectClass(obj)->ext.innerObject)) {
             typedef XrayWrapper<CrossCompartmentWrapper> Xray;
             wrapper = &Xray::singleton;
             xrayHolder = Xray::createHolder(cx, obj, parent);
             if (!xrayHolder)
                 return nsnull;
         } else {
             wrapper = &CrossCompartmentWrapper::singleton;
         }
     } else {
         NS_ASSERTION(!AccessCheck::needsSystemOnlyWrapper(obj),
                      "bad object exposed across origins");
 
         // Cross origin we want to disallow scripting and limit access to
         // a predefined set of properties. XrayWrapper adds a property
         // (.wrappedJSObject) which allows bypassing the XrayWrapper, but
         // we filter out access to that property.
-        if (!IS_WN_WRAPPER(obj) && !obj->getClass()->ext.innerObject) {
+        if (!IS_WN_WRAPPER(obj) && !js::GetObjectClass(obj)->ext.innerObject) {
             wrapper = &FilteringWrapper<CrossCompartmentWrapper,
                                         CrossOriginAccessiblePropertiesOnly>::singleton;
         } else {
             typedef XrayWrapper<CrossCompartmentWrapper> Xray;
 
             // Location objects can become same origin after navigation, so we might
             // have to grant transparent access later on.
             if (IsLocationObject(obj)) {
@@ -371,57 +368,57 @@ WrapperFactory::Rewrap(JSContext *cx, JS
     }
 
     JSObject *wrapperObj = Wrapper::New(cx, obj, wrappedProto, parent, wrapper);
     if (!wrapperObj || !xrayHolder)
         return wrapperObj;
 
     // NB: The fact that the only wrappers to use ProxyExtra are XrayWrappers
     // is relied on by XPCNativeWrapper.unwrap.
-    wrapperObj->setProxyExtra(js::ObjectValue(*xrayHolder));
+    js::SetProxyExtra(wrapperObj, js::ObjectValue(*xrayHolder));
     return wrapperObj;
 }
 
 typedef FilteringWrapper<XrayWrapper<Wrapper>,
                          SameOriginOrCrossOriginAccessiblePropertiesOnly> LW;
 
 bool
 WrapperFactory::IsLocationObject(JSObject *obj)
 {
-    const char *name = obj->getClass()->name;
+    const char *name = js::GetObjectClass(obj)->name;
     return name[0] == 'L' && !strcmp(name, "Location");
 }
 
 JSObject *
 WrapperFactory::WrapLocationObject(JSContext *cx, JSObject *obj)
 {
-    JSObject *xrayHolder = LW::createHolder(cx, obj, obj->getParent());
+    JSObject *xrayHolder = LW::createHolder(cx, obj, js::GetObjectParent(obj));
     if (!xrayHolder)
         return nsnull;
-    JSObject *wrapperObj = Wrapper::New(cx, obj, obj->getProto(), obj->getParent(),
+    JSObject *wrapperObj = Wrapper::New(cx, obj, js::GetObjectProto(obj), js::GetObjectParent(obj),
                                         &LW::singleton);
     if (!wrapperObj)
         return nsnull;
-    wrapperObj->setProxyExtra(js::ObjectValue(*xrayHolder));
+    js::SetProxyExtra(wrapperObj, js::ObjectValue(*xrayHolder));
     return wrapperObj;
 }
 
 // Call WaiveXrayAndWrap when you have a JS object that you don't want to be
 // wrapped in an Xray wrapper. cx->compartment is the compartment that will be
 // using the returned object. If the object to be wrapped is already in the
 // correct compartment, then this returns the unwrapped object.
 bool
 WrapperFactory::WaiveXrayAndWrap(JSContext *cx, jsval *vp)
 {
     if (JSVAL_IS_PRIMITIVE(*vp))
         return JS_WrapValue(cx, vp);
 
-    JSObject *obj = JSVAL_TO_OBJECT(*vp)->unwrap();
+    JSObject *obj = js::UnwrapObject(JSVAL_TO_OBJECT(*vp));
     obj = GetCurrentOuter(cx, obj);
-    if (obj->compartment() == cx->compartment) {
+    if (js::GetObjectCompartment(obj) == cx->compartment) {
         *vp = OBJECT_TO_JSVAL(obj);
         return true;
     }
 
     obj = WaiveXray(cx, obj);
     if (!obj)
         return false;
 
--- a/js/src/xpconnect/wrappers/WrapperFactory.h
+++ b/js/src/xpconnect/wrappers/WrapperFactory.h
@@ -48,17 +48,17 @@ class WrapperFactory {
            IS_XRAY_WRAPPER_FLAG    = WAIVE_XRAY_WRAPPER_FLAG << 1,
            SCRIPT_ACCESS_ONLY_FLAG = IS_XRAY_WRAPPER_FLAG << 1,
            PARTIALLY_TRANSPARENT   = SCRIPT_ACCESS_ONLY_FLAG << 1,
            SOW_FLAG                = PARTIALLY_TRANSPARENT << 1 };
 
     // Return true if any of any of the nested wrappers have the flag set.
     static bool HasWrapperFlag(JSObject *wrapper, uintN flag) {
         uintN flags = 0;
-        wrapper->unwrap(&flags);
+        js::UnwrapObject(wrapper, &flags);
         return !!(flags & flag);
     }
 
     static bool IsXrayWrapper(JSObject *wrapper) {
         return HasWrapperFlag(wrapper, IS_XRAY_WRAPPER_FLAG);
     }
 
     static bool IsPartiallyTransparent(JSObject *wrapper) {
--- a/js/src/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/src/xpconnect/wrappers/XrayWrapper.cpp
@@ -39,17 +39,16 @@
 
 #include "XrayWrapper.h"
 #include "AccessCheck.h"
 #include "FilteringWrapper.h"
 #include "CrossOriginWrapper.h"
 #include "WrapperFactory.h"
 
 #include "jscntxt.h"
-#include "jsiter.h"
 
 #include "nsINode.h"
 #include "nsIDocument.h"
 
 #include "XPCWrapper.h"
 #include "xpcprivate.h"
 
 namespace xpc {
@@ -63,26 +62,26 @@ static const uint32 JSSLOT_EXPANDO = 2;
 class ResolvingId
 {
   public:
     ResolvingId(JSObject *holder, jsid id)
       : mId(id),
         mPrev(getResolvingId(holder)),
         mHolder(holder)
     {
-        holder->setSlot(JSSLOT_RESOLVING, PrivateValue(this));
+        js::SetReservedSlot(holder, JSSLOT_RESOLVING, PrivateValue(this));
     }
 
     ~ResolvingId() {
         NS_ASSERTION(getResolvingId(mHolder) == this, "unbalanced ResolvingIds");
-        mHolder->setSlot(JSSLOT_RESOLVING, PrivateValue(mPrev));
+        js::SetReservedSlot(mHolder, JSSLOT_RESOLVING, PrivateValue(mPrev));
     }
 
     static ResolvingId *getResolvingId(JSObject *holder) {
-        return (ResolvingId *)holder->getSlot(JSSLOT_RESOLVING).toPrivate();
+        return (ResolvingId *)js::GetReservedSlot(holder, JSSLOT_RESOLVING).toPrivate();
     }
 
     jsid mId;
     ResolvingId *mPrev;
 
   private:
     JSObject *mHolder;
 };
@@ -117,83 +116,83 @@ JSClass HolderClass = {
 
 }
 
 using namespace XrayUtils;
 
 static JSObject *
 GetHolder(JSObject *obj)
 {
-    return &obj->getProxyExtra().toObject();
+    return &js::GetProxyExtra(obj).toObject();
 }
 
 static XPCWrappedNative *
 GetWrappedNative(JSObject *obj)
 {
     NS_ASSERTION(IS_WN_WRAPPER_OBJECT(obj), "expected a wrapped native here");
-    return static_cast<XPCWrappedNative *>(obj->getPrivate());
+    return static_cast<XPCWrappedNative *>(js::GetObjectPrivate(obj));
 }
 
 static XPCWrappedNative *
 GetWrappedNativeFromHolder(JSObject *holder)
 {
-    NS_ASSERTION(holder->getJSClass() == &HolderClass, "expected a native property holder object");
-    return static_cast<XPCWrappedNative *>(holder->getSlot(JSSLOT_WN).toPrivate());
+    NS_ASSERTION(js::GetObjectJSClass(holder) == &HolderClass, "expected a native property holder object");
+    return static_cast<XPCWrappedNative *>(js::GetReservedSlot(holder, JSSLOT_WN).toPrivate());
 }
 
 static JSObject *
 GetWrappedNativeObjectFromHolder(JSObject *holder)
 {
-    NS_ASSERTION(holder->getJSClass() == &HolderClass, "expected a native property holder object");
+    NS_ASSERTION(js::GetObjectJSClass(holder) == &HolderClass, "expected a native property holder object");
     return GetWrappedNativeFromHolder(holder)->GetFlatJSObject();
 }
 
 static JSObject *
 GetExpandoObject(JSObject *holder)
 {
-    NS_ASSERTION(holder->getJSClass() == &HolderClass, "expected a native property holder object");
-    return holder->getSlot(JSSLOT_EXPANDO).toObjectOrNull();
+    NS_ASSERTION(js::GetObjectJSClass(holder) == &HolderClass, "expected a native property holder object");
+    return js::GetReservedSlot(holder, JSSLOT_EXPANDO).toObjectOrNull();
 }
 
 static JSObject *
 EnsureExpandoObject(JSContext *cx, JSObject *holder)
 {
-    NS_ASSERTION(holder->getJSClass() == &HolderClass, "expected a native property holder object");
+    NS_ASSERTION(js::GetObjectJSClass(holder) == &HolderClass, "expected a native property holder object");
     JSObject *expando = GetExpandoObject(holder);
     if (expando)
         return expando;
     CompartmentPrivate *priv =
-        (CompartmentPrivate *)JS_GetCompartmentPrivate(cx, holder->compartment());
+        (CompartmentPrivate *)JS_GetCompartmentPrivate(cx, js::GetObjectCompartment(holder));
     XPCWrappedNative *wn = GetWrappedNativeFromHolder(holder);
     expando = priv->LookupExpandoObject(wn);
     if (!expando) {
-        expando = JS_NewObjectWithGivenProto(cx, nsnull, nsnull, holder->getParent());
+        expando = JS_NewObjectWithGivenProto(cx, nsnull, nsnull, js::GetObjectParent(holder));
         if (!expando)
             return NULL;
         // Add the expando object to the expando map to keep it alive.
         if (!priv->RegisterExpandoObject(wn, expando)) {
             JS_ReportOutOfMemory(cx);
             return NULL;
         }
         // Make sure the wn stays alive so it keeps the expando object alive.
         nsRefPtr<nsXPCClassInfo> ci;
         CallQueryInterface(wn->Native(), getter_AddRefs(ci));
         if (ci)
             ci->PreserveWrapper(wn->Native());
     }
-    holder->setSlot(JSSLOT_EXPANDO, ObjectValue(*expando));
+    js::SetReservedSlot(holder, JSSLOT_EXPANDO, ObjectValue(*expando));
     return expando;
 }
 
 static inline JSObject *
 FindWrapper(JSObject *wrapper)
 {
-    while (!wrapper->isWrapper() ||
+    while (!js::IsWrapper(wrapper) ||
            !(Wrapper::wrapperHandler(wrapper)->flags() & WrapperFactory::IS_XRAY_WRAPPER_FLAG)) {
-        wrapper = wrapper->getProto();
+        wrapper = js::GetObjectProto(wrapper);
         // NB: we must eventually hit our wrapper.
     }
 
     return wrapper;
 }
 
 // Some DOM objects have shared properties that don't have an explicit
 // getter/setter and rely on the class getter/setter. We install a
@@ -248,17 +247,17 @@ holder_set(JSContext *cx, JSObject *wrap
 }
 
 static bool
 ResolveNativeProperty(JSContext *cx, JSObject *wrapper, JSObject *holder, jsid id, bool set,
                       JSPropertyDescriptor *desc)
 {
     desc->obj = NULL;
 
-    NS_ASSERTION(holder->getJSClass() == &HolderClass, "expected a native property holder object");
+    NS_ASSERTION(js::GetObjectJSClass(holder) == &HolderClass, "expected a native property holder object");
     JSObject *wnObject = GetWrappedNativeObjectFromHolder(holder);
     XPCWrappedNative *wn = GetWrappedNative(wnObject);
 
     // This will do verification and the method lookup for us.
     XPCCallContext ccx(JS_CALLER, cx, wnObject, nsnull, id);
 
     // There are no native numeric properties, so we can shortcut here. We will not
     // find the property.
@@ -318,29 +317,29 @@ ResolveNativeProperty(JSContext *cx, JSO
         desc->getter = JS_PropertyStub;
         desc->setter = JS_StrictPropertyStub;
     }
 
     if (!JS_WrapValue(cx, &desc->value) || !JS_WrapValue(cx, &fval))
         return false;
 
     if (desc->attrs & JSPROP_GETTER)
-        desc->getter = CastAsJSPropertyOp(JSVAL_TO_OBJECT(fval));
+        desc->getter = js::CastAsJSPropertyOp(JSVAL_TO_OBJECT(fval));
     if (desc->attrs & JSPROP_SETTER)
-        desc->setter = CastAsJSStrictPropertyOp(JSVAL_TO_OBJECT(fval));
+        desc->setter = js::CastAsJSStrictPropertyOp(JSVAL_TO_OBJECT(fval));
 
     // Define the property.
     return JS_DefinePropertyById(cx, holder, id, desc->value,
                                  desc->getter, desc->setter, desc->attrs);
 }
 
 static JSBool
 wrappedJSObject_getter(JSContext *cx, JSObject *wrapper, jsid id, jsval *vp)
 {
-    if (!wrapper->isWrapper() || !WrapperFactory::IsXrayWrapper(wrapper)) {
+    if (!IsWrapper(wrapper) || !WrapperFactory::IsXrayWrapper(wrapper)) {
         JS_ReportError(cx, "Unexpected object");
         return false;
     }
 
     *vp = OBJECT_TO_JSVAL(wrapper);
 
     return WrapperFactory::WaiveXrayAndWrap(cx, vp);
 }
@@ -368,17 +367,17 @@ WrapURI(JSContext *cx, nsIURI *uri, jsva
         return false;
     }
     return true;
 }
 
 static JSBool
 documentURIObject_getter(JSContext *cx, JSObject *wrapper, jsid id, jsval *vp)
 {
-    if (!wrapper->isWrapper() || !WrapperFactory::IsXrayWrapper(wrapper)) {
+    if (!IsWrapper(wrapper) || !WrapperFactory::IsXrayWrapper(wrapper)) {
         JS_ReportError(cx, "Unexpected object");
         return false;
     }
 
     JSObject *holder = GetHolder(wrapper);
     XPCWrappedNative *wn = GetWrappedNativeFromHolder(holder);
     nsCOMPtr<nsIDocument> native = do_QueryWrappedNative(wn);
     if (!native) {
@@ -393,17 +392,17 @@ documentURIObject_getter(JSContext *cx, 
     }
 
     return WrapURI(cx, uri, vp);
 }
 
 static JSBool
 baseURIObject_getter(JSContext *cx, JSObject *wrapper, jsid id, jsval *vp)
 {
-    if (!wrapper->isWrapper() || !WrapperFactory::IsXrayWrapper(wrapper)) {
+    if (!IsWrapper(wrapper) || !WrapperFactory::IsXrayWrapper(wrapper)) {
         JS_ReportError(cx, "Unexpected object");
         return false;
     }
 
     JSObject *holder = GetHolder(wrapper);
     XPCWrappedNative *wn = GetWrappedNativeFromHolder(holder);
     nsCOMPtr<nsINode> native = do_QueryWrappedNative(wn);
     if (!native) {
@@ -417,17 +416,17 @@ baseURIObject_getter(JSContext *cx, JSOb
     }
 
     return WrapURI(cx, uri, vp);
 }
 
 static JSBool
 nodePrincipal_getter(JSContext *cx, JSObject *wrapper, jsid id, jsval *vp)
 {
-    if (!wrapper->isWrapper() || !WrapperFactory::IsXrayWrapper(wrapper)) {
+    if (!IsWrapper(wrapper) || !WrapperFactory::IsXrayWrapper(wrapper)) {
         JS_ReportError(cx, "Unexpected object");
         return false;
     }
 
     JSObject *holder = GetHolder(wrapper);
     XPCWrappedNative *wn = GetWrappedNativeFromHolder(holder);
     nsCOMPtr<nsINode> node = do_QueryWrappedNative(wn);
     if (!node) {
@@ -446,17 +445,17 @@ nodePrincipal_getter(JSContext *cx, JSOb
     }
     return true;
 }
 
 static JSBool
 XrayToString(JSContext *cx, uintN argc, jsval *vp)
 {
     JSObject *wrapper = JS_THIS_OBJECT(cx, vp);
-    if (!wrapper->isWrapper() || !WrapperFactory::IsXrayWrapper(wrapper)) {
+    if (!IsWrapper(wrapper) || !WrapperFactory::IsXrayWrapper(wrapper)) {
         JS_ReportError(cx, "XrayToString called on an incompatible object");
         return false;
     }
     JSObject *holder = GetHolder(wrapper);
     XPCWrappedNative *wn = GetWrappedNativeFromHolder(holder);
     JSObject *wrappednative = wn->GetFlatJSObject();
 
     XPCCallContext ccx(JS_CALLER, cx, wrappednative);
@@ -533,17 +532,17 @@ IsTransparent(JSContext *cx, JSObject *w
 
     if (!WrapperFactory::IsPartiallyTransparent(wrapper))
         return false;
 
     // Redirect access straight to the wrapper if UniversalXPConnect is enabled.
     if (IsPrivilegedScript())
         return true;
 
-    return AccessCheck::documentDomainMakesSameOrigin(cx, wrapper->unwrap());
+    return AccessCheck::documentDomainMakesSameOrigin(cx, UnwrapObject(wrapper));
 }
 
 }
 
 template <typename Base>
 bool
 XrayWrapper<Base>::resolveOwnProperty(JSContext *cx, JSObject *wrapper, jsid id, bool set,
                                       PropertyDescriptor *desc)
@@ -700,17 +699,17 @@ XrayWrapper<Base>::getPropertyDescriptor
 
     if (id == nsXPConnect::GetRuntimeInstance()->GetStringID(XPCJSRuntime::IDX_TO_STRING)) {
         desc->obj = wrapper;
         desc->attrs = 0;
         desc->getter = NULL;
         desc->setter = NULL;
         desc->shortid = 0;
 
-        JSObject *toString = JS_NewFunction(cx, XrayToString, 0, 0, holder, "toString");
+        JSObject *toString = JS_GetFunctionObject(JS_NewFunction(cx, XrayToString, 0, 0, holder, "toString"));
         if (!toString)
             return false;
         desc->value = OBJECT_TO_JSVAL(toString);
         return true;
     }
 
     return true;
 }
@@ -1026,35 +1025,34 @@ template <typename Base>
 JSObject *
 XrayWrapper<Base>::createHolder(JSContext *cx, JSObject *wrappedNative, JSObject *parent)
 {
     JSObject *holder = JS_NewObjectWithGivenProto(cx, &HolderClass, nsnull, parent);
     if (!holder)
         return nsnull;
 
     CompartmentPrivate *priv =
-        (CompartmentPrivate *)JS_GetCompartmentPrivate(cx, holder->compartment());
-    JSObject *inner = wrappedNative;
-    OBJ_TO_INNER_OBJECT(cx, inner);
+        (CompartmentPrivate *)JS_GetCompartmentPrivate(cx, js::GetObjectCompartment(holder));
+    JSObject *inner = JS_ObjectToInnerObject(cx, wrappedNative);
     XPCWrappedNative *wn = GetWrappedNative(inner);
     Value expando = ObjectOrNullValue(priv->LookupExpandoObject(wn));
 
     // A note about ownership: the holder has a direct pointer to the wrapped
     // native that we're wrapping. Normally, we'd have to AddRef the pointer
     // so that it doesn't have to be collected, but then we'd have to tell the
     // cycle collector. Fortunately for us, we know that the Xray wrapper
     // itself has a reference to the flat JS object which will hold the
     // wrapped native alive. Furthermore, the reachability of that object and
     // the associated holder are exactly the same, so we can use that for our
     // strong reference.
     JS_ASSERT(IS_WN_WRAPPER(wrappedNative) ||
-              wrappedNative->getClass()->ext.innerObject);
-    holder->setSlot(JSSLOT_WN, PrivateValue(wn));
-    holder->setSlot(JSSLOT_RESOLVING, PrivateValue(NULL));
-    holder->setSlot(JSSLOT_EXPANDO, expando);
+              js::GetObjectClass(wrappedNative)->ext.innerObject);
+    js::SetReservedSlot(holder, JSSLOT_WN, PrivateValue(wn));
+    js::SetReservedSlot(holder, JSSLOT_RESOLVING, PrivateValue(NULL));
+    js::SetReservedSlot(holder, JSSLOT_EXPANDO, expando);
     return holder;
 }
 
 #define XPCNW XrayWrapper<CrossCompartmentWrapper>
 #define SCNW XrayWrapper<Wrapper>
 
 template <> XPCNW XPCNW::singleton(0);
 template <> SCNW SCNW::singleton(0);