Bug 838691 part 1. Add support in Prefable for calling a function to determine whether a property should be exposed in a WebIDL binding. r=peterv

This commit is contained in:
Boris Zbarsky 2013-02-19 11:54:40 -05:00
parent 39c064049b
commit 5803a201da
3 changed files with 41 additions and 22 deletions

View File

@ -185,7 +185,7 @@ DefinePrefable(JSContext* cx, JSObject* obj, Prefable<T>* props)
MOZ_ASSERT(props->specs);
do {
// Define if enabled
if (props->enabled) {
if (props->isEnabled(cx, obj)) {
if (!Define(cx, obj, props->specs)) {
return false;
}
@ -698,12 +698,12 @@ XrayResolveOwnProperty(JSContext* cx, JSObject* wrapper, JSObject* obj, jsid id,
}
static bool
XrayResolveAttribute(JSContext* cx, JSObject* wrapper, jsid id,
XrayResolveAttribute(JSContext* cx, JSObject* wrapper, JSObject* obj, jsid id,
Prefable<JSPropertySpec>* attributes, jsid* attributeIds,
JSPropertySpec* attributeSpecs, JSPropertyDescriptor* desc)
{
for (; attributes->specs; ++attributes) {
if (attributes->enabled) {
if (attributes->isEnabled(cx, obj)) {
// Set i to be the index into our full list of ids/specs that we're
// looking at now.
size_t i = attributes->specs - attributeSpecs;
@ -747,7 +747,7 @@ XrayResolveAttribute(JSContext* cx, JSObject* wrapper, jsid id,
}
static bool
XrayResolveProperty(JSContext* cx, JSObject* wrapper, jsid id,
XrayResolveProperty(JSContext* cx, JSObject* wrapper, JSObject* obj, jsid id,
JSPropertyDescriptor* desc, DOMObjectType type,
const NativeProperties* nativeProperties)
{
@ -766,7 +766,7 @@ XrayResolveProperty(JSContext* cx, JSObject* wrapper, jsid id,
if (methods) {
Prefable<JSFunctionSpec>* method;
for (method = methods; method->specs; ++method) {
if (method->enabled) {
if (method->isEnabled(cx, obj)) {
// Set i to be the index into our full list of ids/specs that we're
// looking at now.
size_t i = method->specs - methodsSpecs;
@ -795,7 +795,7 @@ XrayResolveProperty(JSContext* cx, JSObject* wrapper, jsid id,
if (type == eInterface) {
if (nativeProperties->staticAttributes) {
if (!XrayResolveAttribute(cx, wrapper, id,
if (!XrayResolveAttribute(cx, wrapper, obj, id,
nativeProperties->staticAttributes,
nativeProperties->staticAttributeIds,
nativeProperties->staticAttributeSpecs, desc)) {
@ -807,7 +807,7 @@ XrayResolveProperty(JSContext* cx, JSObject* wrapper, jsid id,
}
} else {
if (nativeProperties->attributes) {
if (!XrayResolveAttribute(cx, wrapper, id,
if (!XrayResolveAttribute(cx, wrapper, obj, id,
nativeProperties->attributes,
nativeProperties->attributeIds,
nativeProperties->attributeSpecs, desc)) {
@ -818,7 +818,7 @@ XrayResolveProperty(JSContext* cx, JSObject* wrapper, jsid id,
}
}
if (nativeProperties->unforgeableAttributes) {
if (!XrayResolveAttribute(cx, wrapper, id,
if (!XrayResolveAttribute(cx, wrapper, obj, id,
nativeProperties->unforgeableAttributes,
nativeProperties->unforgeableAttributeIds,
nativeProperties->unforgeableAttributeSpecs,
@ -834,7 +834,7 @@ XrayResolveProperty(JSContext* cx, JSObject* wrapper, jsid id,
if (nativeProperties->constants) {
Prefable<ConstantSpec>* constant;
for (constant = nativeProperties->constants; constant->specs; ++constant) {
if (constant->enabled) {
if (constant->isEnabled(cx, obj)) {
// Set i to be the index into our full list of ids/specs that we're
// looking at now.
size_t i = constant->specs - nativeProperties->constantSpecs;
@ -901,7 +901,7 @@ XrayResolveNativeProperty(JSContext* cx, JSObject* wrapper,
nativePropertyHooks->mNativeProperties;
if (nativeProperties.regular &&
!XrayResolveProperty(cx, wrapper, id, desc, type,
!XrayResolveProperty(cx, wrapper, obj, id, desc, type,
nativeProperties.regular)) {
return false;
}
@ -909,7 +909,7 @@ XrayResolveNativeProperty(JSContext* cx, JSObject* wrapper,
if (!desc->obj &&
nativeProperties.chromeOnly &&
xpc::AccessCheck::isChrome(js::GetObjectCompartment(wrapper)) &&
!XrayResolveProperty(cx, wrapper, id, desc, type,
!XrayResolveProperty(cx, wrapper, obj, id, desc, type,
nativeProperties.chromeOnly)) {
return false;
}
@ -951,12 +951,13 @@ XrayResolveNativeProperty(JSContext* cx, JSObject* wrapper, JSObject* obj,
}
bool
XrayEnumerateAttributes(Prefable<JSPropertySpec>* attributes,
XrayEnumerateAttributes(JSContext* cx, JSObject* wrapper, JSObject* obj,
Prefable<JSPropertySpec>* attributes,
jsid* attributeIds, JSPropertySpec* attributeSpecs,
unsigned flags, JS::AutoIdVector& props)
{
for (; attributes->specs; ++attributes) {
if (attributes->enabled) {
if (attributes->isEnabled(cx, obj)) {
// Set i to be the index into our full list of ids/specs that we're
// looking at now.
size_t i = attributes->specs - attributeSpecs;
@ -973,7 +974,8 @@ XrayEnumerateAttributes(Prefable<JSPropertySpec>* attributes,
}
bool
XrayEnumerateProperties(unsigned flags, JS::AutoIdVector& props,
XrayEnumerateProperties(JSContext* cx, JSObject* wrapper, JSObject* obj,
unsigned flags, JS::AutoIdVector& props,
DOMObjectType type,
const NativeProperties* nativeProperties)
{
@ -992,7 +994,7 @@ XrayEnumerateProperties(unsigned flags, JS::AutoIdVector& props,
if (methods) {
Prefable<JSFunctionSpec>* method;
for (method = methods; method->specs; ++method) {
if (method->enabled) {
if (method->isEnabled(cx, obj)) {
// Set i to be the index into our full list of ids/specs that we're
// looking at now.
size_t i = method->specs - methodsSpecs;
@ -1009,7 +1011,8 @@ XrayEnumerateProperties(unsigned flags, JS::AutoIdVector& props,
if (type == eInterface) {
if (nativeProperties->staticAttributes &&
!XrayEnumerateAttributes(nativeProperties->staticAttributes,
!XrayEnumerateAttributes(cx, wrapper, obj,
nativeProperties->staticAttributes,
nativeProperties->staticAttributeIds,
nativeProperties->staticAttributeSpecs,
flags, props)) {
@ -1017,14 +1020,16 @@ XrayEnumerateProperties(unsigned flags, JS::AutoIdVector& props,
}
} else {
if (nativeProperties->attributes &&
!XrayEnumerateAttributes(nativeProperties->attributes,
!XrayEnumerateAttributes(cx, wrapper, obj,
nativeProperties->attributes,
nativeProperties->attributeIds,
nativeProperties->attributeSpecs,
flags, props)) {
return false;
}
if (nativeProperties->unforgeableAttributes &&
!XrayEnumerateAttributes(nativeProperties->unforgeableAttributes,
!XrayEnumerateAttributes(cx, wrapper, obj,
nativeProperties->unforgeableAttributes,
nativeProperties->unforgeableAttributeIds,
nativeProperties->unforgeableAttributeSpecs,
flags, props)) {
@ -1035,7 +1040,7 @@ XrayEnumerateProperties(unsigned flags, JS::AutoIdVector& props,
if (nativeProperties->constants) {
Prefable<ConstantSpec>* constant;
for (constant = nativeProperties->constants; constant->specs; ++constant) {
if (constant->enabled) {
if (constant->isEnabled(cx, obj)) {
// Set i to be the index into our full list of ids/specs that we're
// looking at now.
size_t i = constant->specs - nativeProperties->constantSpecs;
@ -1074,13 +1079,15 @@ XrayEnumerateNativeProperties(JSContext* cx, JSObject* wrapper,
nativePropertyHooks->mNativeProperties;
if (nativeProperties.regular &&
!XrayEnumerateProperties(flags, props, type, nativeProperties.regular)) {
!XrayEnumerateProperties(cx, wrapper, obj, flags, props, type,
nativeProperties.regular)) {
return false;
}
if (nativeProperties.chromeOnly &&
xpc::AccessCheck::isChrome(js::GetObjectCompartment(wrapper)) &&
!XrayEnumerateProperties(flags, props, type, nativeProperties.chromeOnly)) {
!XrayEnumerateProperties(cx, wrapper, obj, flags, props, type,
nativeProperties.chromeOnly)) {
return false;
}

View File

@ -1086,7 +1086,7 @@ class PropertyDefiner:
specs = []
prefableSpecs = []
prefableTemplate = ' { true, &%s[%d] }'
prefableTemplate = ' { true, nullptr, &%s[%d] }'
prefCacheTemplate = '&%s[%d].enabled'
def switchToPref(props, pref):
# Remember the info about where our pref-controlled

View File

@ -62,10 +62,22 @@ struct ConstantSpec
JS::Value value;
};
typedef bool (*PropertyEnabled)(JSContext* cx, JSObject* global);
template<typename T>
struct Prefable {
inline bool isEnabled(JSContext* cx, JSObject* obj) {
return enabled &&
(!enabledFunc ||
enabledFunc(cx, js::GetGlobalForObjectCrossCompartment(obj)));
}
// A boolean indicating whether this set of specs is enabled
bool enabled;
// A function pointer to a function that can say the property is disabled
// even if "enabled" is set to true. If the pointer is null the value of
// "enabled" is used as-is.
PropertyEnabled enabledFunc;
// Array of specs, terminated in whatever way is customary for T.
// Null to indicate a end-of-array for Prefable, when such an
// indicator is needed.