--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1637,24 +1637,24 @@ jsid nsDOMClassInfo::sOnafterscriptexecu
jsid nsDOMClassInfo::sWrappedJSObject_id = JSID_VOID;
static const JSClass *sObjectClass = nsnull;
/**
* Set our JSClass pointer for the Object class
*/
static void
-FindObjectClass(JSContext *cx, JSObject* aGlobalObject)
+FindObjectClass(JSObject* aGlobalObject)
{
NS_ASSERTION(!sObjectClass,
"Double set of sObjectClass");
JSObject *obj, *proto = aGlobalObject;
do {
obj = proto;
- proto = JS_GetPrototype(cx, obj);
+ proto = obj->getProto();
} while (proto);
sObjectClass = obj->getJSClass();
}
static void
PrintWarningOnConsole(JSContext *cx, const char *stringBundleProperty)
{
@@ -4656,17 +4656,17 @@ nsDOMClassInfo::PostCreatePrototype(JSCo
count, mData->mInterfaces)) {
JS_ClearPendingException(cx);
}
// This is called before any other location that requires
// sObjectClass, so compute it here. We assume that nobody has had a
// chance to monkey around with proto's prototype chain before this.
if (!sObjectClass) {
- FindObjectClass(cx, proto);
+ FindObjectClass(proto);
NS_ASSERTION(sObjectClass && !strcmp(sObjectClass->name, "Object"),
"Incorrect object class!");
}
NS_ASSERTION(::JS_GetPrototype(cx, proto) &&
JS_GET_CLASS(cx, ::JS_GetPrototype(cx, proto)) == sObjectClass,
"Hmm, somebody did something evil?");
@@ -6951,17 +6951,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
// 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) &&
win->IsInnerWindow()) {
JSObject *realObj;
wrapper->GetJSObject(&realObj);
if (obj == realObj) {
- JSObject *proto = JS_GetPrototype(cx, obj);
+ JSObject *proto = obj->getProto();
if (proto) {
JSObject *pobj = NULL;
jsval val;
if (!::JS_LookupPropertyWithFlagsById(cx, proto, id, flags,
&pobj, &val)) {
*_retval = JS_FALSE;
@@ -8647,17 +8647,17 @@ nsHTMLDocumentSH::DocumentAllGetProperty
// 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 = JS_GetPrototype(cx, obj);
+ obj = obj->getProto();
if (!obj) {
NS_ERROR("The JS engine lies!");
return JS_TRUE;
}
}
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -766,17 +766,17 @@ nsOuterWindowProxy::singleton;
JSObject *
NS_NewOuterWindowProxy(JSContext *cx, JSObject *parent)
{
JSAutoEnterCompartment ac;
if (!ac.enter(cx, parent)) {
return nsnull;
}
- JSObject *obj = JSWrapper::New(cx, parent, JS_GetPrototype(cx, parent), parent,
+ JSObject *obj = JSWrapper::New(cx, parent, parent->getProto(), parent,
&nsOuterWindowProxy::singleton);
NS_ASSERTION(obj->getClass()->ext.innerObject, "bad class");
return obj;
}
//*****************************************************************************
//*** nsGlobalWindow: Object Management
//*****************************************************************************
--- a/js/ipc/ObjectWrapperParent.cpp
+++ b/js/ipc/ObjectWrapperParent.cpp
@@ -223,17 +223,17 @@ ObjectWrapperParent::GetJSObject(JSConte
}
return mObj;
}
static ObjectWrapperParent*
Unwrap(JSContext* cx, JSObject* obj)
{
while (obj->getClass() != &ObjectWrapperParent::sCPOW_JSClass)
- if (!(obj = JS_GetPrototype(cx, obj)))
+ if (!(obj = obj->getProto()))
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
@@ -195,17 +195,17 @@ private:
// otherwise a const method.
JSObject* mObj;
JSContext* mCx;
bool mRooted;
static Handle*
Unwrap(JSContext* cx, JSObject* obj) {
while (obj && obj->getJSClass() != &sHandle_JSClass)
- obj = JS_GetPrototype(cx, obj);
+ obj = obj->getProto();
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/src/jsapi-tests/testBug604087.cpp
+++ b/js/src/jsapi-tests/testBug604087.cpp
@@ -44,17 +44,17 @@ PreWrap(JSContext *cx, JSObject *scope,
static JSObject *
Wrap(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent, uintN flags)
{
return JSWrapper::New(cx, obj, proto, parent, &JSCrossCompartmentWrapper::singleton);
}
BEGIN_TEST(testBug604087)
{
- JSObject *outerObj = JSWrapper::New(cx, global, JS_GetPrototype(cx, global), global,
+ JSObject *outerObj = JSWrapper::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));
@@ -67,17 +67,17 @@ BEGIN_TEST(testBug604087)
CHECK(c4wrapper);
c4wrapper->setProxyExtra(js::Int32Value(4));
compartment4 = c4wrapper = NULL;
JSObject *next;
{
JSAutoEnterCompartment ac;
CHECK(ac.enter(cx, compartment2));
- next = JSWrapper::New(cx, compartment2, JS_GetPrototype(cx, compartment2), compartment2,
+ next = JSWrapper::New(cx, compartment2, compartment2->getProto(), compartment2,
&OuterWrapper::singleton);
CHECK(next);
}
JS_SetWrapObjectCallbacks(JS_GetRuntime(cx), Wrap, PreWrap);
CHECK(JS_TransplantObject(cx, outerObj, next));
return true;
}
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -2347,16 +2347,18 @@ array_splice(JSContext *cx, uintN argc,
if (obj && obj->isArray()) {
type = obj->getType();
} else {
/*
* Make a new type object for the return value. This is an unexpected
* result of the call so mark it at the callsite.
*/
type = cx->getTypeCallerInitObject(true);
+ if (!type)
+ return JS_FALSE;
cx->markTypeObjectUnknownProperties(type);
cx->markTypeCallerUnexpected((jstype) type);
}
if (cx->isTypeCallerMonitored())
cx->markTypeObjectUnknownProperties(type);
/*
@@ -2547,16 +2549,18 @@ array_concat(JSContext *cx, uintN argc,
if (!nobj)
return JS_FALSE;
vp->setObject(*nobj);
length = 0;
}
/* Get the type object to use for the result. */
TypeObject *ntype = cx->getTypeCallerInitObject(true);
+ if (!ntype)
+ return JS_FALSE;
if (cx->isTypeCallerMonitored())
cx->markTypeObjectUnknownProperties(ntype);
AutoValueRooter tvr(cx);
/* Loop over [0, argc] to concat args into nobj, expanding all Arrays. */
for (uintN i = 0; i <= argc; i++) {
if (!JS_CHECK_OPERATION_LIMIT(cx))
@@ -2660,16 +2664,18 @@ array_slice(JSContext *cx, uintN argc, V
if (obj->isArray()) {
type = obj->getType();
} else {
/*
* Make a new type object for the return value. This is an unexpected
* result of the call so mark it at the callsite.
*/
type = cx->getTypeCallerInitObject(true);
+ if (!type)
+ return JS_FALSE;
cx->markTypeObjectUnknownProperties(type);
cx->markTypeCallerUnexpected((jstype) type);
}
if (cx->isTypeCallerMonitored())
cx->markTypeObjectUnknownProperties(type);
if (obj->isDenseArray() && end <= obj->getDenseArrayCapacity() &&
@@ -2863,16 +2869,18 @@ array_extra(JSContext *cx, ArrayExtraMod
break;
case MAP:
case FILTER:
newlen = (mode == MAP) ? length : 0;
newarr = js_NewArrayObject(cx, newlen, NULL);
if (!newarr)
return JS_FALSE;
newtype = cx->getTypeCallerInitObject(true);
+ if (!newtype)
+ return JS_FALSE;
newarr->setType(newtype);
vp->setObject(*newarr);
break;
case SOME:
vp->setBoolean(false);
break;
case EVERY:
vp->setBoolean(true);
@@ -3330,16 +3338,18 @@ NewDenseArrayObject(JSContext *cx, jsuin
JSBool
js_Array(JSContext *cx, uintN argc, Value *vp)
{
jsuint length;
const Value *vector;
TypeObject *type = cx->getTypeCallerInitObject(true);
+ if (!type)
+ return JS_FALSE;
if (argc == 0) {
length = 0;
vector = NULL;
} else if (argc > 1) {
length = (jsuint) argc;
vector = vp + 2;
} else if (!vp[2].isNumber()) {
@@ -3627,13 +3637,12 @@ js_CloneDensePrimitiveArray(JSContext *c
}
vector.append(val);
}
*clone = js_NewArrayObject(cx, initlen, vector.begin());
if (!*clone)
return JS_FALSE;
- (*clone)->setType(obj->getType());
(*clone)->setArrayLength(cx, length);
return JS_TRUE;
}
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -366,17 +366,18 @@ WrapEscapingClosure(JSContext *cx, JSSta
*/
JSObject *scopeChain = GetScopeChain(cx, fp);
if (!scopeChain)
return NULL;
JSObject *wfunobj = NewFunction(cx, scopeChain);
if (!wfunobj)
return NULL;
- wfunobj->setType(fun->getType());
+ if (fun->getProto() == wfunobj->getProto())
+ wfunobj->setType(fun->getType());
AutoObjectRooter tvr(cx, wfunobj);
JSFunction *wfun = (JSFunction *) wfunobj;
wfunobj->setPrivate(wfun);
wfun->nargs = fun->nargs;
wfun->flags = fun->flags | JSFUN_HEAVYWEIGHT;
wfun->u.i.nvars = fun->u.i.nvars;
wfun->u.i.nupvars = fun->u.i.nupvars;
--- a/js/src/jsinfer.h
+++ b/js/src/jsinfer.h
@@ -40,16 +40,17 @@
/* Definitions related to javascript type inference. */
#ifndef jsinfer_h___
#define jsinfer_h___
#include "jsarena.h"
#include "jstl.h"
#include "jsprvtd.h"
+#include "jsvalue.h"
#ifndef _MSC_VER
#include <sys/time.h>
#endif
/* Define to get detailed output of inference actions. */
namespace js { namespace analyze {
--- a/js/src/jsinferinlines.h
+++ b/js/src/jsinferinlines.h
@@ -484,16 +484,18 @@ JSScript::setTypeNesting(JSScript *paren
}
inline js::types::TypeObject *
JSScript::getTypeInitObject(JSContext *cx, const jsbytecode *pc, bool isArray)
{
#ifdef JS_TYPE_INFERENCE
/* :FIXME: */
JS_ASSERT(!analysis->failed());
+ if (compileAndGo)
+ return cx->getTypeNewObject(isArray ? JSProto_Array : JSProto_Object);
return analysis->getCode(pc).getInitObject(cx, isArray);
#else
return cx->getTypeNewObject(isArray ? JSProto_Array : JSProto_Object);
#endif
}
inline void
JSScript::typeMonitorResult(JSContext *cx, const jsbytecode *pc, unsigned index,
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -2773,16 +2773,18 @@ js_Object(JSContext *cx, uintN argc, Val
if (!obj) {
/* Make an object whether this was called with 'new' or not. */
JS_ASSERT(!argc || vp[2].isNull() || vp[2].isUndefined());
gc::FinalizeKind kind = NewObjectGCKind(cx, &js_ObjectClass);
obj = NewBuiltinClassInstance(cx, &js_ObjectClass, kind);
if (!obj)
return JS_FALSE;
TypeObject *type = cx->getTypeCallerInitObject(false);
+ if (!type)
+ return JS_FALSE;
obj->setType(type);
}
vp->setObject(*obj);
return JS_TRUE;
}
JSObject*
js_CreateThis(JSContext *cx, JSObject *callee)
@@ -3421,17 +3423,18 @@ JSObject::clone(JSContext *cx, JSObject
return NULL;
}
}
JSObject *clone = NewObject<WithProto::Given>(cx, getClass(),
proto, parent,
gc::FinalizeKind(finalizeKind()));
if (!clone)
return NULL;
- clone->setType(getType());
+ if (getProto() == proto)
+ clone->setType(getType());
if (isNative()) {
if (clone->isFunction() && (compartment() != clone->compartment())) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_CANT_CLONE_OBJECT);
return NULL;
}
if (getClass()->flags & JSCLASS_HAS_PRIVATE)
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -44,16 +44,17 @@
* JS object definitions.
*
* 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 "jsinfer.h"
#include "jshash.h"
#include "jspubtd.h"
#include "jsprvtd.h"
#include "jslock.h"
#include "jsvalue.h"
#include "jsvector.h"
#include "jscell.h"
@@ -654,21 +655,24 @@ struct JSObject : js::gc::Cell {
/* Extend this object to have shape as its last-added property. */
inline void extend(JSContext *cx, const js::Shape *shape, bool isDefinitelyAtom = false);
js::types::TypeObject* getType() const { return type; }
inline void clearType(JSContext *cx);
inline void setType(js::types::TypeObject *newType);
- inline JSObject *getProto() const;
inline js::types::TypeObject *getNewType(JSContext *cx);
void makeNewType(JSContext *cx);
+ JSObject * getProto() const {
+ return type->proto;
+ }
+
JSObject *getParent() const {
return parent;
}
void clearParent() {
parent = NULL;
}
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -607,22 +607,16 @@ JSObject::getNewType(JSContext *cx)
{
if (isDenseArray() && !makeDenseArraySlow(cx))
return NULL;
if (!newType)
makeNewType(cx);
return newType;
}
-inline JSObject *
-JSObject::getProto() const
-{
- return type->proto;
-}
-
inline void
JSObject::clearType(JSContext *cx)
{
type = cx->emptyTypeObject();
}
inline void
JSObject::setType(js::types::TypeObject *newType)
--- a/js/src/jsregexpinlines.h
+++ b/js/src/jsregexpinlines.h
@@ -233,16 +233,18 @@ RegExp::checkMatchPairs(JSString *input,
}
#endif
}
inline types::TypeObject *
GetRegExpMatchType(JSContext *cx)
{
types::TypeObject *type = cx->getTypeCallerInitObject(true);
+ if (!type)
+ return NULL;
cx->addTypeProperty(type, NULL, types::TYPE_STRING);
cx->addTypeProperty(type, "index", types::TYPE_INT32);
cx->addTypeProperty(type, "input", types::TYPE_STRING);
cx->markTypeArrayNotPacked(type, true);
return type;
}
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -4980,17 +4980,20 @@ mjit::Compiler::jsop_newinit()
break;
default:
JS_NOT_REACHED("Bad op");
return;
}
prepareStubCall(Uses(0));
- types::TypeObject *type = script->getTypeInitObject(cx, PC, isArray);
+ /* Don't bake in types for non-compileAndGo scripts. */
+ types::TypeObject *type = NULL;
+ if (script->compileAndGo)
+ type = script->getTypeInitObject(cx, PC, isArray);
masm.storePtr(ImmPtr(type), FrameAddress(offsetof(VMFrame, scratch)));
if (isArray) {
masm.move(Imm32(count), Registers::ArgReg1);
INLINE_STUBCALL(stubs::NewInitArray);
} else {
masm.move(ImmPtr(baseobj), Registers::ArgReg1);
INLINE_STUBCALL(stubs::NewInitObject);
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -1408,36 +1408,40 @@ stubs::NewInitArray(VMFrame &f, uint32 c
JSContext *cx = f.cx;
gc::FinalizeKind kind = GuessObjectGCKind(count, true);
JSObject *obj = NewArrayWithKind(cx, kind);
if (!obj || !obj->ensureSlots(cx, count))
THROWV(NULL);
TypeObject *type = (TypeObject *) f.scratch;
- obj->setType(type);
+ if (type)
+ obj->setType(type);
+
obj->setArrayLength(cx, count);
return obj;
}
JSObject * JS_FASTCALL
stubs::NewInitObject(VMFrame &f, JSObject *baseobj)
{
JSContext *cx = f.cx;
TypeObject *type = (TypeObject *) f.scratch;
if (!baseobj) {
gc::FinalizeKind kind = GuessObjectGCKind(0, false);
JSObject *obj = NewBuiltinClassInstance(cx, &js_ObjectClass, kind);
if (!obj)
THROWV(NULL);
- obj->setType(type);
+ if (type)
+ obj->setType(type);
return obj;
}
+ JS_ASSERT(type);
JSObject *obj = CopyInitializerObject(cx, baseobj, type);
if (!obj)
THROWV(NULL);
return obj;
}
void JS_FASTCALL
--- a/js/src/xpconnect/src/xpcdebug.cpp
+++ b/js/src/xpconnect/src/xpcdebug.cpp
@@ -35,22 +35,16 @@
* 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 "xpcprivate.h"
-#include "mozilla/mozalloc_undef_macro_wrappers.h"
-
-#include "jscntxt.h"
-#include "jsobj.h"
-#include "jsobjinlines.h"
-
#ifdef TAB
#undef TAB
#endif
#define TAB " "
static const char* JSVAL2String(JSContext* cx, jsval val, JSBool* isString,
JSAutoByteString *bytes)
{
--- a/js/src/xpconnect/src/xpcwrappednative.cpp
+++ b/js/src/xpconnect/src/xpcwrappednative.cpp
@@ -48,19 +48,16 @@
#include "xpclog.h"
#include "jstl.h"
#include "nsINode.h"
#include "xpcquickstubs.h"
#include "jsproxy.h"
#include "AccessCheck.h"
#include "WrapperFactory.h"
-#include "mozilla/mozalloc_undef_macro_wrappers.h"
-#include "jsobjinlines.h"
-
/***************************************************************************/
NS_IMPL_CYCLE_COLLECTION_CLASS(XPCWrappedNative)
NS_IMETHODIMP
NS_CYCLE_COLLECTION_CLASSNAME(XPCWrappedNative)::RootAndUnlinkJSObjects(void *p)
{
XPCWrappedNative *tmp = static_cast<XPCWrappedNative*>(p);