Bug 1017424 part 5. Remove classinfo for Window. r=peterv

This commit is contained in:
Boris Zbarsky 2014-09-05 14:28:45 -04:00
Родитель b197b61892
Коммит 4532962c88
6 изменённых файлов: 19 добавлений и 562 удалений

Просмотреть файл

@ -35,7 +35,6 @@
#include "nsIXPConnect.h"
#include "xptcall.h"
#include "nsTArray.h"
#include "nsDocument.h" // nsDOMStyleSheetList
#include "nsDOMBlobBuilder.h"
// General helper includes
@ -51,18 +50,12 @@
#include "mozilla/Telemetry.h"
// Window scriptable helper includes
#include "nsIDocShell.h"
#include "nsJSUtils.h"
#include "nsScriptNameSpaceManager.h"
#include "nsIJSNativeInitializer.h"
#include "nsJSEnvironment.h"
// DOM base includes
#include "nsIDOMLocation.h"
#include "nsIDOMWindow.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMJSWindow.h"
#include "nsIDOMChromeWindow.h"
#include "nsIDOMConstructor.h"
// DOM core includes
@ -134,10 +127,7 @@
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/Likely.h"
#include "WindowNamedPropertiesHandler.h"
#include "nsIInterfaceInfoManager.h"
#include "mozilla/dom/EventTargetBinding.h"
#include "mozilla/dom/WindowBinding.h"
#ifdef MOZ_TIME_MANAGER
#include "TimeManager.h"
@ -151,14 +141,6 @@ static NS_DEFINE_CID(kDOMSOF_CID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
// NOTE: DEFAULT_SCRIPTABLE_FLAGS and DOM_DEFAULT_SCRIPTABLE_FLAGS
// are defined in nsIDOMClassInfo.h.
#define WINDOW_SCRIPTABLE_FLAGS \
(nsIXPCScriptable::WANT_PRECREATE | \
nsIXPCScriptable::WANT_POSTCREATE | \
nsIXPCScriptable::WANT_ENUMERATE | \
nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE | \
nsIXPCScriptable::IS_GLOBAL_OBJECT | \
nsIXPCScriptable::WANT_OUTER_OBJECT)
#define ARRAY_SCRIPTABLE_FLAGS \
(DOM_DEFAULT_SCRIPTABLE_FLAGS | \
nsIXPCScriptable::WANT_GETPROPERTY | \
@ -244,17 +226,6 @@ DOMCI_DATA_NO_CLASS(XULPopupElement)
static nsDOMClassInfoData sClassInfoData[] = {
// Base classes
// The Window class lets you QI into interfaces that are not in the
// flattened set (i.e. nsIXPCScriptable::CLASSINFO_INTERFACES_ONLY
// is not set), because of this make sure all scriptable interfaces
// that are implemented by nsGlobalWindow can securely be exposed
// to JS.
NS_DEFINE_CLASSINFO_DATA(Window, nsWindowSH,
DEFAULT_SCRIPTABLE_FLAGS |
WINDOW_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(DOMPrototype, nsDOMConstructorSH,
DOM_BASE_SCRIPTABLE_FLAGS |
nsIXPCScriptable::WANT_PRECREATE |
@ -300,11 +271,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
DEFAULT_SCRIPTABLE_FLAGS)
#endif
// DOM Chrome Window class.
NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(ChromeWindow, nsWindowSH,
DEFAULT_SCRIPTABLE_FLAGS |
WINDOW_SCRIPTABLE_FLAGS)
#ifdef MOZ_XUL
NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULTemplateBuilder, nsDOMGenericSH,
DEFAULT_SCRIPTABLE_FLAGS)
@ -335,10 +301,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
NS_DEFINE_CLASSINFO_DATA(File, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(ModalContentWindow, nsWindowSH,
DEFAULT_SCRIPTABLE_FLAGS |
WINDOW_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(MozSmsMessage, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
@ -424,10 +386,7 @@ nsIXPConnect *nsDOMClassInfo::sXPConnect = nullptr;
bool nsDOMClassInfo::sIsInitialized = false;
jsid nsDOMClassInfo::sLocation_id = JSID_VOID;
jsid nsDOMClassInfo::sConstructor_id = JSID_VOID;
jsid nsDOMClassInfo::sTop_id = JSID_VOID;
jsid nsDOMClassInfo::sDocument_id = JSID_VOID;
jsid nsDOMClassInfo::sWrappedJSObject_id = JSID_VOID;
static const JSClass *sObjectClass = nullptr;
@ -519,10 +478,7 @@ nsDOMClassInfo::DefineStaticJSVals(JSContext *cx)
else \
return NS_ERROR_OUT_OF_MEMORY;
SET_JSID_TO_STRING(sLocation_id, cx, "location");
SET_JSID_TO_STRING(sConstructor_id, cx, "constructor");
SET_JSID_TO_STRING(sTop_id, cx, "top");
SET_JSID_TO_STRING(sDocument_id, cx, "document");
SET_JSID_TO_STRING(sWrappedJSObject_id, cx, "wrappedJSObject");
return NS_OK;
@ -734,29 +690,6 @@ nsDOMClassInfo::RegisterExternalClasses()
d.mInterfaces = interface_list; \
}
#ifdef MOZ_B2G
#define DOM_CLASSINFO_WINDOW_MAP_ENTRIES \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindow) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindowB2G) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMJSWindow) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget) \
DOM_CLASSINFO_MAP_ENTRY(nsIInlineEventHandlers) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindowPerformance) \
DOM_CLASSINFO_MAP_ENTRY(nsIInterfaceRequestor) \
DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsITouchEventReceiver, \
TouchEvent::PrefEnabled())
#else // !MOZ_B2G
#define DOM_CLASSINFO_WINDOW_MAP_ENTRIES \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindow) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMJSWindow) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget) \
DOM_CLASSINFO_MAP_ENTRY(nsIInlineEventHandlers) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindowPerformance) \
DOM_CLASSINFO_MAP_ENTRY(nsIInterfaceRequestor) \
DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsITouchEventReceiver, \
TouchEvent::PrefEnabled())
#endif // MOZ_B2G
nsresult
nsDOMClassInfo::Init()
{
@ -778,13 +711,6 @@ nsDOMClassInfo::Init()
AutoSafeJSContext cx;
DOM_CLASSINFO_MAP_BEGIN(Window, nsIDOMWindow)
DOM_CLASSINFO_WINDOW_MAP_ENTRIES
#ifdef MOZ_WEBSPEECH
DOM_CLASSINFO_MAP_ENTRY(nsISpeechSynthesisGetter)
#endif
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(DOMPrototype, nsIDOMDOMConstructor)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMConstructor)
DOM_CLASSINFO_MAP_END
@ -838,14 +764,6 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_END
#endif
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ChromeWindow, nsIDOMWindow)
DOM_CLASSINFO_WINDOW_MAP_ENTRIES
DOM_CLASSINFO_MAP_ENTRY(nsIDOMChromeWindow)
#ifdef MOZ_WEBSPEECH
DOM_CLASSINFO_MAP_ENTRY(nsISpeechSynthesisGetter)
#endif
DOM_CLASSINFO_MAP_END
#ifdef MOZ_XUL
DOM_CLASSINFO_MAP_BEGIN(XULTemplateBuilder, nsIXULTemplateBuilder)
DOM_CLASSINFO_MAP_ENTRY(nsIXULTemplateBuilder)
@ -890,14 +808,6 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMFile)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ModalContentWindow, nsIDOMWindow)
DOM_CLASSINFO_WINDOW_MAP_ENTRIES
DOM_CLASSINFO_MAP_ENTRY(nsIDOMModalContentWindow)
#ifdef MOZ_WEBSPEECH
DOM_CLASSINFO_MAP_ENTRY(nsISpeechSynthesisGetter)
#endif
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(MozSmsMessage, nsIDOMMozSmsMessage)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozSmsMessage)
DOM_CLASSINFO_MAP_END
@ -1555,146 +1465,13 @@ nsDOMClassInfo::ShutDown()
}
}
sLocation_id = JSID_VOID;
sConstructor_id = JSID_VOID;
sTop_id = JSID_VOID;
sDocument_id = JSID_VOID;
sWrappedJSObject_id = JSID_VOID;
NS_IF_RELEASE(sXPConnect);
sIsInitialized = false;
}
// Window helper
NS_IMETHODIMP
nsWindowSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
JSObject *globalObj, JSObject **parentObj)
{
// Normally ::PreCreate() is used to give XPConnect the parent
// object for the object that's being wrapped, this parent object is
// set as the parent of the wrapper and it's also used to find the
// right scope for the object being wrapped. Now, in the case of the
// global object the wrapper shouldn't have a parent but we supply
// one here anyway (the global object itself) and this will be used
// by XPConnect only to find the right scope, once the scope is
// found XPConnect will find the existing wrapper (which always
// exists since it's created on window construction), since an
// existing wrapper is found the parent we supply here is ignored
// after the wrapper is found.
nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryInterface(nativeObj));
NS_ASSERTION(sgo, "nativeObj not a global object!");
nsGlobalWindow *win = nsGlobalWindow::FromSupports(nativeObj);
NS_ASSERTION(win->IsInnerWindow(), "Should be inner window.");
// We sometimes get a disconnected window during file api test. :-(
if (!win->GetOuterWindowInternal())
return NS_ERROR_FAILURE;
// If we're bootstrapping, we don't have a JS object yet.
if (win->GetOuterWindowInternal()->IsCreatingInnerWindow())
return NS_OK;
return SetParentToWindow(win, parentObj);
}
NS_IMETHODIMP
nsWindowSH::PostCreatePrototype(JSContext* aCx, JSObject* aProto)
{
JS::Rooted<JSObject*> proto(aCx, aProto);
nsresult rv = nsDOMClassInfo::PostCreatePrototype(aCx, proto);
NS_ENSURE_SUCCESS(rv, rv);
// We should probably move this into the CreateInterfaceObjects for Window
// once it is on WebIDL bindings.
WindowNamedPropertiesHandler::Install(aCx, proto);
return NS_OK;
}
NS_IMETHODIMP
nsWindowSH::PostCreate(nsIXPConnectWrappedNative *wrapper,
JSContext *cx, JSObject *obj)
{
JS::Rooted<JSObject*> window(cx, obj);
#ifdef DEBUG
nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryWrappedNative(wrapper));
NS_ASSERTION(sgo && sgo->GetGlobalJSObject() == obj,
"Multiple wrappers created for global object!");
#endif
const NativeProperties* windowProperties =
WindowBinding::sNativePropertyHooks->mNativeProperties.regular;
const NativeProperties* eventTargetProperties =
EventTargetBinding::sNativePropertyHooks->mNativeProperties.regular;
if (!DefineWebIDLBindingUnforgeablePropertiesOnXPCObject(cx, window, windowProperties) ||
!DefineWebIDLBindingUnforgeablePropertiesOnXPCObject(cx, window, eventTargetProperties)) {
return NS_ERROR_FAILURE;
}
if (!GlobalPropertiesAreOwn()) {
return NS_OK;
}
return DefineWebIDLBindingPropertiesOnXPCObject(cx, window, windowProperties) &&
DefineWebIDLBindingPropertiesOnXPCObject(cx, window, eventTargetProperties) ?
NS_OK : NS_ERROR_FAILURE;
}
struct ResolveGlobalNameClosure
{
JSContext* cx;
JS::Handle<JSObject*> obj;
bool* retval;
};
static PLDHashOperator
ResolveGlobalName(const nsAString& aName,
const nsGlobalNameStruct& aNameStruct,
void* aClosure)
{
ResolveGlobalNameClosure* closure =
static_cast<ResolveGlobalNameClosure*>(aClosure);
JS::Rooted<JS::Value> dummy(closure->cx);
bool ok = JS_LookupUCProperty(closure->cx, closure->obj,
aName.BeginReading(), aName.Length(),
&dummy);
if (!ok) {
*closure->retval = false;
return PL_DHASH_STOP;
}
return PL_DHASH_NEXT;
}
NS_IMETHODIMP
nsWindowSH::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *aObj, bool *_retval)
{
JS::Rooted<JSObject*> obj(cx, aObj);
if (!xpc::WrapperFactory::IsXrayWrapper(obj)) {
*_retval = JS_EnumerateStandardClasses(cx, obj);
if (!*_retval) {
return NS_OK;
}
// Now resolve everything from the namespace manager
nsScriptNameSpaceManager *nameSpaceManager = GetNameSpaceManager();
if (!nameSpaceManager) {
NS_ERROR("Can't get namespace manager.");
return NS_ERROR_UNEXPECTED;
}
ResolveGlobalNameClosure closure = { cx, obj, _retval };
nameSpaceManager->EnumerateGlobalNames(ResolveGlobalName, &closure);
}
return NS_OK;
}
static nsDOMConstructorFunc
FindConstructorFunc(const nsDOMClassInfoData *aDOMClassInfoData)
{
@ -2265,23 +2042,6 @@ GetXPCProto(nsIXPConnect *aXPConnect, JSContext *cx, nsGlobalWindow *aWin,
nsDOMClassInfoID ci_id = (nsDOMClassInfoID)id;
ci = NS_GetDOMClassInfoInstance(ci_id);
// In most cases we want to find the wrapped native prototype in
// aWin's scope and use that prototype for
// ClassName.prototype. But in the case where we're setting up
// "Window.prototype" or "ChromeWindow.prototype" we want to do
// the look up in aWin's outer window's scope since the inner
// window's wrapped native prototype comes from the outer
// window's scope.
if (ci_id == eDOMClassInfo_Window_id ||
ci_id == eDOMClassInfo_ModalContentWindow_id ||
ci_id == eDOMClassInfo_ChromeWindow_id) {
nsGlobalWindow *scopeWindow = aWin->GetOuterWindowInternal();
if (scopeWindow) {
aWin = scopeWindow;
}
}
}
else {
ci = nsDOMClassInfo::GetClassInfoInstance(aNameStruct->mData);
@ -2498,6 +2258,7 @@ LookupComponentsShim(JSContext *cx, JS::Handle<JSObject*> global,
nsPIDOMWindow *win,
JS::MutableHandle<JSPropertyDescriptor> desc);
// static
bool
nsWindowSH::NameStructEnabled(JSContext* aCx, nsGlobalWindow *aWin,
const nsAString& aName,
@ -2732,7 +2493,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
// set up the prototype chain. This will go ahead and define things on the
// actual window's global.
nsCOMPtr<nsIXPConnectJSObjectHolder> proto_holder;
rv = GetXPCProto(sXPConnect, cx, aWin, name_struct,
rv = GetXPCProto(nsDOMClassInfo::sXPConnect, cx, aWin, name_struct,
getter_AddRefs(proto_holder));
NS_ENSURE_SUCCESS(rv, rv);
bool isXray = xpc::WrapperFactory::IsXrayWrapper(obj);
@ -2755,7 +2516,8 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
ci_data = name_struct->mData;
}
return ResolvePrototype(sXPConnect, aWin, cx, obj, class_name, ci_data,
return ResolvePrototype(nsDOMClassInfo::sXPConnect, aWin, cx, obj,
class_name, ci_data,
name_struct, nameSpaceManager, dot_prototype,
desc);
}
@ -2763,7 +2525,8 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
if (name_struct->mType == nsGlobalNameStruct::eTypeClassProto) {
// We don't have a XPConnect prototype object, let ResolvePrototype create
// one.
return ResolvePrototype(sXPConnect, aWin, cx, obj, class_name, nullptr,
return ResolvePrototype(nsDOMClassInfo::sXPConnect, aWin, cx, obj,
class_name, nullptr,
name_struct, nameSpaceManager, nullptr, desc);
}
@ -2776,7 +2539,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
// constructor is an alias for (for example for Image we need the prototype
// for HTMLImageElement).
nsCOMPtr<nsIXPConnectJSObjectHolder> proto_holder;
rv = GetXPCProto(sXPConnect, cx, aWin, alias_struct,
rv = GetXPCProto(nsDOMClassInfo::sXPConnect, cx, aWin, alias_struct,
getter_AddRefs(proto_holder));
NS_ENSURE_SUCCESS(rv, rv);
@ -2792,7 +2555,8 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
return NS_ERROR_UNEXPECTED;
}
return ResolvePrototype(sXPConnect, aWin, cx, obj, class_name, ci_data,
return ResolvePrototype(nsDOMClassInfo::sXPConnect, aWin, cx, obj,
class_name, ci_data,
name_struct, nameSpaceManager, nullptr, desc);
}
@ -2860,77 +2624,6 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
return rv;
}
template<class Interface>
static nsresult
LocationSetterGuts(JSContext *cx, JSObject *obj, JS::MutableHandle<JS::Value> vp)
{
// This function duplicates some of the logic in XPC_WN_HelperSetProperty
obj = js::CheckedUnwrap(obj, /* stopAtOuter = */ false);
if (!IS_WN_REFLECTOR(obj))
return NS_ERROR_XPC_BAD_CONVERT_JS;
XPCWrappedNative *wrapper = XPCWrappedNative::Get(obj);
// The error checks duplicate code in THROW_AND_RETURN_IF_BAD_WRAPPER
NS_ENSURE_TRUE(!wrapper || wrapper->IsValid(), NS_ERROR_XPC_HAS_BEEN_SHUTDOWN);
nsCOMPtr<Interface> xpcomObj = do_QueryWrappedNative(wrapper, obj);
NS_ENSURE_TRUE(xpcomObj, NS_ERROR_UNEXPECTED);
nsCOMPtr<nsIDOMLocation> location;
nsresult rv = xpcomObj->GetLocation(getter_AddRefs(location));
NS_ENSURE_SUCCESS(rv, rv);
// Grab the value we're being set to before we stomp on |vp|
JS::Rooted<JSString*> val(cx, JS::ToString(cx, vp));
NS_ENSURE_TRUE(val, NS_ERROR_UNEXPECTED);
// Make sure |val| stays alive below
JS::Anchor<JSString *> anchor(val);
// We have to wrap location into vp before null-checking location, to
// avoid assigning the wrong thing into the slot.
rv = WrapNative(cx, location, &NS_GET_IID(nsIDOMLocation), true, vp);
NS_ENSURE_SUCCESS(rv, rv);
if (!location) {
// Make this a no-op
return NS_OK;
}
nsAutoJSString str;
NS_ENSURE_TRUE(str.init(cx, val), NS_ERROR_UNEXPECTED);
return location->SetHref(str);
}
template<class Interface>
static bool
LocationSetter(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, bool strict,
JS::MutableHandle<JS::Value> vp)
{
nsresult rv = LocationSetterGuts<Interface>(cx, obj, vp);
if (NS_FAILED(rv)) {
xpc::Throw(cx, rv);
return false;
}
return true;
}
static bool
LocationSetterUnwrapper(JSContext *cx, JS::Handle<JSObject*> obj_, JS::Handle<jsid> id,
bool strict, JS::MutableHandle<JS::Value> vp)
{
JS::Rooted<JSObject*> obj(cx, obj_);
JSObject *wrapped = XPCWrapper::UnsafeUnwrapSecurityWrapper(obj);
if (wrapped) {
obj = wrapped;
}
return LocationSetter<nsIDOMWindow>(cx, obj, id, strict, vp);
}
struct InterfaceShimEntry {
const char *geckoName;
const char *domName;
@ -3019,200 +2712,6 @@ LookupComponentsShim(JSContext *cx, JS::Handle<JSObject*> global,
return NS_OK;
}
NS_IMETHODIMP
nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj_, jsid id_, JSObject **objp,
bool *_retval)
{
JS::Rooted<JSObject*> obj(cx, obj_);
JS::Rooted<jsid> id(cx, id_);
if (!JSID_IS_STRING(id)) {
return NS_OK;
}
MOZ_ASSERT(*_retval == true); // guaranteed by XPC_WN_Helper_NewResolve
nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
MOZ_ASSERT(win->IsInnerWindow());
// Don't resolve standard classes on XrayWrappers, only resolve them if we're
// resolving on the real global object.
bool isXray = xpc::WrapperFactory::IsXrayWrapper(obj);
if (!isXray) {
bool did_resolve = false;
if (!JS_ResolveStandardClass(cx, obj, id, &did_resolve)) {
// Return NS_OK to avoid stomping over the exception that was passed
// down from the ResolveStandardClass call.
*_retval = false;
return NS_OK;
}
if (did_resolve) {
*objp = obj;
return NS_OK;
}
}
// WebIDL quickstubs handle location for us, but Xrays don't see those. So if
// we're an Xray, we have to resolve stuff here to make "window.location =
// someString" work.
if (sLocation_id == id && isXray) {
nsCOMPtr<nsIDOMLocation> location;
nsresult rv = win->GetLocation(getter_AddRefs(location));
NS_ENSURE_SUCCESS(rv, rv);
JS::Rooted<JS::Value> v(cx);
rv = WrapNative(cx, location, &NS_GET_IID(nsIDOMLocation), true, &v);
NS_ENSURE_SUCCESS(rv, rv);
bool ok = JS_DefinePropertyById(cx, obj, id, v,
JSPROP_PERMANENT | JSPROP_ENUMERATE,
JS_PropertyStub, LocationSetterUnwrapper);
if (!ok) {
return NS_ERROR_FAILURE;
}
*objp = obj;
return NS_OK;
}
// WebIDL quickstubs handle "top" for us, but Xrays don't see those. So if
// we're an Xray and we want "top" to be JSPROP_PERMANENT, we need to resolve
// it here.
if (sTop_id == id && isXray) {
nsCOMPtr<nsIDOMWindow> top;
nsresult rv = win->GetScriptableTop(getter_AddRefs(top));
NS_ENSURE_SUCCESS(rv, rv);
JS::Rooted<JS::Value> v(cx);
js::AssertSameCompartment(cx, obj);
rv = WrapNative(cx, top, &NS_GET_IID(nsIDOMWindow), true, &v);
NS_ENSURE_SUCCESS(rv, rv);
// Hold on to the top window object as a global property so we
// don't need to worry about losing expando properties etc.
if (!JS_DefinePropertyById(cx, obj, id, v,
JSPROP_READONLY | JSPROP_PERMANENT |
JSPROP_ENUMERATE,
JS_PropertyStub, JS_StrictPropertyStub)) {
return NS_ERROR_FAILURE;
}
*objp = obj;
return NS_OK;
}
if (isXray) {
// We promise to resolve on the underlying object first. That will create
// the actual interface object if needed and store it in a data structure
// hanging off the global. Then our second call will wrap up in an Xray as
// needed. We do things this way because we use the existence of the
// object in that data structure as a flag that indicates that its name
// (and any relevant named constructor names) has been resolved before;
// this allows us to avoid re-resolving in the Xray case if the property is
// deleted by page script.
JS::Rooted<JSObject*> global(cx,
js::UncheckedUnwrap(obj, /* stopAtOuter = */ false));
JSAutoCompartment ac(cx, global);
JS::Rooted<JSPropertyDescriptor> desc(cx);
if (!win->DoNewResolve(cx, global, id, &desc)) {
return NS_ERROR_FAILURE;
}
// If we have an object here, that means we resolved the property.
// But if the value is undefined, that means that GlobalResolve
// also already defined it, so we don't have to.
if (desc.object() && !desc.value().isUndefined() &&
!JS_DefinePropertyById(cx, global, id, desc.value(),
desc.attributes(),
desc.getter(), desc.setter())) {
return NS_ERROR_FAILURE;
}
}
JS::Rooted<JSPropertyDescriptor> desc(cx);
if (!win->DoNewResolve(cx, obj, id, &desc)) {
return NS_ERROR_FAILURE;
}
if (desc.object()) {
// If we have an object here, that means we resolved the property.
// But if the value is undefined, that means that GlobalResolve
// also already defined it, so we don't have to. Note that in the
// Xray case we should never see undefined.
MOZ_ASSERT_IF(isXray, !desc.value().isUndefined());
if (!desc.value().isUndefined() &&
!JS_DefinePropertyById(cx, obj, id, desc.value(),
desc.attributes(),
desc.getter(), desc.setter())) {
return NS_ERROR_FAILURE;
}
*objp = obj;
return NS_OK;
}
if (sDocument_id == id) {
nsCOMPtr<nsIDocument> document = win->GetDoc();
JS::Rooted<JS::Value> v(cx);
nsresult rv = WrapNative(cx, document, document,
&NS_GET_IID(nsIDOMDocument), &v, false);
NS_ENSURE_SUCCESS(rv, rv);
// nsIDocument::WrapObject will handle defining the property.
*objp = obj;
// NB: We need to do this for any Xray wrapper.
if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
*_retval = JS_WrapValue(cx, &v) &&
JS_DefineProperty(cx, obj, "document", v,
JSPROP_READONLY | JSPROP_ENUMERATE,
JS_PropertyStub, JS_StrictPropertyStub);
if (!*_retval) {
return NS_ERROR_UNEXPECTED;
}
}
return NS_OK;
}
return nsDOMGenericSH::NewResolve(wrapper, cx, obj, id, objp, _retval);
}
NS_IMETHODIMP
nsWindowSH::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, JSObject * *_retval)
{
nsGlobalWindow *origWin = nsGlobalWindow::FromWrapper(wrapper);
nsGlobalWindow *win = origWin->GetOuterWindowInternal();
if (!win) {
// If we no longer have an outer window. No code should ever be
// running on a window w/o an outer, which means this hook should
// never be called when we have no outer. But just in case, return
// null to prevent leaking an inner window to code in a different
// window.
*_retval = nullptr;
return NS_ERROR_UNEXPECTED;
}
JS::Rooted<JSObject*> winObj(cx, win->FastGetGlobalJSObject());
MOZ_ASSERT(winObj);
// Note that while |wrapper| is same-compartment with cx, the outer window
// might not be. If we're running script in an inactive scope and evalute
// |this|, the outer window is actually a cross-compartment wrapper. So we
// need to wrap here.
if (!JS_WrapObject(cx, &winObj)) {
*_retval = nullptr;
return NS_ERROR_UNEXPECTED;
}
*_retval = winObj;
return NS_OK;
}
// EventTarget helper
NS_IMETHODIMP

Просмотреть файл

@ -68,10 +68,11 @@ struct nsExternalDOMClassInfoData : public nsDOMClassInfoData
#define MARK_EXTERNAL(_ptr) (nsIClassInfo*)(uintptr_t(_ptr) | 0x1)
#define IS_EXTERNAL(_ptr) (uintptr_t(_ptr) & 0x1)
class nsWindowSH;
class nsDOMClassInfo : public nsXPCClassInfo
{
friend class nsHTMLDocumentSH;
friend class nsWindowSH;
protected:
virtual ~nsDOMClassInfo();
@ -156,10 +157,7 @@ protected:
static bool sIsInitialized;
public:
static jsid sLocation_id;
static jsid sConstructor_id;
static jsid sTop_id;
static jsid sDocument_id;
static jsid sWrappedJSObject_id;
};
@ -230,46 +228,20 @@ public:
}
};
// Window scriptable helper
class nsWindowSH : public nsDOMGenericSH
// A place to hang some static methods that we should really consider
// moving to be nsGlobalWindow member methods. See bug 1062418.
class nsWindowSH
{
protected:
explicit nsWindowSH(nsDOMClassInfoData *aData) : nsDOMGenericSH(aData)
{
}
virtual ~nsWindowSH()
{
}
static nsresult GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc);
friend class nsGlobalWindow;
public:
NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
JSObject *globalObj, JSObject **parentObj) MOZ_OVERRIDE;
NS_IMETHOD PostCreatePrototype(JSContext * cx, JSObject * proto) MOZ_OVERRIDE;
NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj) MOZ_OVERRIDE;
NS_IMETHOD Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, bool *_retval) MOZ_OVERRIDE;
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, JSObject **objp,
bool *_retval) MOZ_OVERRIDE;
NS_IMETHOD OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, JSObject * *_retval) MOZ_OVERRIDE;
static bool NameStructEnabled(JSContext* aCx, nsGlobalWindow *aWin,
const nsAString& aName,
const nsGlobalNameStruct& aNameStruct);
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
{
return new nsWindowSH(aData);
}
};

Просмотреть файл

@ -4,7 +4,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// IWYU pragma: private, include "nsDOMClassInfoID.h"
DOMCI_CLASS(Window)
DOMCI_CLASS(DOMPrototype)
DOMCI_CLASS(DOMConstructor)
@ -26,9 +25,6 @@ DOMCI_CLASS(TreeSelection)
DOMCI_CLASS(TreeContentView)
#endif
// DOM Chrome Window class, almost identical to Window
DOMCI_CLASS(ChromeWindow)
#ifdef MOZ_XUL
DOMCI_CLASS(XULTemplateBuilder)
DOMCI_CLASS(XULTreeBuilder)
@ -50,9 +46,6 @@ DOMCI_CLASS(XPathNSResolver)
DOMCI_CLASS(Blob)
DOMCI_CLASS(File)
// DOM modal content window class, almost identical to Window
DOMCI_CLASS(ModalContentWindow)
DOMCI_CLASS(MozSmsMessage)
DOMCI_CLASS(MozMmsMessage)
DOMCI_CLASS(MozMobileMessageThread)

Просмотреть файл

@ -1637,8 +1637,6 @@ nsGlobalWindow::FreeInnerObjects()
// nsGlobalWindow::nsISupports
//*****************************************************************************
DOMCI_DATA(Window, nsGlobalWindow)
// QueryInterface implementation for nsGlobalWindow
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindow)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
@ -1673,7 +1671,6 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindow)
NS_INTERFACE_MAP_ENTRY(nsIDOMWindowPerformance)
NS_INTERFACE_MAP_ENTRY(nsITouchEventReceiver)
NS_INTERFACE_MAP_ENTRY(nsIInlineEventHandlers)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Window)
NS_INTERFACE_MAP_END
@ -13371,12 +13368,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsGlobalChromeWindow,
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGroupMessageManagers)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
DOMCI_DATA(ChromeWindow, nsGlobalChromeWindow)
// QueryInterface implementation for nsGlobalChromeWindow
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsGlobalChromeWindow)
NS_INTERFACE_MAP_ENTRY(nsIDOMChromeWindow)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ChromeWindow)
NS_INTERFACE_MAP_END_INHERITING(nsGlobalWindow)
NS_IMPL_ADDREF_INHERITED(nsGlobalChromeWindow, nsGlobalWindow)
@ -13773,11 +13767,8 @@ nsGlobalWindow::GetGroupMessageManager(const nsAString& aGroup,
// nsGlobalModalWindow implementation
// QueryInterface implementation for nsGlobalModalWindow
DOMCI_DATA(ModalContentWindow, nsGlobalModalWindow)
NS_INTERFACE_MAP_BEGIN(nsGlobalModalWindow)
NS_INTERFACE_MAP_ENTRY(nsIDOMModalContentWindow)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ModalContentWindow)
NS_INTERFACE_MAP_END_INHERITING(nsGlobalWindow)
NS_IMPL_ADDREF_INHERITED(nsGlobalModalWindow, nsGlobalWindow)

Просмотреть файл

@ -643,8 +643,6 @@ var interfaceNamesInGlobalScope =
"MimeType",
// IMPORTANT: Do not change this list without review from a DOM peer!
"MimeTypeArray",
// IMPORTANT: Do not change this list without review from a DOM peer!
"ModalContentWindow",
// IMPORTANT: Do not change this list without review from a DOM peer!
"MouseEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!

Просмотреть файл

@ -23,7 +23,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=763343
const Ci = Components.interfaces;
const Cu = Components.utils;
var singleton = window.QueryInterface(Ci.nsIClassInfo);
// We need an object here that has singleton classinfo. For now, the console
// service works.
var singleton = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIClassInfo);
ok(singleton.flags & Ci.nsIClassInfo.SINGLETON_CLASSINFO,
"Should have singleton classinfo");
var sb = new Cu.Sandbox(window);
// Don't crash.