Bug 958262 - reduce space required by JSPropertySpec; r=till,bz,Waldo

This commit is contained in:
Nathan Froyd 2014-01-10 12:11:31 -05:00
parent fcb25e37ea
commit 10655c5f12
4 changed files with 62 additions and 31 deletions

View File

@ -951,21 +951,21 @@ XrayResolveAttribute(JSContext* cx, JS::Handle<JSObject*> wrapper,
// They all have getters, so we can just make it.
JS::Rooted<JSObject*> global(cx, JS_GetGlobalForObject(cx, wrapper));
JS::Rooted<JSFunction*> fun(cx,
JS_NewFunctionById(cx, (JSNative)attrSpec.getter.op,
JS_NewFunctionById(cx, (JSNative)attrSpec.getter.propertyOp.op,
0, 0, global, id));
if (!fun)
return false;
SET_JITINFO(fun, attrSpec.getter.info);
SET_JITINFO(fun, attrSpec.getter.propertyOp.info);
JSObject *funobj = JS_GetFunctionObject(fun);
desc.setGetterObject(funobj);
desc.attributesRef() |= JSPROP_GETTER;
if (attrSpec.setter.op) {
if (attrSpec.setter.propertyOp.op) {
// We have a setter! Make it.
fun = JS_NewFunctionById(cx, (JSNative)attrSpec.setter.op, 1, 0,
fun = JS_NewFunctionById(cx, (JSNative)attrSpec.setter.propertyOp.op, 1, 0,
global, id);
if (!fun)
return false;
SET_JITINFO(fun, attrSpec.setter.info);
SET_JITINFO(fun, attrSpec.setter.propertyOp.info);
funobj = JS_GetFunctionObject(fun);
desc.setSetterObject(funobj);
desc.attributesRef() |= JSPROP_SETTER;

View File

@ -1649,7 +1649,7 @@ class AttrDefiner(PropertyDefiner):
else:
accessor = "genericGetter"
jitinfo = "&%s_getterinfo" % attr.identifier.name
return "{ JS_CAST_NATIVE_TO(%s, JSPropertyOp), %s }" % \
return "{ { JS_CAST_NATIVE_TO(%s, JSPropertyOp), %s } }" % \
(accessor, jitinfo)
def setter(attr):
@ -1668,7 +1668,7 @@ class AttrDefiner(PropertyDefiner):
else:
accessor = "genericSetter"
jitinfo = "&%s_setterinfo" % attr.identifier.name
return "{ JS_CAST_NATIVE_TO(%s, JSStrictPropertyOp), %s }" % \
return "{ { JS_CAST_NATIVE_TO(%s, JSStrictPropertyOp), %s } }" % \
(accessor, jitinfo)
def specData(attr):

View File

@ -3289,10 +3289,23 @@ JS_DefineProperties(JSContext *cx, JSObject *objArg, const JSPropertySpec *ps)
RootedObject obj(cx, objArg);
bool ok;
for (ok = true; ps->name; ps++) {
if (ps->selfHostedGetter) {
if (ps->flags & JSPROP_NATIVE_ACCESSORS) {
// If you declare native accessors, then you should have a native
// getter.
JS_ASSERT(ps->getter.propertyOp.op);
// If you do not have a self-hosted getter, you should not have a
// self-hosted setter. This is the closest approximation to that
// assertion we can have with our setup.
JS_ASSERT_IF(ps->setter.propertyOp.info, ps->setter.propertyOp.op);
ok = DefineProperty(cx, obj, ps->name, UndefinedValue(),
ps->getter.propertyOp, ps->setter.propertyOp,
ps->flags, Shape::HAS_SHORTID, ps->tinyid);
} else {
// If you have self-hosted getter/setter, you can't have a
// native one.
JS_ASSERT(!ps->getter.op && !ps->setter.op);
JS_ASSERT(!ps->getter.propertyOp.op && !ps->setter.propertyOp.op);
JS_ASSERT(ps->flags & JSPROP_GETTER);
/*
* During creation of the self-hosting global, we ignore all
* self-hosted properties, as that means we're currently setting up
@ -3304,18 +3317,10 @@ JS_DefineProperties(JSContext *cx, JSObject *objArg, const JSPropertySpec *ps)
continue;
ok = DefineSelfHostedProperty(cx, obj, ps->name,
ps->selfHostedGetter,
ps->selfHostedSetter,
ps->getter.selfHosted.funname,
ps->setter.selfHosted.funname,
ps->flags, Shape::HAS_SHORTID,
ps->tinyid);
} else {
// If you do not have a self-hosted getter, you should
// have a native getter; and you should not have a
// self-hosted setter.
JS_ASSERT(ps->getter.op && !ps->selfHostedSetter);
ok = DefineProperty(cx, obj, ps->name, UndefinedValue(), ps->getter, ps->setter,
ps->flags, Shape::HAS_SHORTID, ps->tinyid);
}
if (!ok)
break;

View File

@ -2390,7 +2390,7 @@ typedef struct JSNativeWrapper {
* Macro static initializers which make it easy to pass no JSJitInfo as part of a
* JSPropertySpec or JSFunctionSpec.
*/
#define JSOP_WRAPPER(op) {op, nullptr}
#define JSOP_WRAPPER(op) { {op, nullptr} }
#define JSOP_NULLWRAPPER JSOP_WRAPPER(nullptr)
/*
@ -2399,13 +2399,30 @@ typedef struct JSNativeWrapper {
* JSPROP_INDEX bit in flags.
*/
struct JSPropertySpec {
struct SelfHostedWrapper {
void *unused;
const char *funname;
};
const char *name;
int8_t tinyid;
uint8_t flags;
JSPropertyOpWrapper getter;
JSStrictPropertyOpWrapper setter;
const char *selfHostedGetter;
const char *selfHostedSetter;
union {
JSPropertyOpWrapper propertyOp;
SelfHostedWrapper selfHosted;
} getter;
union {
JSStrictPropertyOpWrapper propertyOp;
SelfHostedWrapper selfHosted;
} setter;
private:
void StaticAsserts() {
JS_STATIC_ASSERT(sizeof(SelfHostedWrapper) == sizeof(JSPropertyOpWrapper));
JS_STATIC_ASSERT(sizeof(SelfHostedWrapper) == sizeof(JSStrictPropertyOpWrapper));
JS_STATIC_ASSERT(offsetof(SelfHostedWrapper, funname) ==
offsetof(JSPropertyOpWrapper, info));
}
};
namespace JS {
@ -2414,6 +2431,11 @@ namespace detail {
/* NEVER DEFINED, DON'T USE. For use by JS_CAST_NATIVE_TO only. */
inline int CheckIsNative(JSNative native);
/* NEVER DEFINED, DON'T USE. For use by JS_CAST_STRING_TO only. */
template<size_t N>
inline int
CheckIsCharacterLiteral(const char (&arr)[N]);
} // namespace detail
} // namespace JS
@ -2421,6 +2443,10 @@ inline int CheckIsNative(JSNative native);
(static_cast<void>(sizeof(JS::detail::CheckIsNative(v))), \
reinterpret_cast<To>(v))
#define JS_CAST_STRING_TO(s, To) \
(static_cast<void>(sizeof(JS::detail::CheckIsCharacterLiteral(s))), \
reinterpret_cast<To>(s))
#define JS_CHECK_ACCESSOR_FLAGS(flags) \
(static_cast<mozilla::EnableIf<!((flags) & (JSPROP_READONLY | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS))>::Type>(0), \
(flags))
@ -2436,23 +2462,23 @@ inline int CheckIsNative(JSNative native);
{name, 0, \
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS), \
JSOP_WRAPPER(JS_CAST_NATIVE_TO(getter, JSPropertyOp)), \
JSOP_NULLWRAPPER, nullptr, nullptr}
JSOP_NULLWRAPPER}
#define JS_PSGS(name, getter, setter, flags) \
{name, 0, \
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS), \
JSOP_WRAPPER(JS_CAST_NATIVE_TO(getter, JSPropertyOp)), \
JSOP_WRAPPER(JS_CAST_NATIVE_TO(setter, JSStrictPropertyOp)), \
nullptr, nullptr}
JSOP_WRAPPER(JS_CAST_NATIVE_TO(setter, JSStrictPropertyOp))}
#define JS_SELF_HOSTED_GET(name, getterName, flags) \
{name, 0, \
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER), \
JSOP_NULLWRAPPER, JSOP_NULLWRAPPER, getterName, nullptr}
{ nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo *) }, \
JSOP_NULLWRAPPER }
#define JS_SELF_HOSTED_GETSET(name, getterName, setterName, flags) \
{name, 0, \
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER), \
JSOP_NULLWRAPPER, JSOP_NULLWRAPPER, getterName, setterName}
#define JS_PS_END {0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER, \
nullptr, nullptr}
{ nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo *) }, \
{ nullptr, JS_CAST_STRING_TO(setterName, const JSJitInfo *) } }
#define JS_PS_END {0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
/*
* To define a native function, set call to a JSNativeWrapper. To define a