Bug 1054756, part 1 - Support symbol-keyed properties in JSXrayTraits::resolveOwnProperty(). r=jandem.

--HG--
extra : commitid : Iw7k8V0s8vH
extra : rebase_source : 47344f609f8282df5cfe30ccb89792e3b26e5d3c
This commit is contained in:
Jason Orendorff 2015-07-07 19:22:20 -05:00
Родитель 15a26cce97
Коммит cba3fb8913
5 изменённых файлов: 119 добавлений и 102 удалений

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

@ -3315,22 +3315,6 @@ JS_NewFunction(JSContext* cx, JSNative native, unsigned nargs, unsigned flags,
: NewNativeFunction(cx, native, nargs, atom);
}
JS_PUBLIC_API(JSFunction*)
JS_NewFunctionById(JSContext* cx, JSNative native, unsigned nargs, unsigned flags,
HandleId id)
{
MOZ_ASSERT(JSID_IS_STRING(id));
MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
MOZ_ASSERT(native);
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
RootedAtom name(cx, JSID_TO_ATOM(id));
return (flags & JSFUN_CONSTRUCTOR)
? NewNativeConstructor(cx, native, nargs, name)
: NewNativeFunction(cx, native, nargs, name);
}
JS_PUBLIC_API(JSFunction*)
JS::GetSelfHostedFunction(JSContext* cx, const char* selfHostedName, HandleId id, unsigned nargs)
{
@ -3352,6 +3336,52 @@ JS::GetSelfHostedFunction(JSContext* cx, const char* selfHostedName, HandleId id
return &funVal.toObject().as<JSFunction>();
}
JS_PUBLIC_API(JSFunction*)
JS::NewFunctionFromSpec(JSContext* cx, const JSFunctionSpec* fs, HandleId id)
{
// Delay cloning self-hosted functions until they are called. This is
// achieved by passing DefineFunction a nullptr JSNative which produces an
// interpreted JSFunction where !hasScript. Interpreted call paths then
// call InitializeLazyFunctionScript if !hasScript.
if (fs->selfHostedName) {
MOZ_ASSERT(!fs->call.op);
MOZ_ASSERT(!fs->call.info);
JSAtom* shAtom = Atomize(cx, fs->selfHostedName, strlen(fs->selfHostedName));
if (!shAtom)
return nullptr;
RootedPropertyName shName(cx, shAtom->asPropertyName());
RootedAtom name(cx, IdToFunctionName(cx, id));
if (!name)
return nullptr;
RootedValue funVal(cx);
if (!GlobalObject::getSelfHostedFunction(cx, cx->global(), shName, name, fs->nargs,
&funVal))
{
return nullptr;
}
return &funVal.toObject().as<JSFunction>();
}
RootedAtom atom(cx, IdToFunctionName(cx, id));
if (!atom)
return nullptr;
JSFunction* fun;
if (!fs->call.op)
fun = NewScriptedFunction(cx, fs->nargs, JSFunction::INTERPRETED_LAZY, atom);
else if (fs->flags & JSFUN_CONSTRUCTOR)
fun = NewNativeConstructor(cx, fs->call.op, fs->nargs, atom);
else
fun = NewNativeFunction(cx, fs->call.op, fs->nargs, atom);
if (!fun)
return nullptr;
if (fs->call.info)
fun->setJitInfo(fs->call.info);
return fun;
}
static bool
CreateNonSyntacticScopeChain(JSContext* cx, AutoObjectVector& scopeChain,
MutableHandleObject dynamicScopeObj,
@ -3576,39 +3606,30 @@ GenericNativeMethodDispatcher(JSContext* cx, unsigned argc, Value* vp)
return fs->call.op(cx, argc, vp);
}
JS_PUBLIC_API(bool)
JS_DefineFunctions(JSContext* cx, HandleObject obj, const JSFunctionSpec* fs,
PropertyDefinitionBehavior behavior)
static bool
DefineFunctionFromSpec(JSContext* cx, HandleObject obj, const JSFunctionSpec* fs, unsigned flags)
{
MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
GetterOp gop;
SetterOp sop;
if (flags & JSFUN_STUB_GSOPS) {
// JSFUN_STUB_GSOPS is a request flag only, not stored in fun->flags or
// the defined property's attributes.
flags &= ~JSFUN_STUB_GSOPS;
gop = nullptr;
sop = nullptr;
} else {
gop = obj->getClass()->getProperty;
sop = obj->getClass()->setProperty;
MOZ_ASSERT(gop != JS_PropertyStub);
MOZ_ASSERT(sop != JS_StrictPropertyStub);
}
RootedId id(cx);
for (; fs->name; fs++) {
if (!PropertySpecNameToId(cx, fs->name, &id))
return false;
unsigned flags = fs->flags;
switch (behavior) {
case DefineAllProperties:
break;
case OnlyDefineLateProperties:
if (!(flags & JSPROP_DEFINE_LATE))
continue;
break;
default:
MOZ_ASSERT(behavior == DontDefineLateProperties);
if (flags & JSPROP_DEFINE_LATE)
continue;
}
flags &= ~JSPROP_DEFINE_LATE;
/*
* Define a generic arity N+1 static method for the arity N prototype
* method if flags contains JSFUN_GENERIC_NATIVE.
*/
// Define a generic arity N+1 static method for the arity N prototype
// method if flags contains JSFUN_GENERIC_NATIVE.
if (flags & JSFUN_GENERIC_NATIVE) {
// We require that any consumers using JSFUN_GENERIC_NATIVE stash
// the prototype and constructor in the global slots before invoking
@ -3625,45 +3646,45 @@ JS_DefineFunctions(JSContext* cx, HandleObject obj, const JSFunctionSpec* fs,
if (!fun)
return false;
/*
* As jsapi.h notes, fs must point to storage that lives as long
* as fun->object lives.
*/
// As jsapi.h notes, fs must point to storage that lives as long
// as fun->object lives.
fun->setExtendedSlot(0, PrivateValue(const_cast<JSFunctionSpec*>(fs)));
}
/*
* Delay cloning self-hosted functions until they are called. This is
* achieved by passing DefineFunction a nullptr JSNative which
* produces an interpreted JSFunction where !hasScript. Interpreted
* call paths then call InitializeLazyFunctionScript if !hasScript.
*/
if (fs->selfHostedName) {
MOZ_ASSERT(!fs->call.op);
MOZ_ASSERT(!fs->call.info);
JSAtom* shAtom = Atomize(cx, fs->selfHostedName, strlen(fs->selfHostedName));
if (!shAtom)
return false;
RootedPropertyName shName(cx, shAtom->asPropertyName());
RootedAtom name(cx, IdToFunctionName(cx, id));
if (!name)
return false;
RootedValue funVal(cx);
if (!GlobalObject::getSelfHostedFunction(cx, cx->global(), shName, name, fs->nargs,
&funVal))
{
return false;
}
if (!DefineProperty(cx, obj, id, funVal, nullptr, nullptr, flags))
return false;
} else {
JSFunction* fun = DefineFunction(cx, obj, id, fs->call.op, fs->nargs, flags);
JSFunction* fun = NewFunctionFromSpec(cx, fs, id);
if (!fun)
return false;
if (fs->call.info)
fun->setJitInfo(fs->call.info);
RootedValue funVal(cx, ObjectValue(*fun));
return DefineProperty(cx, obj, id, funVal, gop, sop, flags & ~JSFUN_FLAGS_MASK);
}
JS_PUBLIC_API(bool)
JS_DefineFunctions(JSContext* cx, HandleObject obj, const JSFunctionSpec* fs,
PropertyDefinitionBehavior behavior)
{
MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
for (; fs->name; fs++) {
unsigned flags = fs->flags;
switch (behavior) {
case DefineAllProperties:
break;
case OnlyDefineLateProperties:
if (!(flags & JSPROP_DEFINE_LATE))
continue;
break;
default:
MOZ_ASSERT(behavior == DontDefineLateProperties);
if (flags & JSPROP_DEFINE_LATE)
continue;
}
if (!DefineFunctionFromSpec(cx, obj, fs, flags & ~JSPROP_DEFINE_LATE))
return false;
}
return true;
}

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

@ -3124,20 +3124,23 @@ extern JS_PUBLIC_API(JSFunction*)
JS_NewFunction(JSContext* cx, JSNative call, unsigned nargs, unsigned flags,
const char* name);
/*
* Create the function with the name given by the id. JSID_IS_STRING(id) must
* be true.
*/
extern JS_PUBLIC_API(JSFunction*)
JS_NewFunctionById(JSContext* cx, JSNative call, unsigned nargs, unsigned flags,
JS::Handle<jsid> id);
namespace JS {
extern JS_PUBLIC_API(JSFunction*)
GetSelfHostedFunction(JSContext* cx, const char* selfHostedName, JS::Handle<jsid> id,
GetSelfHostedFunction(JSContext* cx, const char* selfHostedName, HandleId id,
unsigned nargs);
/**
* Create a new function based on the given JSFunctionSpec, *fs.
* id is the result of a successful call to
* `PropertySpecNameToPermanentId(cx, fs->name, &id)`.
*
* Unlike JS_DefineFunctions, this does not treat fs as an array.
* *fs must not be JS_FS_END.
*/
extern JS_PUBLIC_API(JSFunction*)
NewFunctionFromSpec(JSContext* cx, const JSFunctionSpec* fs, HandleId id);
} /* namespace JS */
extern JS_PUBLIC_API(JSObject*)

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

@ -2223,8 +2223,7 @@ js::IdToFunctionName(JSContext* cx, HandleId id)
JSFunction*
js::DefineFunction(JSContext* cx, HandleObject obj, HandleId id, Native native,
unsigned nargs, unsigned flags, AllocKind allocKind /* = AllocKind::FUNCTION */,
NewObjectKind newKind /* = GenericObject */)
unsigned nargs, unsigned flags, AllocKind allocKind /* = AllocKind::FUNCTION */)
{
GetterOp gop;
SetterOp sop;
@ -2253,11 +2252,11 @@ js::DefineFunction(JSContext* cx, HandleObject obj, HandleId id, Native native,
if (!native)
fun = NewScriptedFunction(cx, nargs,
JSFunction::INTERPRETED_LAZY, atom,
allocKind, newKind, obj);
allocKind, GenericObject, obj);
else if (flags & JSFUN_CONSTRUCTOR)
fun = NewNativeConstructor(cx, native, nargs, atom, allocKind, newKind);
fun = NewNativeConstructor(cx, native, nargs, atom, allocKind);
else
fun = NewNativeFunction(cx, native, nargs, atom, allocKind, newKind);
fun = NewNativeFunction(cx, native, nargs, atom, allocKind);
if (!fun)
return nullptr;

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

@ -636,8 +636,7 @@ IdToFunctionName(JSContext* cx, HandleId id);
extern JSFunction*
DefineFunction(JSContext* cx, HandleObject obj, HandleId id, JSNative native,
unsigned nargs, unsigned flags,
gc::AllocKind allocKind = gc::AllocKind::FUNCTION,
NewObjectKind newKind = GenericObject);
gc::AllocKind allocKind = gc::AllocKind::FUNCTION);
bool
FunctionHasResolveHook(const JSAtomState& atomState, jsid id);

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

@ -518,12 +518,7 @@ JSXrayTraits::resolveOwnProperty(JSContext* cx, const Wrapper& jsWrapper,
}
if (fsMatch) {
// Generate an Xrayed version of the method.
RootedFunction fun(cx);
if (fsMatch->selfHostedName) {
fun = JS::GetSelfHostedFunction(cx, fsMatch->selfHostedName, id, fsMatch->nargs);
} else {
fun = JS_NewFunctionById(cx, fsMatch->call.op, fsMatch->nargs, 0, id);
}
RootedFunction fun(cx, JS::NewFunctionFromSpec(cx, fsMatch, id));
if (!fun)
return false;