Remove jsobj.h from installed headers, bug 690943. r=luke
authorBrian Hackett <bhackett1024@gmail.com>
Tue, 04 Oct 2011 07:06:54 -0700
changeset 78730 d6756be38c9fcfa206c1a0e660fb0b2dea8ea14d
parent 78729 8a26e77cffaed07138db3328bafc209a7ca37250
child 78731 3304b551a1b5f7def8fa237c509b7db31c03fc91
child 78760 e05e1b35ebedc2fd665a251d3f6c4156e08dd45f
push id506
push userclegnitto@mozilla.com
push dateWed, 09 Nov 2011 02:03:18 +0000
treeherdermozilla-aurora@63587fc7bb93 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs690943
milestone10.0a1
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);