--- 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/", ®exp);
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 ∾
+ 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 ∾
- 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 ®s)
--- 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 ®s() 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 ®s, const CallArgs &args,
- JSObject &callee, JSFunction *fun, JSScript *script,
- InitialFrameFlags initial);
- bool pushInlineFrame(JSContext *cx, FrameRegs ®s, const CallArgs &args,
- JSObject &callee, JSFunction *fun, JSScript *script,
- InitialFrameFlags initial, Value **stackLimit);
- void popInlineFrame(FrameRegs ®s);
-
- /* 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 ®s() 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 ®s, const CallArgs &args,
+ JSObject &callee, JSFunction *fun, JSScript *script,
+ InitialFrameFlags initial);
+ bool pushInlineFrame(JSContext *cx, FrameRegs ®s, const CallArgs &args,
+ JSObject &callee, JSFunction *fun, JSScript *script,
+ InitialFrameFlags initial, Value **stackLimit);
+ void popInlineFrame(FrameRegs ®s);
+
+ /* 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);