mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
bf10328ba6
commit
5005320e02
@ -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__");
|
||||
|
||||
|
@ -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'");
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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.
|
||||
|
@ -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()
|
||||
|
@ -19,7 +19,7 @@ namespace dom {
|
||||
class MediaDocument : public nsHTMLDocument
|
||||
{
|
||||
public:
|
||||
MediaDocument(bool aUseXPConnectToWrap = false);
|
||||
MediaDocument();
|
||||
virtual ~MediaDocument();
|
||||
|
||||
virtual nsresult Init();
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -415,6 +415,7 @@ DOMInterfaces = {
|
||||
|
||||
'HTMLDocument': {
|
||||
'nativeType': 'nsHTMLDocument',
|
||||
'register': False,
|
||||
'hasXPConnectImpls': True,
|
||||
'resultNotAddRefed': [ 'body', 'head', 'images', 'embeds', 'plugins',
|
||||
'links', 'forms', 'scripts', 'anchors', 'applets' ],
|
||||
|
@ -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):
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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:
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
interface Selection;
|
||||
|
||||
[OverrideBuiltins]
|
||||
interface HTMLDocument : Document {
|
||||
[Throws]
|
||||
attribute DOMString? domain;
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user