зеркало из https://github.com/mozilla/gecko-dev.git
Back out bug 1131802 (changesets 80e90f586329 and 35c268f162db) and patch 2 from bug 1131805 (changeset 4139522bf814) on a CLOSED TREE for assertion failures.
Assertion failure: (ptrBits & 1) == 0, at ../../dist/include/js/Value.h :871 called from XrayCreateFunction
This commit is contained in:
Родитель
2598315589
Коммит
8de963d8ad
|
@ -981,28 +981,6 @@ GetNativePropertyHooks(JSContext *cx, JS::Handle<JSObject*> obj,
|
|||
return ifaceAndProtoJSClass->mNativeHooks;
|
||||
}
|
||||
|
||||
static JSObject*
|
||||
XrayCreateFunction(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JSNativeWrapper native, unsigned nargs, JS::Handle<jsid> id)
|
||||
{
|
||||
JSFunction* fun = js::NewFunctionByIdWithReserved(cx, native.op, nargs, 0,
|
||||
/* parent = */nullptr, id);
|
||||
if (!fun) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SET_JITINFO(fun, native.info);
|
||||
JSObject* obj = JS_GetFunctionObject(fun);
|
||||
js::SetFunctionNativeReserved(obj, XRAY_DOM_FUNCTION_PARENT_WRAPPER_SLOT,
|
||||
JS::ObjectValue(*wrapper));
|
||||
#ifdef DEBUG
|
||||
js::SetFunctionNativeReserved(obj, XRAY_DOM_FUNCTION_NATIVE_SLOT_FOR_ASSERT,
|
||||
JS::PrivateValue(JS_FUNC_TO_DATA_PTR(void *,
|
||||
native.op)));
|
||||
#endif
|
||||
return obj;
|
||||
}
|
||||
|
||||
static bool
|
||||
XrayResolveAttribute(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
|
@ -1025,18 +1003,23 @@ XrayResolveAttribute(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
|||
// way to do this is wrap them up as functions ourselves.
|
||||
desc.setAttributes(attrSpec.flags);
|
||||
// They all have getters, so we can just make it.
|
||||
JS::Rooted<JSObject*> funobj(cx,
|
||||
XrayCreateFunction(cx, wrapper, attrSpec.getter.native, 0, id));
|
||||
if (!funobj)
|
||||
JS::Rooted<JSFunction*> fun(cx,
|
||||
JS_NewFunctionById(cx, attrSpec.getter.native.op,
|
||||
0, 0, wrapper, id));
|
||||
if (!fun)
|
||||
return false;
|
||||
SET_JITINFO(fun, attrSpec.getter.native.info);
|
||||
JSObject *funobj = JS_GetFunctionObject(fun);
|
||||
desc.setGetterObject(funobj);
|
||||
desc.attributesRef() |= JSPROP_GETTER;
|
||||
if (attrSpec.setter.native.op) {
|
||||
// We have a setter! Make it.
|
||||
funobj =
|
||||
XrayCreateFunction(cx, wrapper, attrSpec.setter.native, 1, id);
|
||||
if (!funobj)
|
||||
fun = JS_NewFunctionById(cx, attrSpec.setter.native.op, 1, 0,
|
||||
wrapper, id);
|
||||
if (!fun)
|
||||
return false;
|
||||
SET_JITINFO(fun, attrSpec.setter.native.info);
|
||||
funobj = JS_GetFunctionObject(fun);
|
||||
desc.setSetterObject(funobj);
|
||||
desc.attributesRef() |= JSPROP_SETTER;
|
||||
} else {
|
||||
|
@ -1071,24 +1054,22 @@ XrayResolveMethod(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
|||
cacheOnHolder = true;
|
||||
|
||||
const JSFunctionSpec& methodSpec = methodSpecs[i];
|
||||
JSObject *funobj;
|
||||
JSFunction *fun;
|
||||
if (methodSpec.selfHostedName) {
|
||||
JSFunction* fun =
|
||||
JS::GetSelfHostedFunction(cx, methodSpec.selfHostedName, id,
|
||||
methodSpec.nargs);
|
||||
fun = JS::GetSelfHostedFunction(cx, methodSpec.selfHostedName, id, methodSpec.nargs);
|
||||
if (!fun) {
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(!methodSpec.call.op, "Bad FunctionSpec declaration: non-null native");
|
||||
MOZ_ASSERT(!methodSpec.call.info, "Bad FunctionSpec declaration: non-null jitinfo");
|
||||
funobj = JS_GetFunctionObject(fun);
|
||||
} else {
|
||||
funobj = XrayCreateFunction(cx, wrapper, methodSpec.call,
|
||||
methodSpec.nargs, id);
|
||||
if (!funobj) {
|
||||
fun = JS_NewFunctionById(cx, methodSpec.call.op, methodSpec.nargs, 0, wrapper, id);
|
||||
if (!fun) {
|
||||
return false;
|
||||
}
|
||||
SET_JITINFO(fun, methodSpec.call.info);
|
||||
}
|
||||
JSObject *funobj = JS_GetFunctionObject(fun);
|
||||
desc.value().setObject(*funobj);
|
||||
desc.setAttributes(methodSpec.flags);
|
||||
desc.object().set(wrapper);
|
||||
|
|
|
@ -18,3 +18,10 @@ BEGIN_TEST(selfTest_NaNsAreSame)
|
|||
return true;
|
||||
}
|
||||
END_TEST(selfTest_NaNsAreSame)
|
||||
|
||||
BEGIN_TEST(selfTest_globalHasNoParent)
|
||||
{
|
||||
CHECK(JS_GetParent(global) == nullptr);
|
||||
return true;
|
||||
}
|
||||
END_TEST(selfTest_globalHasNoParent)
|
||||
|
|
|
@ -33,6 +33,8 @@ BEGIN_TEST(testTypedArrays)
|
|||
RootedObject proto(cx);
|
||||
JS_GetPrototype(cx, buffer, &proto);
|
||||
CHECK(!JS_IsArrayBufferObject(proto));
|
||||
RootedObject dummy(cx, JS_GetParent(proto));
|
||||
CHECK(!JS_IsArrayBufferObject(dummy));
|
||||
|
||||
{
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
|
@ -70,6 +72,8 @@ TestPlainTypedArray(JSContext *cx)
|
|||
RootedObject proto(cx);
|
||||
JS_GetPrototype(cx, array, &proto);
|
||||
CHECK(!JS_IsTypedArrayObject(proto));
|
||||
RootedObject dummy(cx, JS_GetParent(proto));
|
||||
CHECK(!JS_IsTypedArrayObject(dummy));
|
||||
|
||||
CHECK_EQUAL(JS_GetTypedArrayLength(array), 7u);
|
||||
CHECK_EQUAL(JS_GetTypedArrayByteOffset(array), 0u);
|
||||
|
|
|
@ -1717,6 +1717,13 @@ JS_PreventExtensions(JSContext *cx, JS::HandleObject obj, bool *succeeded)
|
|||
return PreventExtensions(cx, obj, succeeded);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_GetParent(JSObject *obj)
|
||||
{
|
||||
MOZ_ASSERT(!obj->is<ScopeObject>());
|
||||
return obj->getParent();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_GetConstructor(JSContext *cx, HandleObject proto)
|
||||
{
|
||||
|
|
|
@ -2242,6 +2242,9 @@ JS_GetPrototype(JSContext *cx, JS::HandleObject obj, JS::MutableHandleObject pro
|
|||
extern JS_PUBLIC_API(bool)
|
||||
JS_SetPrototype(JSContext *cx, JS::HandleObject obj, JS::HandleObject proto);
|
||||
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_GetParent(JSObject *obj);
|
||||
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_GetConstructor(JSContext *cx, JS::Handle<JSObject*> proto);
|
||||
|
||||
|
|
|
@ -473,13 +473,6 @@ js::SetFunctionNativeReserved(JSObject *fun, size_t which, const Value &val)
|
|||
fun->as<JSFunction>().setExtendedSlot(which, val);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
js::FunctionHasNativeReserved(JSObject *fun)
|
||||
{
|
||||
MOZ_ASSERT(fun->as<JSFunction>().isNative());
|
||||
return fun->as<JSFunction>().isExtended();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
js::GetObjectProto(JSContext *cx, JS::Handle<JSObject*> obj, JS::MutableHandle<JSObject*> proto)
|
||||
{
|
||||
|
|
|
@ -687,6 +687,14 @@ IsCallObject(JSObject *obj);
|
|||
JS_FRIEND_API(bool)
|
||||
CanAccessObjectShape(JSObject *obj);
|
||||
|
||||
inline JSObject *
|
||||
GetObjectParent(JSObject *obj)
|
||||
{
|
||||
MOZ_ASSERT(!IsScopeObject(obj));
|
||||
MOZ_ASSERT(CanAccessObjectShape(obj));
|
||||
return reinterpret_cast<shadow::Object*>(obj)->shape->base->parent;
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE JSCompartment *
|
||||
GetObjectCompartment(JSObject *obj)
|
||||
{
|
||||
|
@ -747,9 +755,6 @@ GetFunctionNativeReserved(JSObject *fun, size_t which);
|
|||
JS_FRIEND_API(void)
|
||||
SetFunctionNativeReserved(JSObject *fun, size_t which, const JS::Value &val);
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
FunctionHasNativeReserved(JSObject *fun);
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
GetObjectProto(JSContext *cx, JS::HandleObject obj, JS::MutableHandleObject proto);
|
||||
|
||||
|
|
|
@ -2584,7 +2584,7 @@ Clone(JSContext *cx, unsigned argc, jsval *vp)
|
|||
if (!JS_ValueToObject(cx, args[1], &parent))
|
||||
return false;
|
||||
} else {
|
||||
parent = js::GetGlobalForObjectCrossCompartment(&args.callee());
|
||||
parent = JS_GetParent(&args.callee());
|
||||
}
|
||||
|
||||
// Should it worry us that we might be getting with wrappers
|
||||
|
@ -3237,6 +3237,34 @@ Elapsed(JSContext *cx, unsigned argc, jsval *vp)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
Parent(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
if (args.length() != 1) {
|
||||
JS_ReportError(cx, "Wrong number of arguments");
|
||||
return false;
|
||||
}
|
||||
|
||||
Value v = args[0];
|
||||
if (v.isPrimitive()) {
|
||||
JS_ReportError(cx, "Only objects have parents!");
|
||||
return false;
|
||||
}
|
||||
|
||||
Rooted<JSObject*> parent(cx, JS_GetParent(&v.toObject()));
|
||||
|
||||
/* Outerize if necessary. */
|
||||
if (parent) {
|
||||
parent = GetOuterObject(cx, parent);
|
||||
if (!parent)
|
||||
return false;
|
||||
}
|
||||
|
||||
args.rval().setObjectOrNull(parent);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
Compile(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
|
@ -4904,6 +4932,10 @@ static const JSFunctionSpecWithHelp fuzzing_unsafe_functions[] = {
|
|||
" Get a self-hosted value by its name. Note that these values don't get \n"
|
||||
" cached, so repeatedly getting the same value creates multiple distinct clones."),
|
||||
|
||||
JS_FN_HELP("parent", Parent, 1, 0,
|
||||
"parent(obj)",
|
||||
" Returns the parent of obj."),
|
||||
|
||||
JS_FN_HELP("line2pc", LineToPC, 0, 0,
|
||||
"line2pc([fun,] line)",
|
||||
" Map line number to PC."),
|
||||
|
|
|
@ -119,25 +119,10 @@ JSObject *
|
|||
XrayAwareCalleeGlobal(JSObject *fun)
|
||||
{
|
||||
MOZ_ASSERT(js::IsFunctionObject(fun));
|
||||
|
||||
if (!js::FunctionHasNativeReserved(fun)) {
|
||||
// Just a normal function, no Xrays involved.
|
||||
return js::GetGlobalForObjectCrossCompartment(fun);
|
||||
}
|
||||
|
||||
// The functions we expect here have the Xray wrapper they're associated with
|
||||
// in their XRAY_DOM_FUNCTION_PARENT_WRAPPER_SLOT and, in a debug build, their
|
||||
// JSNative in their XRAY_DOM_FUNCTION_NATIVE_SLOT_FOR_ASSERT. Assert that
|
||||
// last bit.
|
||||
MOZ_ASSERT(js::GetFunctionNativeReserved(fun, XRAY_DOM_FUNCTION_NATIVE_SLOT_FOR_ASSERT).toPrivate() ==
|
||||
js::GetFunctionObjectNative(fun));
|
||||
|
||||
Value v =
|
||||
js::GetFunctionNativeReserved(fun, XRAY_DOM_FUNCTION_PARENT_WRAPPER_SLOT);
|
||||
MOZ_ASSERT(IsXrayWrapper(&v.toObject()));
|
||||
|
||||
JSObject *xrayTarget = js::UncheckedUnwrap(&v.toObject());
|
||||
return js::GetGlobalForObjectCrossCompartment(xrayTarget);
|
||||
JSObject *scope = js::GetObjectParent(fun);
|
||||
if (IsXrayWrapper(scope))
|
||||
scope = js::UncheckedUnwrap(scope);
|
||||
return js::GetGlobalForObjectCrossCompartment(scope);
|
||||
}
|
||||
|
||||
JSObject *
|
||||
|
|
|
@ -14,14 +14,6 @@
|
|||
#include "jswrapper.h"
|
||||
#include "js/Proxy.h"
|
||||
|
||||
// Slot where Xray functions for Web IDL methods store a pointer to
|
||||
// the Xray wrapper they're associated with.
|
||||
#define XRAY_DOM_FUNCTION_PARENT_WRAPPER_SLOT 0
|
||||
// Slot where in debug builds Xray functions for Web IDL methods store
|
||||
// a pointer to their JSNative, just so we can assert that they're the
|
||||
// sort of functions we expect.
|
||||
#define XRAY_DOM_FUNCTION_NATIVE_SLOT_FOR_ASSERT 1
|
||||
|
||||
// Xray wrappers re-resolve the original native properties on the native
|
||||
// object and always directly access to those properties.
|
||||
// Because they work so differently from the rest of the wrapper hierarchy,
|
||||
|
|
Загрузка…
Ссылка в новой задаче