☠☠ backed out by a37fedd51b7d ☠ ☠ | |
author | Boris Zbarsky <bzbarsky@mit.edu> |
Thu, 30 Oct 2014 17:40:17 -0400 | |
changeset 213250 | de692c3335f2c67402d155a6b512cab4b7b88e70 |
parent 213249 | 2d449a2b4e1cc684f316f2ad116e352497f6798e |
child 213251 | 13ecff8001149ea961c4490af1a99fe03195d1d9 |
push id | 27745 |
push user | cbook@mozilla.com |
push date | Fri, 31 Oct 2014 13:09:12 +0000 |
treeherder | mozilla-central@6bd2071b373f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | peterv |
bugs | 1088228 |
milestone | 36.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
dom/xbl/nsXBLProtoImplMethod.cpp | file | annotate | diff | comparison | revisions | |
dom/xbl/nsXBLPrototypeHandler.cpp | file | annotate | diff | comparison | revisions |
--- a/dom/xbl/nsXBLProtoImplMethod.cpp +++ b/dom/xbl/nsXBLProtoImplMethod.cpp @@ -264,16 +264,17 @@ nsXBLProtoImplMethod::Write(nsIObjectOut } return NS_OK; } nsresult nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement, JSAddonId* aAddonId) { + MOZ_ASSERT(aBoundElement->IsElement()); NS_PRECONDITION(IsCompiled(), "Can't execute uncompiled method"); if (!GetCompiledMethod()) { // Nothing to do here return NS_OK; } // Get the script context the same way @@ -290,47 +291,46 @@ nsXBLProtoImplAnonymousMethod::Execute(n // We are going to run script via JS::Call, so we need a script entry point, // but as this is XBL related it does not appear in the HTML spec. dom::AutoEntryScript aes(global); JSContext* cx = aes.cx(); JS::Rooted<JSObject*> globalObject(cx, global->GetGlobalJSObject()); - JS::Rooted<JS::Value> v(cx); - nsresult rv = nsContentUtils::WrapNative(cx, aBoundElement, &v); - NS_ENSURE_SUCCESS(rv, rv); - - JS::Rooted<JSObject*> thisObject(cx, &v.toObject()); JS::Rooted<JSObject*> scopeObject(cx, xpc::GetScopeForXBLExecution(cx, globalObject, aAddonId)); NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY); JSAutoCompartment ac(cx, scopeObject); - if (!JS_WrapObject(cx, &thisObject)) - return NS_ERROR_OUT_OF_MEMORY; + JS::AutoObjectVector scopeChain(cx); + if (!nsJSUtils::GetScopeChainForElement(cx, aBoundElement->AsElement(), + scopeChain)) { + return NS_ERROR_OUT_OF_MEMORY; + } + MOZ_ASSERT(scopeChain.length() != 0); - // Clone the function object, using thisObject as the parent so "this" is in - // the scope chain of the resulting function (for backwards compat to the - // days when this was an event handler). + // Clone the function object, using our scope chain (for backwards + // compat to the days when this was an event handler). JS::Rooted<JSObject*> jsMethodObject(cx, GetCompiledMethod()); - JS::Rooted<JSObject*> method(cx, ::JS_CloneFunctionObject(cx, jsMethodObject, thisObject)); + JS::Rooted<JSObject*> method(cx, JS::CloneFunctionObject(cx, jsMethodObject, + scopeChain)); if (!method) return NS_ERROR_OUT_OF_MEMORY; // Now call the method // Check whether script is enabled. bool scriptAllowed = nsContentUtils::GetSecurityManager()-> ScriptAllowed(js::GetGlobalForObjectCrossCompartment(method)); bool ok = true; if (scriptAllowed) { JS::Rooted<JS::Value> retval(cx); JS::Rooted<JS::Value> methodVal(cx, JS::ObjectValue(*method)); - ok = ::JS::Call(cx, thisObject, methodVal, JS::HandleValueArray::empty(), &retval); + ok = ::JS::Call(cx, scopeChain[0], methodVal, JS::HandleValueArray::empty(), &retval); } if (!ok) { // If a constructor or destructor threw an exception, it doesn't stop // anything else. We just report it. Note that we need to set aside the // frame chain here, since the constructor invocation is not related to // whatever is on the stack right now, really. nsJSUtils::ReportPendingException(cx);
--- a/dom/xbl/nsXBLPrototypeHandler.cpp +++ b/dom/xbl/nsXBLPrototypeHandler.cpp @@ -39,16 +39,17 @@ #include "nsUnicharUtils.h" #include "nsCRT.h" #include "nsXBLEventHandler.h" #include "nsXBLSerialize.h" #include "nsJSUtils.h" #include "mozilla/BasicEvents.h" #include "mozilla/JSEventHandler.h" #include "mozilla/Preferences.h" +#include "mozilla/dom/Element.h" #include "mozilla/dom/EventHandlerBinding.h" #include "mozilla/dom/ScriptSettings.h" #include "xpcpublic.h" using namespace mozilla; using namespace mozilla::dom; uint32_t nsXBLPrototypeHandler::gRefCnt = 0; @@ -295,26 +296,25 @@ nsXBLPrototypeHandler::ExecuteHandler(Ev // First, enter our XBL scope. This is where the generic handler should have // been compiled, above. JSAutoCompartment ac(cx, scopeObject); JS::Rooted<JSObject*> genericHandler(cx, handler.get()); bool ok = JS_WrapObject(cx, &genericHandler); NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY); MOZ_ASSERT(!js::IsCrossCompartmentWrapper(genericHandler)); - // Wrap the native into the XBL scope. This creates a reflector in the document - // scope if one doesn't already exist, and potentially wraps it cross- - // compartment into our scope (via aAllowWrapping=true). - JS::Rooted<JS::Value> targetV(cx, JS::UndefinedValue()); - rv = nsContentUtils::WrapNative(cx, scriptTarget, &targetV); - NS_ENSURE_SUCCESS(rv, rv); + // Build a scope chain in the XBL scope. + nsRefPtr<Element> targetElement = do_QueryObject(scriptTarget); + JS::AutoObjectVector scopeChain(cx); + ok = nsJSUtils::GetScopeChainForElement(cx, targetElement, scopeChain); + NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY); - // Next, clone the generic handler to be parented to the target. - JS::Rooted<JSObject*> target(cx, &targetV.toObject()); - JS::Rooted<JSObject*> bound(cx, JS_CloneFunctionObject(cx, genericHandler, target)); + // Next, clone the generic handler with our desired scope chain. + JS::Rooted<JSObject*> bound(cx, JS::CloneFunctionObject(cx, genericHandler, + scopeChain)); NS_ENSURE_TRUE(bound, NS_ERROR_FAILURE); nsRefPtr<EventHandlerNonNull> handlerCallback = new EventHandlerNonNull(bound, /* aIncumbentGlobal = */ nullptr); TypedEventHandler typedHandler(handlerCallback); // Execute it.