Backed out 3 changesets (bug 855971, bug 820846) because of browser-chrome test failures

Backed out changeset a2245b038bcc (bug 855971)
Backed out changeset 2a999f8ee317 (bug 820846)
Backed out changeset 6dba144500f3 (bug 820846)
This commit is contained in:
Ehsan Akhgari 2013-05-04 19:27:20 -04:00
parent bf10328ba6
commit 5005320e02
27 changed files with 242 additions and 634 deletions

View File

@ -64,7 +64,7 @@ function testFrameParameters()
is(globalNodes[3].querySelector(".name").getAttribute("value"), "document",
"Should have the right property name for |document|.");
is(globalNodes[3].querySelector(".value").getAttribute("value"), "[object Proxy]",
is(globalNodes[3].querySelector(".value").getAttribute("value"), "[object HTMLDocument]",
"Should have the right property value for |document|.");
let buttonNode = gVars.getItemForNode(anonymousNodes[1]);
@ -190,18 +190,18 @@ function testFrameParameters()
.getAttribute("value"), '""',
"'formMethod' in buttonProtoNode should have the right value.");
is(documentProtoNode.get("domain").target.querySelector(".name")
.getAttribute("value"), "domain",
"Should have the right property name for 'domain' in documentProtoNode.");
is(documentProtoNode.get("domain").target.querySelector(".value")
.getAttribute("value"), '"example.com"',
"'domain' in documentProtoNode should have the right value.");
is(documentProtoNode.get("cookie").target.querySelector(".name")
.getAttribute("value"), "cookie",
"Should have the right property name for 'cookie' in documentProtoNode.");
is(documentProtoNode.get("cookie").target.querySelector(".value")
.getAttribute("value"), '""',
"'cookie' in documentProtoNode should have the right value.");
is(documentProtoNode.get("baseURI").target.querySelector(".name")
.getAttribute("value"), "baseURI",
"Should have the right property name for 'baseURI' in documentProtoNode.");
is(documentProtoNode.get("baseURI").target.querySelector(".value")
.getAttribute("value"), '"' + TAB_URL + '"',
"'baseURI' in documentProtoNode should have the right value.");
is(documentProtoNode.get("URL").target.querySelector(".name")
.getAttribute("value"), "URL",
"Should have the right property name for 'URL' in documentProtoNode.");
is(documentProtoNode.get("URL").target.querySelector(".value")
.getAttribute("value"), '"' + TAB_URL + '"',
"'URL' in documentProtoNode should have the right value.");
let buttonAsProtoProtoProtoNode = buttonAsProtoProtoNode.get("__proto__");

View File

@ -89,11 +89,11 @@ function testVariablesFiltering()
"There should be 0 variables displayed in the test scope");
is(loadScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the load scope");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 1,
"There should be 1 variables displayed in the global scope");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 2,
"There should be 2 variables displayed in the global scope");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match])").length, 7,
"There should be 7 properties displayed in the inner scope");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match])").length, 8,
"There should be 8 properties displayed in the inner scope");
is(mathScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the math scope");
is(testScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
@ -106,21 +106,25 @@ function testVariablesFiltering()
is(innerScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"this", "The only inner variable displayed should be 'this'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[0].getAttribute("value"),
"window", "The first inner property displayed should be 'window'");
"document", "The first inner property displayed should be 'document'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[1].getAttribute("value"),
"document", "The second inner property displayed should be 'document'");
"window", "The second inner property displayed should be 'window'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[2].getAttribute("value"),
"location", "The third inner property displayed should be 'location'");
"document", "The third inner property displayed should be 'document'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[3].getAttribute("value"),
"__proto__", "The fourth inner property displayed should be '__proto__'");
"location", "The fourth inner property displayed should be 'location'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[4].getAttribute("value"),
"__proto__", "The fifth inner property displayed should be '__proto__'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[5].getAttribute("value"),
"HTMLDocument", "The sixth inner property displayed should be 'HTMLDocument'");
"__proto__", "The sixth inner property displayed should be '__proto__'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[6].getAttribute("value"),
"HTMLDocument", "The seventh inner property displayed should be 'HTMLDocument'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[7].getAttribute("value"),
"HTMLDocument", "The eight inner property displayed should be 'HTMLDocument'");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"document", "The first global variable displayed should be 'document'");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[1].getAttribute("value"),
"HTMLDocument", "The first global variable displayed should be 'HTMLDocument'");
}
@ -179,11 +183,11 @@ function testVariablesFiltering()
"There should be 0 variables displayed in the test scope");
is(loadScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the load scope");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 1,
"There should be 1 variables displayed in the global scope");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 2,
"There should be 2 variables displayed in the global scope");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match])").length, 7,
"There should be 7 properties displayed in the inner scope");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match])").length, 8,
"There should be 8 properties displayed in the inner scope");
is(mathScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the math scope");
is(testScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
@ -196,21 +200,25 @@ function testVariablesFiltering()
is(innerScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"this", "The only inner variable displayed should be 'this'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[0].getAttribute("value"),
"window", "The first inner property displayed should be 'window'");
"document", "The first inner property displayed should be 'document'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[1].getAttribute("value"),
"document", "The second inner property displayed should be 'document'");
"window", "The second inner property displayed should be 'window'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[2].getAttribute("value"),
"location", "The third inner property displayed should be 'location'");
"document", "The third inner property displayed should be 'document'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[3].getAttribute("value"),
"__proto__", "The fourth inner property displayed should be '__proto__'");
"location", "The fourth inner property displayed should be 'location'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[4].getAttribute("value"),
"__proto__", "The fifth inner property displayed should be '__proto__'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[5].getAttribute("value"),
"HTMLDocument", "The sixth inner property displayed should be 'HTMLDocument'");
"__proto__", "The sixth inner property displayed should be '__proto__'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[6].getAttribute("value"),
"HTMLDocument", "The seventh inner property displayed should be 'HTMLDocument'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[7].getAttribute("value"),
"HTMLDocument", "The eight inner property displayed should be 'HTMLDocument'");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"document", "The first global variable displayed should be 'document'");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[1].getAttribute("value"),
"HTMLDocument", "The first global variable displayed should be 'HTMLDocument'");
}

View File

@ -22,7 +22,7 @@ function consoleOpened(hud) {
function testConsoleDir(hud, ev, view) {
findVariableViewProperties(view, [
{ name: "__proto__.__proto__.querySelectorAll", value: "[object Function]" },
{ name: "__proto__.querySelectorAll", value: "[object Function]" },
{ name: "location", value: "[object Location]" },
{ name: "__proto__.write", value: "[object Function]" },
], { webconsole: hud }).then(finishTest);

View File

@ -437,14 +437,6 @@ nsIdentifierMapEntry::RemoveNameElement(Element* aElement)
}
}
bool
nsIdentifierMapEntry::HasIdElementExposedAsHTMLDocumentProperty()
{
Element* idElement = GetIdElement();
return idElement &&
nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(idElement);
}
// static
size_t
nsIdentifierMapEntry::SizeOfExcludingThis(nsIdentifierMapEntry* aEntry,
@ -1792,9 +1784,6 @@ CustomPrototypeTrace(const nsAString& aName, JSObject* aObject, void *aArg)
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDocument)
CustomPrototypeTraceArgs customPrototypeArgs = { aCallback, aClosure };
tmp->mCustomPrototypes.EnumerateRead(CustomPrototypeTrace, &customPrototypeArgs);
if (tmp->PreservingWrapper()) {
NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mExpandoAndGeneration.expando);
}
nsINode::Trace(tmp, aCallback, aClosure);
NS_IMPL_CYCLE_COLLECTION_TRACE_END
@ -1859,8 +1848,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
// else, and not unlink an awful lot here.
tmp->mIdentifierMap.Clear();
++tmp->mExpandoAndGeneration.generation;
tmp->mExpandoAndGeneration.expando = JS::UndefinedValue();
tmp->mCustomPrototypes.Clear();
@ -2738,19 +2725,11 @@ nsIDocument::GetLastModified(nsAString& aLastModified) const
void
nsDocument::AddToNameTable(Element *aElement, nsIAtom* aName)
{
MOZ_ASSERT(nsGenericHTMLElement::ShouldExposeNameAsHTMLDocumentProperty(aElement),
"Only put elements that need to be exposed as document['name'] in "
"the named table.");
nsIdentifierMapEntry *entry =
mIdentifierMap.PutEntry(nsDependentAtomString(aName));
// Null for out-of-memory
if (entry) {
if (!entry->HasNameElement() &&
!entry->HasIdElementExposedAsHTMLDocumentProperty()) {
++mExpandoAndGeneration.generation;
}
entry->AddNameElement(this, aElement);
}
}
@ -2768,10 +2747,6 @@ nsDocument::RemoveFromNameTable(Element *aElement, nsIAtom* aName)
return;
entry->RemoveNameElement(aElement);
if (!entry->HasNameElement() &&
!entry->HasIdElementExposedAsHTMLDocumentProperty()) {
++mExpandoAndGeneration.generation;
}
}
void
@ -2781,11 +2756,6 @@ nsDocument::AddToIdTable(Element *aElement, nsIAtom* aId)
mIdentifierMap.PutEntry(nsDependentAtomString(aId));
if (entry) { /* True except on OOM */
if (nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(aElement) &&
!entry->HasNameElement() &&
!entry->HasIdElementExposedAsHTMLDocumentProperty()) {
++mExpandoAndGeneration.generation;
}
entry->AddIdElement(aElement);
}
}
@ -2806,11 +2776,6 @@ nsDocument::RemoveFromIdTable(Element *aElement, nsIAtom* aId)
return;
entry->RemoveIdElement(aElement);
if (nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(aElement) &&
!entry->HasNameElement() &&
!entry->HasIdElementExposedAsHTMLDocumentProperty()) {
++mExpandoAndGeneration.generation;
}
if (entry->IsEmpty()) {
mIdentifierMap.RawRemoveEntry(entry);
}
@ -8157,7 +8122,6 @@ nsDocument::DestroyElementMaps()
#endif
mStyledLinks.Clear();
mIdentifierMap.Clear();
++mExpandoAndGeneration.generation;
}
static

View File

@ -178,7 +178,6 @@ public:
* GetIdElement(true) if non-null.
*/
void SetImageElement(Element* aElement);
bool HasIdElementExposedAsHTMLDocumentProperty();
bool HasContentChangeCallback() { return mChangeCallbacks != nullptr; }
void AddContentChangeCallback(nsIDocument::IDTargetObserver aCallback,
@ -1140,9 +1139,6 @@ public:
virtual void SetTitle(const nsAString& aTitle, mozilla::ErrorResult& rv);
static void XPCOMShutdown();
js::ExpandoAndGeneration mExpandoAndGeneration;
protected:
already_AddRefed<nsIPresShell> doCreateShell(nsPresContext* aContext,
nsViewManager* aViewManager,

View File

@ -69,9 +69,9 @@ function checkHasNoName(removed, test) {
is(i3_2.getAttribute("name"), attrValue, "i3_2 getAttribute " + test);
is(i3_3.getAttribute("name"), attrValue, "i3_3 getAttribute " + test);
is(document.n1, undefined, "doc.n1 " + test);
is(document.n2, undefined, "doc.n2 " + test);
is(document.n3, undefined, "doc.n3 " + test);
todo_is(document.n1, undefined, "doc.n1 " + test);
todo_is(document.n2, undefined, "doc.n2 " + test);
todo_is(document.n3, undefined, "doc.n3 " + test);
}
// Check that dynamic modifications of attribute work
@ -326,7 +326,7 @@ i3_1.addEventListener("DOMAttrModified", function(e) {
}, false);
i3_1.name = "n3";
ok(mutateFired, "mutation event fired");
is(document.n3, undefined, "named was readded during mutation");
todo_is(document.n3, undefined, "named was readded during mutation");
removeNode(i3_1);
SpecialPowers.gc();

View File

@ -1047,6 +1047,16 @@ nsGenericHTMLElement::GetBaseTarget(nsAString& aBaseTarget) const
//----------------------------------------------------------------------
static bool
CanHaveName(nsIAtom* aTag)
{
return aTag == nsGkAtoms::img ||
aTag == nsGkAtoms::form ||
aTag == nsGkAtoms::applet ||
aTag == nsGkAtoms::embed ||
aTag == nsGkAtoms::object;
}
bool
nsGenericHTMLElement::ParseAttribute(int32_t aNamespaceID,
nsIAtom* aAttribute,

View File

@ -717,20 +717,6 @@ public:
static bool TouchEventsEnabled(JSContext* /* unused */, JSObject* /* unused */);
static inline bool
CanHaveName(nsIAtom* aTag)
{
return aTag == nsGkAtoms::img ||
aTag == nsGkAtoms::form ||
aTag == nsGkAtoms::applet ||
aTag == nsGkAtoms::embed ||
aTag == nsGkAtoms::object;
}
static inline bool
ShouldExposeNameAsHTMLDocumentProperty(Element* aElement)
{
return aElement->IsHTML() && CanHaveName(aElement->Tag());
}
static inline bool
ShouldExposeIdAsHTMLDocumentProperty(Element* aElement)
{

View File

@ -217,8 +217,7 @@ ImageListener::OnStartRequest(nsIRequest* request, nsISupports *ctxt)
}
ImageDocument::ImageDocument()
: MediaDocument(true),
mOriginalZoomLevel(1.0)
: mOriginalZoomLevel(1.0)
{
// NOTE! nsDocument::operator new() zeroes out all members, so don't
// bother initializing members to 0.

View File

@ -97,9 +97,8 @@ const char* const MediaDocument::sFormatNames[4] =
"" // eWithDimAndFile
};
MediaDocument::MediaDocument(bool aUseXPConnectToWrap)
: nsHTMLDocument(aUseXPConnectToWrap),
mDocumentElementInserted(false)
MediaDocument::MediaDocument()
: mDocumentElementInserted(false)
{
}
MediaDocument::~MediaDocument()

View File

@ -19,7 +19,7 @@ namespace dom {
class MediaDocument : public nsHTMLDocument
{
public:
MediaDocument(bool aUseXPConnectToWrap = false);
MediaDocument();
virtual ~MediaDocument();
virtual nsresult Init();

View File

@ -102,9 +102,7 @@
#include "nsHtml5Parser.h"
#include "nsIDOMJSWindow.h"
#include "nsSandboxFlags.h"
#include "nsIImageDocument.h"
#include "mozilla/dom/HTMLBodyElement.h"
#include "mozilla/dom/HTMLDocumentBinding.h"
#include "nsCharsetSource.h"
#include "nsIStringBundle.h"
#include "nsDOMClassInfo.h"
@ -197,7 +195,7 @@ NS_NewHTMLDocument(nsIDocument** aInstancePtrResult, bool aLoadedAsData)
// NOTE! nsDocument::operator new() zeroes out all members, so don't
// bother initializing members to 0.
nsHTMLDocument::nsHTMLDocument(bool aUseXPConnectToWrap)
nsHTMLDocument::nsHTMLDocument()
: nsDocument("text/html")
{
// NOTE! nsDocument::operator new() zeroes out all members, so don't
@ -206,10 +204,6 @@ nsHTMLDocument::nsHTMLDocument(bool aUseXPConnectToWrap)
mIsRegularHTML = true;
mDefaultElementType = kNameSpaceID_XHTML;
mCompatMode = eCompatibility_NavQuirks;
if (!aUseXPConnectToWrap) {
SetIsDOMBinding();
}
}
@ -257,21 +251,6 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLDocument)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(HTMLDocument)
NS_INTERFACE_MAP_END_INHERITING(nsDocument)
JSObject*
nsHTMLDocument::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
#ifdef DEBUG
// Don't do it yet for image documents
nsCOMPtr<nsIImageDocument> imgDoc = do_QueryObject(this);
MOZ_ASSERT(!imgDoc, "Who called SetIsDOMBinding()?");
#endif
JS::Rooted<JSObject*> obj(aCx, HTMLDocumentBinding::Wrap(aCx, aScope, this));
if (obj && !PostCreateWrapper(aCx, obj)) {
return nullptr;
}
return obj;
}
nsresult
nsHTMLDocument::Init()
@ -1681,13 +1660,14 @@ nsHTMLDocument::Open(JSContext* cx,
SetIsInitialDocument(false);
nsCOMPtr<nsIScriptGlobalObject> newScope(do_QueryReferent(mScopeObject));
JS::RootedObject wrapper(cx, GetWrapper());
if (oldScope && newScope != oldScope && wrapper) {
rv = mozilla::dom::ReparentWrapper(cx, wrapper);
if (oldScope && newScope != oldScope) {
nsIXPConnect *xpc = nsContentUtils::XPConnect();
rv = xpc->ReparentWrappedNativeIfFound(cx, oldScope->GetGlobalJSObject(),
newScope->GetGlobalJSObject(),
static_cast<nsINode*>(this));
if (rv.Failed()) {
return nullptr;
}
nsIXPConnect *xpc = nsContentUtils::XPConnect();
rv = xpc->RescueOrphansInScope(cx, oldScope->GetGlobalJSObject());
if (rv.Failed()) {
return nullptr;
@ -2405,8 +2385,10 @@ static PLDHashOperator
IdentifierMapEntryAddNames(nsIdentifierMapEntry* aEntry, void* aArg)
{
nsTArray<nsString>* aNames = static_cast<nsTArray<nsString>*>(aArg);
Element* idElement;
if (aEntry->HasNameElement() ||
aEntry->HasIdElementExposedAsHTMLDocumentProperty()) {
((idElement = aEntry->GetIdElement()) &&
nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(idElement))) {
aNames->AppendElement(aEntry->GetKey());
}
return PL_DHASH_NEXT;

View File

@ -42,7 +42,7 @@ public:
using nsDocument::SetDocumentURI;
using nsDocument::GetPlugins;
nsHTMLDocument(bool aUseXPConnectToWrap = false);
nsHTMLDocument();
virtual nsresult Init();
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
@ -180,8 +180,6 @@ public:
virtual bool WillIgnoreCharsetOverride();
// WebIDL API
virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
MOZ_OVERRIDE;
void GetDomain(nsAString& aDomain, mozilla::ErrorResult& rv);
void SetDomain(const nsAString& aDomain, mozilla::ErrorResult& rv);
void GetCookie(nsAString& aCookie, mozilla::ErrorResult& rv);

View File

@ -415,6 +415,7 @@ DOMInterfaces = {
'HTMLDocument': {
'nativeType': 'nsHTMLDocument',
'register': False,
'hasXPConnectImpls': True,
'resultNotAddRefed': [ 'body', 'head', 'images', 'embeds', 'plugins',
'links', 'forms', 'scripts', 'anchors', 'applets' ],

View File

@ -995,10 +995,7 @@ def finalizeHook(descriptor, hookName, context):
finalize = "self->%s(%s);" % (hookName, context)
else:
finalize = "JSBindingFinalized<%s>::Finalized(self);\n" % descriptor.nativeType
if descriptor.wrapperCache:
finalize += "ClearWrapper(self, self);\n"
if descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
finalize += "self->mExpandoAndGeneration.expando = JS::UndefinedValue();\n"
finalize += "ClearWrapper(self, self);\n" if descriptor.wrapperCache else ""
if descriptor.workers:
finalize += "self->Release();"
elif descriptor.nativeOwnership == 'nsisupports':
@ -2009,11 +2006,6 @@ def CreateBindingJSObject(descriptor, properties, parent):
return NULL;
}
"""
if descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
create += """ js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO,
JS::PrivateValue(&aObject->mExpandoAndGeneration));
"""
else:
create = """ obj = JS_NewObject(aCx, &Class.mBase, proto, %s);
@ -6242,7 +6234,9 @@ class CGResolveOwnProperty(CGAbstractMethod):
]
CGAbstractMethod.__init__(self, descriptor, "ResolveOwnProperty", "bool", args)
def definition_body(self):
return """ return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc, flags);
return """ // We rely on getOwnPropertyDescriptor not shadowing prototype properties by named
// properties. If that changes we'll need to filter here.
return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc, flags);
"""
class CGEnumerateOwnProperties(CGAbstractMethod):
@ -6253,7 +6247,9 @@ class CGEnumerateOwnProperties(CGAbstractMethod):
Argument('JS::AutoIdVector&', 'props')]
CGAbstractMethod.__init__(self, descriptor, "EnumerateOwnProperties", "bool", args)
def definition_body(self):
return """ return js::GetProxyHandler(obj)->getOwnPropertyNames(cx, wrapper, props);
return """ // We rely on getOwnPropertyNames not shadowing prototype properties by named
// properties. If that changes we'll need to filter here.
return js::GetProxyHandler(obj)->getOwnPropertyNames(cx, wrapper, props);
"""
class CGPrototypeTraitsClass(CGClass):
@ -6588,10 +6584,10 @@ MOZ_ASSERT_IF(desc->obj, desc->obj == ${holder});"""
fillDescriptor = "FillPropertyDescriptor(desc, proxy, %s);\nreturn true;" % readonly
templateValues = {'jsvalRef': 'desc->value', 'jsvalPtr': '&desc->value',
'obj': 'proxy', 'successCode': fillDescriptor}
condition = "!HasPropertyOnPrototype(cx, proxy, this, id)"
if self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
condition = "(!isXray || %s)" % condition
condition = "!(flags & JSRESOLVE_ASSIGNING) && " + condition
# Once we start supporting OverrideBuiltins we need to make
# ResolveOwnProperty or EnumerateOwnProperties filter out named
# properties that shadow prototype properties.
condition = "!(flags & JSRESOLVE_ASSIGNING) && !HasPropertyOnPrototype(cx, proxy, this, id)"
if self.descriptor.supportsIndexedProperties():
condition = "!IsArrayIndex(index) && " + condition
namedGet = ("\n" +
@ -6749,16 +6745,14 @@ class CGDOMJSProxyHandler_delete(ClassMethod):
# We always return above for an index id in the case when we support
# indexed properties, so we can just treat the id as a name
# unconditionally here.
delete += (CGGeneric(namedBody).define() + "\n"
"if (found) {\n"
" return true;\n"
delete += ("if (!HasPropertyOnPrototype(cx, proxy, this, id)) {\n" +
CGIndenter(CGGeneric(namedBody)).define() + "\n"
" if (found) {\n"
" return true;\n"
" }\n"
"}\n")
if not self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
delete = CGIfWrapper(CGGeneric(delete),
"!HasPropertyOnPrototype(cx, proxy, this, id)").define()
delete += """
return dom::DOMProxyHandler::delete_(cx, proxy, id, bp);"""
delete += "return dom::DOMProxyHandler::delete_(cx, proxy, id, bp);";
return delete
@ -6785,17 +6779,13 @@ for (int32_t i = 0; i < int32_t(length); ++i) {
addIndices = ""
if self.descriptor.supportsNamedProperties():
if self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
shadow = "!isXray"
else:
shadow = "false"
addNames = """
nsTArray<nsString> names;
UnwrapProxy(proxy)->GetSupportedNames(names);
if (!AppendNamedPropertyIds(cx, proxy, names, %s, props)) {
if (!AppendNamedPropertyIds(cx, proxy, names, props)) {
return false;
}
""" % shadow
"""
else:
addNames = ""
@ -6852,15 +6842,14 @@ class CGDOMJSProxyHandler_hasOwn(ClassMethod):
if self.descriptor.supportsNamedProperties():
# If we support indexed properties we always return above for index
# property names, so no need to check for those here.
named = (CGProxyNamedPresenceChecker(self.descriptor).define() + "\n" +
"*bp = found;\n")
if not self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
named = CGIfWrapper(CGGeneric(named + "return true;\n"),
"!HasPropertyOnPrototype(cx, proxy, this, id)").define()
named += ("\n"
"*bp = false;")
named = ("if (!HasPropertyOnPrototype(cx, proxy, this, id)) {\n" +
CGIndenter(CGProxyNamedPresenceChecker(self.descriptor)).define() + "\n" +
" *bp = found;\n"
" return true;\n"
"}\n" +
"\n")
else:
named = "*bp = false;"
named = ""
return """MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
"Should not have a XrayWrapper here");
@ -6876,7 +6865,7 @@ if (expando) {
}
}
""" + named + """
""" + named + """*bp = false;
return true;"""
class CGDOMJSProxyHandler_get(ClassMethod):
@ -6926,39 +6915,35 @@ if (expando) {
} else {
%s
}
""" % (stripTrailingWhitespace(getUnforgeableOrExpando.replace('\n', '\n ')))
else:
getIndexedOrExpando = getUnforgeableOrExpando + "\n\n"
getIndexedOrExpando = getUnforgeableOrExpando + "\n"
if self.descriptor.supportsNamedProperties():
getNamed = CGProxyNamedGetter(self.descriptor, templateValues)
if self.descriptor.supportsIndexedProperties():
getNamed = CGIfWrapper(getNamed, "!IsArrayIndex(index)")
getNamed = getNamed.define() + "\n\n"
getNamed = getNamed.define() + "\n"
else:
getNamed = ""
getOnPrototype = """bool foundOnPrototype;
if (!GetPropertyOnPrototype(cx, proxy, id, &foundOnPrototype, vp.address())) {
return false;
}
if (foundOnPrototype) {
return true;
}
"""
if self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
getNamed = getNamed + getOnPrototype
else:
getNamed = getOnPrototype + getNamed
return """MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
"Should not have a XrayWrapper here");
""" + getIndexedOrExpando + getNamed + """vp.setUndefined();
return true;"""
%s
{ // Scope for this "found" so it doesn't leak to things below
bool found;
if (!GetPropertyOnPrototype(cx, proxy, id, &found, vp.address())) {
return false;
}
if (found) {
return true;
}
}
%s
vp.setUndefined();
return true;""" % (getIndexedOrExpando, getNamed)
class CGDOMJSProxyHandler_className(ClassMethod):
def __init__(self, descriptor):

View File

@ -37,35 +37,11 @@ DefineStaticJSVals(JSContext* cx)
int HandlerFamily;
js::ListBaseShadowsResult
DOMListShadows(JSContext* cx, JSHandleObject proxy, JSHandleId id)
{
JS::Value v = js::GetProxyExtra(proxy, JSPROXYSLOT_EXPANDO);
if (v.isObject()) {
JSBool hasOwn;
if (!JS_AlreadyHasOwnPropertyById(cx, &v.toObject(), id, &hasOwn))
return js::ShadowCheckFailed;
return hasOwn ? js::Shadows : js::DoesntShadow;
}
if (v.isUndefined()) {
return js::DoesntShadow;
}
bool hasOwn;
if (!GetProxyHandler(proxy)->hasOwn(cx, proxy, id, &hasOwn))
return js::ShadowCheckFailed;
return hasOwn ? js::Shadows : js::DoesntShadowUnique;
}
// Store the information for the specialized ICs.
struct SetListBaseInformation
{
SetListBaseInformation() {
js::SetListBaseInformation((void*) &HandlerFamily,
js::JSSLOT_PROXY_EXTRA + JSPROXYSLOT_EXPANDO, DOMListShadows);
js::SetListBaseInformation((void*) &HandlerFamily, js::JSSLOT_PROXY_EXTRA + JSPROXYSLOT_EXPANDO);
}
};
@ -75,27 +51,11 @@ SetListBaseInformation gSetListBaseInformation;
JSObject*
DOMProxyHandler::GetAndClearExpandoObject(JSObject* obj)
{
MOZ_ASSERT(IsDOMProxy(obj), "expected a DOM proxy object");
JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
if (v.isUndefined()) {
return nullptr;
}
if (v.isObject()) {
js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, UndefinedValue());
} else {
js::ExpandoAndGeneration* expandoAndGeneration =
static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
v = expandoAndGeneration->expando;
if (v.isUndefined()) {
return nullptr;
}
expandoAndGeneration->expando = UndefinedValue();
}
xpc::GetObjectScope(obj)->RemoveDOMExpandoObject(obj);
return &v.toObject();
JSObject* expando = GetExpandoObject(obj);
XPCWrappedNativeScope* scope = xpc::GetObjectScope(obj);
scope->RemoveDOMExpandoObject(obj);
js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, UndefinedValue());
return expando;
}
// static
@ -103,42 +63,25 @@ JSObject*
DOMProxyHandler::EnsureExpandoObject(JSContext* cx, JS::Handle<JSObject*> obj)
{
NS_ASSERTION(IsDOMProxy(obj), "expected a DOM proxy object");
JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
if (v.isObject()) {
return &v.toObject();
}
js::ExpandoAndGeneration* expandoAndGeneration;
if (!v.isUndefined()) {
expandoAndGeneration = static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
if (expandoAndGeneration->expando.isObject()) {
return &expandoAndGeneration->expando.toObject();
}
} else {
expandoAndGeneration = nullptr;
}
JSObject* expando = JS_NewObjectWithGivenProto(cx, nullptr, nullptr,
js::GetObjectParent(obj));
JS::Rooted<JSObject*> expando(cx, GetExpandoObject(obj));
if (!expando) {
return nullptr;
}
expando = JS_NewObjectWithGivenProto(cx, nullptr, nullptr,
js::GetObjectParent(obj));
if (!expando) {
return NULL;
}
XPCWrappedNativeScope* scope = xpc::GetObjectScope(obj);
if (!scope->RegisterDOMExpandoObject(obj)) {
return nullptr;
}
XPCWrappedNativeScope* scope = xpc::GetObjectScope(obj);
if (!scope->RegisterDOMExpandoObject(obj)) {
return NULL;
}
nsWrapperCache* cache;
CallQueryInterface(UnwrapDOMObject<nsISupports>(obj), &cache);
cache->SetPreservingWrapper(true);
nsWrapperCache* cache;
CallQueryInterface(UnwrapDOMObject<nsISupports>(obj), &cache);
cache->SetPreservingWrapper(true);
if (expandoAndGeneration) {
expandoAndGeneration->expando.setObject(*expando);
} else {
js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, ObjectValue(*expando));
}
return expando;
}
@ -267,7 +210,6 @@ bool
DOMProxyHandler::AppendNamedPropertyIds(JSContext* cx,
JS::Handle<JSObject*> proxy,
nsTArray<nsString>& names,
bool shadowPrototypeProperties,
JS::AutoIdVector& props)
{
for (uint32_t i = 0; i < names.Length(); ++i) {
@ -281,8 +223,7 @@ DOMProxyHandler::AppendNamedPropertyIds(JSContext* cx,
return false;
}
if (shadowPrototypeProperties ||
!HasPropertyOnPrototype(cx, proxy, this, id)) {
if (!HasPropertyOnPrototype(cx, proxy, this, id)) {
if (!props.append(id)) {
return false;
}

View File

@ -51,18 +51,7 @@ public:
{
MOZ_ASSERT(IsDOMProxy(obj), "expected a DOM proxy object");
JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
if (v.isObject()) {
return &v.toObject();
}
if (v.isUndefined()) {
return nullptr;
}
js::ExpandoAndGeneration* expandoAndGeneration =
static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
v = expandoAndGeneration->expando;
return v.isUndefined() ? nullptr : &v.toObject();
return v.isUndefined() ? NULL : v.toObjectOrNull();
}
static JSObject* GetAndClearExpandoObject(JSObject* obj);
static JSObject* EnsureExpandoObject(JSContext* cx,
@ -71,12 +60,10 @@ public:
const DOMClass& mClass;
protected:
// Append the property names in "names" to "props". If
// shadowPrototypeProperties is false then skip properties that are also
// present on our proto chain.
// Append the property names in "names" that don't live on our proto
// chain to "props"
bool AppendNamedPropertyIds(JSContext* cx, JS::Handle<JSObject*> proxy,
nsTArray<nsString>& names,
bool shadowPrototypeProperties,
JS::AutoIdVector& props);
};

View File

@ -903,8 +903,7 @@ class IDLInterface(IDLObjectWithScope):
identifier == "NeedNewResolve" or
identifier == "JSImplementation" or
identifier == "HeaderFile" or
identifier == "NavigatorProperty" or
identifier == "OverrideBuiltins"):
identifier == "NavigatorProperty"):
# Known attributes that we don't need to do anything with here
pass
else:

View File

@ -6,7 +6,6 @@
interface Selection;
[OverrideBuiltins]
interface HTMLDocument : Document {
[Throws]
attribute DOMString? domain;

View File

@ -301,13 +301,8 @@ ICStub::trace(JSTracer *trc)
MarkShape(trc, &propStub->holderShape(), "baseline-getpropnativeproto-stub-holdershape");
break;
}
case ICStub::GetProp_CallListBaseNative:
case ICStub::GetProp_CallListBaseWithGenerationNative: {
ICGetPropCallListBaseNativeStub *propStub;
if (kind() == ICStub::GetProp_CallListBaseNative)
propStub = toGetProp_CallListBaseNative();
else
propStub = toGetProp_CallListBaseWithGenerationNative();
case ICStub::GetProp_CallListBaseNative: {
ICGetProp_CallListBaseNative *propStub = toGetProp_CallListBaseNative();
MarkShape(trc, &propStub->shape(), "baseline-getproplistbasenative-stub-shape");
if (propStub->expandoShape()) {
MarkShape(trc, &propStub->expandoShape(),
@ -612,7 +607,6 @@ ICStubCompiler::guardProfilingEnabled(MacroAssembler &masm, Register scratch, La
JS_ASSERT(kind == ICStub::Call_Scripted || kind == ICStub::Call_AnyScripted ||
kind == ICStub::Call_Native || kind == ICStub::GetProp_CallScripted ||
kind == ICStub::GetProp_CallNative || kind == ICStub::GetProp_CallListBaseNative ||
kind == ICStub::GetProp_CallListBaseWithGenerationNative ||
kind == ICStub::SetProp_CallScripted || kind == ICStub::SetProp_CallNative);
// Guard on bit in frame that indicates if the SPS frame was pushed in the first
@ -3042,8 +3036,6 @@ static void
GenerateListBaseChecks(JSContext *cx, MacroAssembler &masm, Register object,
Address checkProxyHandlerAddr,
Address checkExpandoShapeAddr,
Address *expandoAndGenerationAddr,
Address *generationAddr,
Register scratch,
GeneralRegisterSet &listBaseRegSet,
Label *checkFailed)
@ -3067,22 +3059,7 @@ GenerateListBaseChecks(JSContext *cx, MacroAssembler &masm, Register object,
Label failListBaseCheck;
Label listBaseOk;
if (expandoAndGenerationAddr) {
JS_ASSERT(generationAddr);
masm.loadPtr(*expandoAndGenerationAddr, tempVal.scratchReg());
masm.branchPrivatePtr(Assembler::NotEqual, expandoAddr, tempVal.scratchReg(),
&failListBaseCheck);
masm.load32(*generationAddr, scratch);
masm.branch32(Assembler::NotEqual,
Address(tempVal.scratchReg(), offsetof(ExpandoAndGeneration, expando)),
scratch, &failListBaseCheck);
masm.loadValue(Address(tempVal.scratchReg(), 0), tempVal);
} else {
masm.loadValue(expandoAddr, tempVal);
}
masm.loadValue(expandoAddr, tempVal);
// If the incoming object does not have an expando object then we're sure we're not
// shadowing.
@ -3116,7 +3093,7 @@ GenerateListBaseChecks(JSContext *cx, MacroAssembler &masm, Register object,
static bool
EffectlesslyLookupProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,
MutableHandleObject holder, MutableHandleShape shape,
bool *checkListBase=NULL, bool *listBaseHasGeneration=NULL)
bool *checkListBase=NULL)
{
shape.set(NULL);
holder.set(NULL);
@ -3128,21 +3105,19 @@ EffectlesslyLookupProperty(JSContext *cx, HandleObject obj, HandlePropertyName n
// Check for list base if asked to.
RootedObject checkObj(cx, obj);
if (checkListBase && IsCacheableListBase(obj)) {
JS_ASSERT(listBaseHasGeneration);
*checkListBase = isListBase = true;
if (obj->hasUncacheableProto())
return true;
RootedId id(cx, NameToId(name));
ListBaseShadowsResult shadows =
GetListBaseShadowsCheck()(cx, obj, id);
if (shadows == ShadowCheckFailed)
return false;
if (shadows == Shadows)
return true;
// Expando objects just hold any extra properties the object has been given by a script,
// and have no prototype or anything else that will complicate property lookups on them.
Value expandoVal = obj->getFixedSlot(GetListBaseExpandoSlot());
*listBaseHasGeneration = (shadows == DoesntShadowUnique);
JS_ASSERT_IF(expandoVal.isObject(),
expandoVal.toObject().isNative() && !expandoVal.toObject().getProto());
if (expandoVal.isObject() && expandoVal.toObject().nativeContains(cx, name))
return true;
checkObj = GetListBaseProto(obj);
}
@ -5111,32 +5086,6 @@ TryAttachLengthStub(JSContext *cx, HandleScript script, ICGetProp_Fallback *stub
return true;
}
static bool
UpdateExistingGenerationalListBaseStub(ICGetProp_Fallback *stub,
HandleObject obj)
{
Value expandoSlot = obj->getFixedSlot(GetListBaseExpandoSlot());
JS_ASSERT(!expandoSlot.isObject() && !expandoSlot.isUndefined());
ExpandoAndGeneration *expandoAndGeneration = (ExpandoAndGeneration*)expandoSlot.toPrivate();
for (ICStubConstIterator iter = stub->beginChainConst(); !iter.atEnd(); iter++) {
if (iter->isGetProp_CallListBaseWithGenerationNative()) {
ICGetProp_CallListBaseWithGenerationNative* updateStub =
iter->toGetProp_CallListBaseWithGenerationNative();
if (updateStub->expandoAndGeneration() == expandoAndGeneration) {
// Update generation
uint32_t generation = expandoAndGeneration->generation;
IonSpew(IonSpew_BaselineIC,
" Updating existing stub with generation, old value: %i, "
"new value: %i", updateStub->generation(),
generation);
updateStub->setGeneration(generation);
return true;
}
}
}
return false;
}
static bool
TryAttachNativeGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc,
ICGetProp_Fallback *stub, HandlePropertyName name,
@ -5150,11 +5099,9 @@ TryAttachNativeGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc,
RootedObject obj(cx, &val.toObject());
bool isListBase;
bool listBaseHasGeneration;
RootedShape shape(cx);
RootedObject holder(cx);
if (!EffectlesslyLookupProperty(cx, obj, name, &holder, &shape, &isListBase,
&listBaseHasGeneration))
if (!EffectlesslyLookupProperty(cx, obj, name, &holder, &shape, &isListBase))
return false;
if (!isListBase && !obj->isNative())
@ -5211,27 +5158,19 @@ TryAttachNativeGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc,
JS_ASSERT(obj != holder);
JS_ASSERT(callee->isNative());
IonSpew(IonSpew_BaselineIC, " Generating GetProp(%s%s/NativeGetter %p) stub",
isListBase ? "ListBaseObj" : "NativeObj",
isListBase && listBaseHasGeneration ? "WithGeneration" : "",
callee->native());
ICStub *newStub = NULL;
if (isListBase) {
ICStub::Kind kind;
if (listBaseHasGeneration) {
if (UpdateExistingGenerationalListBaseStub(stub, obj)) {
*attached = true;
return true;
}
kind = ICStub::GetProp_CallListBaseWithGenerationNative;
} else {
kind = ICStub::GetProp_CallListBaseNative;
}
ICGetPropCallListBaseNativeCompiler compiler(cx, kind, monitorStub, obj, holder, callee,
IonSpew(IonSpew_BaselineIC, " Generating GetProp(ListBaseObj/NativeGetter %p) stub",
callee->native());
ICGetProp_CallListBaseNative::Compiler compiler(cx, monitorStub, obj, holder, callee,
pc - script->code);
newStub = compiler.getStub(compiler.getStubSpace(script));
} else {
IonSpew(IonSpew_BaselineIC, " Generating GetProp(NativeObj/NativeGetter %p) stub",
callee->native());
ICGetProp_CallNative::Compiler compiler(cx, monitorStub, obj, holder, callee,
pc - script->code);
newStub = compiler.getStub(compiler.getStubSpace(script));
@ -5750,9 +5689,7 @@ ICGetProp_CallNative::Compiler::generateStubCode(MacroAssembler &masm)
}
bool
ICGetPropCallListBaseNativeCompiler::generateStubCode(MacroAssembler &masm,
Address* expandoAndGenerationAddr,
Address* generationAddr)
ICGetProp_CallListBaseNative::Compiler::generateStubCode(MacroAssembler &masm)
{
Label failure;
GeneralRegisterSet regs(availableGeneralRegs(1));
@ -5785,7 +5722,6 @@ ICGetPropCallListBaseNativeCompiler::generateStubCode(MacroAssembler &masm,
cx, masm, objReg,
Address(BaselineStubReg, ICGetProp_CallListBaseNative::offsetOfProxyHandler()),
Address(BaselineStubReg, ICGetProp_CallListBaseNative::offsetOfExpandoShape()),
expandoAndGenerationAddr, generationAddr,
scratch,
listBaseRegSet,
&failure);
@ -5844,54 +5780,6 @@ ICGetPropCallListBaseNativeCompiler::generateStubCode(MacroAssembler &masm,
return true;
}
bool
ICGetPropCallListBaseNativeCompiler::generateStubCode(MacroAssembler &masm)
{
if (kind == ICStub::GetProp_CallListBaseNative)
return generateStubCode(masm, NULL, NULL);
Address internalStructAddress(BaselineStubReg,
ICGetProp_CallListBaseWithGenerationNative::offsetOfInternalStruct());
Address generationAddress(BaselineStubReg,
ICGetProp_CallListBaseWithGenerationNative::offsetOfGeneration());
return generateStubCode(masm, &internalStructAddress, &generationAddress);
}
ICStub*
ICGetPropCallListBaseNativeCompiler::getStub(ICStubSpace *space)
{
RootedShape shape(cx, obj_->lastProperty());
RootedShape holderShape(cx, holder_->lastProperty());
Value expandoSlot = obj_->getFixedSlot(GetListBaseExpandoSlot());
RootedShape expandoShape(cx, NULL);
ExpandoAndGeneration *expandoAndGeneration;
int32_t generation;
Value expandoVal;
if (kind == ICStub::GetProp_CallListBaseNative) {
expandoVal = expandoSlot;
} else {
JS_ASSERT(kind == ICStub::GetProp_CallListBaseWithGenerationNative);
JS_ASSERT(!expandoSlot.isObject() && !expandoSlot.isUndefined());
expandoAndGeneration = (ExpandoAndGeneration*)expandoSlot.toPrivate();
expandoVal = expandoAndGeneration->expando;
generation = expandoAndGeneration->generation;
}
if (expandoVal.isObject())
expandoShape = expandoVal.toObject().lastProperty();
if (kind == ICStub::GetProp_CallListBaseNative) {
return ICGetProp_CallListBaseNative::New(
space, getStubCode(), firstMonitorStub_, shape, GetProxyHandler(obj_),
expandoShape, holder_, holderShape, getter_, pcOffset_);
}
return ICGetProp_CallListBaseWithGenerationNative::New(
space, getStubCode(), firstMonitorStub_, shape, GetProxyHandler(obj_),
expandoAndGeneration, generation, expandoShape, holder_, holderShape, getter_,
pcOffset_);
}
bool
ICGetProp_ArgumentsLength::Compiler::generateStubCode(MacroAssembler &masm)
{
@ -7877,16 +7765,12 @@ ICCall_Native::ICCall_Native(IonCode *stubCode, ICStub *firstMonitorStub, Handle
pcOffset_(pcOffset)
{ }
ICGetPropCallListBaseNativeStub::ICGetPropCallListBaseNativeStub(Kind kind, IonCode *stubCode,
ICStub *firstMonitorStub,
HandleShape shape,
BaseProxyHandler *proxyHandler,
HandleShape expandoShape,
HandleObject holder,
HandleShape holderShape,
HandleFunction getter,
uint32_t pcOffset)
: ICMonitoredStub(kind, stubCode, firstMonitorStub),
ICGetProp_CallListBaseNative::ICGetProp_CallListBaseNative(IonCode *stubCode, ICStub *firstMonitorStub,
HandleShape shape, BaseProxyHandler *proxyHandler,
HandleShape expandoShape, HandleObject holder,
HandleShape holderShape, HandleFunction getter,
uint32_t pcOffset)
: ICMonitoredStub(GetProp_CallListBaseNative, stubCode, firstMonitorStub),
shape_(shape),
proxyHandler_(proxyHandler),
expandoShape_(expandoShape),
@ -7896,22 +7780,16 @@ ICGetPropCallListBaseNativeStub::ICGetPropCallListBaseNativeStub(Kind kind, IonC
pcOffset_(pcOffset)
{ }
ICGetPropCallListBaseNativeCompiler::ICGetPropCallListBaseNativeCompiler(JSContext *cx,
ICStub::Kind kind,
ICStub *firstMonitorStub,
HandleObject obj,
HandleObject holder,
HandleFunction getter,
uint32_t pcOffset)
: ICStubCompiler(cx, kind),
ICGetProp_CallListBaseNative::Compiler::Compiler(JSContext *cx, ICStub *firstMonitorStub, HandleObject obj,
HandleObject holder, HandleFunction getter,
uint32_t pcOffset)
: ICStubCompiler(cx, ICStub::GetProp_CallListBaseNative),
firstMonitorStub_(firstMonitorStub),
obj_(cx, obj),
holder_(cx, holder),
getter_(cx, getter),
pcOffset_(pcOffset)
{
JS_ASSERT(kind == ICStub::GetProp_CallListBaseNative ||
kind == ICStub::GetProp_CallListBaseWithGenerationNative);
JS_ASSERT(obj_->isProxy());
JS_ASSERT(GetProxyHandler(obj_)->family() == GetListBaseHandlerFamily());
}

View File

@ -365,7 +365,6 @@ class ICEntry
_(GetProp_CallScripted) \
_(GetProp_CallNative) \
_(GetProp_CallListBaseNative)\
_(GetProp_CallListBaseWithGenerationNative)\
_(GetProp_ArgumentsLength) \
\
_(SetProp_Fallback) \
@ -729,7 +728,6 @@ class ICStub
case GetProp_CallScripted:
case GetProp_CallNative:
case GetProp_CallListBaseNative:
case GetProp_CallListBaseWithGenerationNative:
case SetProp_CallScripted:
case SetProp_CallNative:
return true;
@ -4165,7 +4163,7 @@ class ICGetProp_CallNative : public ICGetPropCallGetter
};
};
class ICGetPropCallListBaseNativeStub : public ICMonitoredStub
class ICGetProp_CallListBaseNative : public ICMonitoredStub
{
friend class ICStubSpace;
protected:
@ -4188,13 +4186,26 @@ class ICGetPropCallListBaseNativeStub : public ICMonitoredStub
// PC offset of call
uint32_t pcOffset_;
ICGetPropCallListBaseNativeStub(ICStub::Kind kind, IonCode *stubCode,
ICStub *firstMonitorStub, HandleShape shape,
BaseProxyHandler *proxyHandler, HandleShape expandoShape,
HandleObject holder, HandleShape holderShape,
HandleFunction getter, uint32_t pcOffset);
ICGetProp_CallListBaseNative(IonCode *stubCode, ICStub *firstMonitorStub,
HandleShape shape, BaseProxyHandler *proxyHandler,
HandleShape expandoShape, HandleObject holder,
HandleShape holderShape, HandleFunction getter,
uint32_t pcOffset);
public:
static inline ICGetProp_CallListBaseNative *New(
ICStubSpace *space, IonCode *code, ICStub *firstMonitorStub,
HandleShape shape, BaseProxyHandler *proxyHandler,
HandleShape expandoShape, HandleObject holder, HandleShape holderShape,
HandleFunction getter, uint32_t pcOffset)
{
if (!code)
return NULL;
return space->allocate<ICGetProp_CallListBaseNative>(code, firstMonitorStub, shape,
proxyHandler, expandoShape, holder,
holderShape, getter, pcOffset);
}
HeapPtrShape &shape() {
return shape_;
}
@ -4215,128 +4226,55 @@ class ICGetPropCallListBaseNativeStub : public ICMonitoredStub
}
static size_t offsetOfShape() {
return offsetof(ICGetPropCallListBaseNativeStub, shape_);
return offsetof(ICGetProp_CallListBaseNative, shape_);
}
static size_t offsetOfProxyHandler() {
return offsetof(ICGetPropCallListBaseNativeStub, proxyHandler_);
return offsetof(ICGetProp_CallListBaseNative, proxyHandler_);
}
static size_t offsetOfExpandoShape() {
return offsetof(ICGetPropCallListBaseNativeStub, expandoShape_);
return offsetof(ICGetProp_CallListBaseNative, expandoShape_);
}
static size_t offsetOfHolder() {
return offsetof(ICGetPropCallListBaseNativeStub, holder_);
return offsetof(ICGetProp_CallListBaseNative, holder_);
}
static size_t offsetOfHolderShape() {
return offsetof(ICGetPropCallListBaseNativeStub, holderShape_);
return offsetof(ICGetProp_CallListBaseNative, holderShape_);
}
static size_t offsetOfGetter() {
return offsetof(ICGetPropCallListBaseNativeStub, getter_);
return offsetof(ICGetProp_CallListBaseNative, getter_);
}
static size_t offsetOfPCOffset() {
return offsetof(ICGetPropCallListBaseNativeStub, pcOffset_);
}
};
class ICGetProp_CallListBaseNative : public ICGetPropCallListBaseNativeStub
{
friend class ICStubSpace;
ICGetProp_CallListBaseNative(IonCode *stubCode, ICStub *firstMonitorStub, HandleShape shape,
BaseProxyHandler *proxyHandler, HandleShape expandoShape,
HandleObject holder, HandleShape holderShape,
HandleFunction getter, uint32_t pcOffset)
: ICGetPropCallListBaseNativeStub(ICStub::GetProp_CallListBaseNative, stubCode,
firstMonitorStub, shape, proxyHandler, expandoShape,
holder, holderShape, getter, pcOffset)
{}
public:
static inline ICGetProp_CallListBaseNative *New(
ICStubSpace *space, IonCode *code, ICStub *firstMonitorStub,
HandleShape shape, BaseProxyHandler *proxyHandler,
HandleShape expandoShape, HandleObject holder, HandleShape holderShape,
HandleFunction getter, uint32_t pcOffset)
{
if (!code)
return NULL;
return space->allocate<ICGetProp_CallListBaseNative>(code, firstMonitorStub, shape,
proxyHandler, expandoShape, holder,
holderShape, getter, pcOffset);
}
};
class ICGetProp_CallListBaseWithGenerationNative : public ICGetPropCallListBaseNativeStub
{
protected:
ExpandoAndGeneration *expandoAndGeneration_;
uint32_t generation_;
public:
ICGetProp_CallListBaseWithGenerationNative(IonCode *stubCode, ICStub *firstMonitorStub,
HandleShape shape, BaseProxyHandler *proxyHandler,
ExpandoAndGeneration *expandoAndGeneration,
uint32_t generation, HandleShape expandoShape,
HandleObject holder, HandleShape holderShape,
HandleFunction getter, uint32_t pcOffset)
: ICGetPropCallListBaseNativeStub(ICStub::GetProp_CallListBaseWithGenerationNative,
stubCode, firstMonitorStub, shape, proxyHandler,
expandoShape, holder, holderShape, getter, pcOffset),
expandoAndGeneration_(expandoAndGeneration),
generation_(generation)
{
return offsetof(ICGetProp_CallListBaseNative, pcOffset_);
}
static inline ICGetProp_CallListBaseWithGenerationNative *New(
ICStubSpace *space, IonCode *code, ICStub *firstMonitorStub,
HandleShape shape, BaseProxyHandler *proxyHandler,
ExpandoAndGeneration *expandoAndGeneration, uint32_t generation,
HandleShape expandoShape, HandleObject holder, HandleShape holderShape,
HandleFunction getter, uint32_t pcOffset)
{
if (!code)
return NULL;
return space->allocate<ICGetProp_CallListBaseWithGenerationNative>(code, firstMonitorStub,
shape, proxyHandler, expandoAndGeneration,
generation, expandoShape, holder, holderShape,
getter, pcOffset);
}
class Compiler : public ICStubCompiler {
protected:
ICStub *firstMonitorStub_;
RootedObject obj_;
RootedObject holder_;
RootedFunction getter_;
uint32_t pcOffset_;
void *expandoAndGeneration() const {
return expandoAndGeneration_;
}
uint32_t generation() const {
return generation_;
}
bool generateStubCode(MacroAssembler &masm);
void setGeneration(uint32_t value) {
generation_ = value;
}
public:
Compiler(JSContext *cx, ICStub *firstMonitorStub, HandleObject obj,
HandleObject holder, HandleFunction getter, uint32_t pcOffset);
static size_t offsetOfInternalStruct() {
return offsetof(ICGetProp_CallListBaseWithGenerationNative, expandoAndGeneration_);
}
static size_t offsetOfGeneration() {
return offsetof(ICGetProp_CallListBaseWithGenerationNative, generation_);
}
};
ICStub *getStub(ICStubSpace *space) {
RootedShape shape(cx, obj_->lastProperty());
RootedShape holderShape(cx, holder_->lastProperty());
class ICGetPropCallListBaseNativeCompiler : public ICStubCompiler {
ICStub *firstMonitorStub_;
RootedObject obj_;
RootedObject holder_;
RootedFunction getter_;
uint32_t pcOffset_;
Value expandoVal = obj_->getFixedSlot(GetListBaseExpandoSlot());
RootedShape expandoShape(cx, NULL);
if (expandoVal.isObject())
expandoShape = expandoVal.toObject().lastProperty();
bool generateStubCode(MacroAssembler &masm, Address* internalStructAddr,
Address* generationAddr);
bool generateStubCode(MacroAssembler &masm);
public:
ICGetPropCallListBaseNativeCompiler(JSContext *cx, ICStub::Kind kind,
ICStub *firstMonitorStub, HandleObject obj,
HandleObject holder, HandleFunction getter,
uint32_t pcOffset);
ICStub *getStub(ICStubSpace *space);
return ICGetProp_CallListBaseNative::New(
space, getStubCode(), firstMonitorStub_, shape, GetProxyHandler(obj_),
expandoShape, holder_, holderShape, getter_, pcOffset_);
}
};
};
class ICGetProp_ArgumentsLength : public ICStub

View File

@ -634,7 +634,7 @@ GenerateListBaseChecks(JSContext *cx, MacroAssembler &masm, JSObject *obj,
// 2. The object does not have expando properties, or has an expando
// which is known to not have the desired property.
Address handlerAddr(object, JSObject::getFixedSlotOffset(JSSLOT_PROXY_HANDLER));
Address expandoSlotAddr(object, JSObject::getFixedSlotOffset(GetListBaseExpandoSlot()));
Address expandoAddr(object, JSObject::getFixedSlotOffset(GetListBaseExpandoSlot()));
// Check that object is a ListBase.
masm.branchPrivatePtr(Assembler::NotEqual, handlerAddr, ImmWord(GetProxyHandler(obj)), stubFailure);
@ -649,27 +649,13 @@ GenerateListBaseChecks(JSContext *cx, MacroAssembler &masm, JSObject *obj,
Label failListBaseCheck;
Label listBaseOk;
Value expandoVal = obj->getFixedSlot(GetListBaseExpandoSlot());
masm.loadValue(expandoSlotAddr, tempVal);
if (!expandoVal.isObject() && !expandoVal.isUndefined()) {
masm.branchTestValue(Assembler::NotEqual, tempVal, expandoVal, &failListBaseCheck);
ExpandoAndGeneration *expandoAndGeneration = (ExpandoAndGeneration*)expandoVal.toPrivate();
masm.movePtr(ImmWord(expandoAndGeneration), tempVal.scratchReg());
masm.branch32(Assembler::NotEqual, Address(tempVal.scratchReg(), sizeof(Value)),
Imm32(expandoAndGeneration->generation),
&failListBaseCheck);
expandoVal = expandoAndGeneration->expando;
masm.loadValue(Address(tempVal.scratchReg(), 0), tempVal);
}
masm.loadValue(expandoAddr, tempVal);
// If the incoming object does not have an expando object then we're sure we're not
// shadowing.
masm.branchTestUndefined(Assembler::Equal, tempVal, &listBaseOk);
Value expandoVal = obj->getFixedSlot(GetListBaseExpandoSlot());
if (expandoVal.isObject()) {
JS_ASSERT(!expandoVal.toObject().nativeContains(cx, name));
@ -1258,20 +1244,16 @@ TryAttachNativeGetPropStub(JSContext *cx, IonScript *ion,
RootedObject checkObj(cx, obj);
if (IsCacheableListBase(obj)) {
RootedId id(cx, NameToId(name));
ListBaseShadowsResult shadows =
GetListBaseShadowsCheck()(cx, obj, id);
if (shadows == ShadowCheckFailed)
return false;
if (shadows == Shadows)
Value expandoVal = obj->getFixedSlot(GetListBaseExpandoSlot());
// Expando objects just hold any extra properties the object has been given by a script,
// and have no prototype or anything else that will complicate property lookups on them.
JS_ASSERT_IF(expandoVal.isObject(),
expandoVal.toObject().isNative() && !expandoVal.toObject().getProto());
if (expandoVal.isObject() && expandoVal.toObject().nativeContains(cx, name))
return true;
if (shadows == DoesntShadowUnique)
// We reset the cache to clear out an existing IC for this object
// (if there is one). The generation is a constant in the generated
// code and we will not have the same generation again for this
// object, so the generation check in the existing IC would always
// fail anyway.
cache.reset();
checkObj = obj->getTaggedProto().toObjectOrNull();
}

View File

@ -1004,15 +1004,12 @@ js::GetDOMCallbacks(JSRuntime *rt)
static void *gListBaseHandlerFamily = NULL;
static uint32_t gListBaseExpandoSlot = 0;
static ListBaseShadowsCheck gListBaseShadowsCheck;
JS_FRIEND_API(void)
js::SetListBaseInformation(void *listBaseHandlerFamily, uint32_t listBaseExpandoSlot,
ListBaseShadowsCheck listBaseShadowsCheck)
js::SetListBaseInformation(void *listBaseHandlerFamily, uint32_t listBaseExpandoSlot)
{
gListBaseHandlerFamily = listBaseHandlerFamily;
gListBaseExpandoSlot = listBaseExpandoSlot;
gListBaseShadowsCheck = listBaseShadowsCheck;
}
void *
@ -1027,12 +1024,6 @@ js::GetListBaseExpandoSlot()
return gListBaseExpandoSlot;
}
ListBaseShadowsCheck
js::GetListBaseShadowsCheck()
{
return gListBaseShadowsCheck;
}
JS_FRIEND_API(void)
js::SetCTypesActivityCallback(JSRuntime *rt, CTypesActivityCallback cb)
{

View File

@ -855,46 +855,11 @@ NukeCrossCompartmentWrappers(JSContext* cx,
NukeReferencesToWindow nukeReferencesToWindow);
/* Specify information about ListBase proxies in the DOM, for use by ICs. */
/*
* The ListBaseShadowsCheck function will be called to check if the property for
* id should be gotten from the prototype, or if there is an own property that
* shadows it.
* If DoesntShadow is returned then the slot at listBaseExpandoSlot should
* either be undefined or point to an expando object that would contain the own
* property.
* If DoesntShadowUnique is returned then the slot at listBaseExpandoSlot should
* contain a private pointer to a ExpandoAndGeneration, which contains a
* JS::Value that should either be undefined or point to an expando object, and
* a uint32 value. If that value changes then the IC for getting a property will
* be invalidated.
*/
struct ExpandoAndGeneration {
ExpandoAndGeneration()
: expando(UndefinedValue()),
generation(0)
{}
Value expando;
uint32_t generation;
};
typedef enum ListBaseShadowsResult {
ShadowCheckFailed,
Shadows,
DoesntShadow,
DoesntShadowUnique
} ListBaseShadowsResult;
typedef ListBaseShadowsResult
(* ListBaseShadowsCheck)(JSContext* cx, JSHandleObject object, JSHandleId id);
JS_FRIEND_API(void)
SetListBaseInformation(void *listBaseHandlerFamily, uint32_t listBaseExpandoSlot,
ListBaseShadowsCheck listBaseShadowsCheck);
SetListBaseInformation(void *listBaseHandlerFamily, uint32_t listBaseExpandoSlot);
void *GetListBaseHandlerFamily();
uint32_t GetListBaseExpandoSlot();
ListBaseShadowsCheck GetListBaseShadowsCheck();
} /* namespace js */

View File

@ -677,15 +677,17 @@ struct GetPropHelper {
LookupStatus lookup() {
RootedObject aobj(cx, obj);
if (IsCacheableListBase(obj)) {
RootedId aid(cx, NameToId(name));
ListBaseShadowsResult shadows =
GetListBaseShadowsCheck()(cx, obj, aid);
if (shadows == ShadowCheckFailed)
return ic.error(cx);
// Either the property is shadowed or we need an additional check in
// the stub, which we haven't implemented.
if (shadows == Shadows || shadows == DoesntShadowUnique)
Value expandoValue = obj->getFixedSlot(GetListBaseExpandoSlot());
// Expando objects just hold any extra properties the object has been given by a
// script, and have no prototype or anything else that will complicate property
// lookups on them.
JS_ASSERT_IF(expandoValue.isObject(),
expandoValue.toObject().isNative() && !expandoValue.toObject().getProto());
if (expandoValue.isObject() && expandoValue.toObject().nativeContains(cx, name))
return Lookup_Uncacheable;
aobj = obj->getTaggedProto().toObjectOrNull();
}

View File

@ -25,7 +25,6 @@
#include "mozilla/dom/HTMLElementBinding.h"
#include "mozilla/dom/DocumentBinding.h"
#include "mozilla/dom/SVGElementBinding.h"
#include "mozilla/dom/HTMLDocumentBinding.h"
template<class T>
struct ProtoIDAndDepth
@ -53,7 +52,6 @@ NEW_BINDING(mozilla::dom::Element, Element);
NEW_BINDING(nsGenericHTMLElement, HTMLElement);
NEW_BINDING(nsIDocument, Document);
NEW_BINDING(nsDocument, Document);
NEW_BINDING(nsHTMLDocument, HTMLDocument);
NEW_BINDING(nsSVGElement, SVGElement);
NEW_BINDING(nsDOMEvent, Event);
NEW_BINDING(nsDOMMouseEvent, MouseEvent);

View File

@ -33,7 +33,7 @@ ok(sawProp, "property should be enumerable");
is(getter.call(document), document.documentElement, "the getter actually works");
Document.prototype.__defineSetter__('documentElement', function() {});
Object.getPrototypeOf(document).__defineSetter__('documentElement', function() {});
is(getter.call(document), document.documentElement, "the getter works after defineSetter");
var oldTitle = document.title;