mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Fix JS_TraceChildren crash triggered by findReferences. Bug 708261, r=jimb.
--HG-- extra : rebase_source : 336ebf499834345d364955000977a952014ea2bb
This commit is contained in:
parent
92b99889d2
commit
579d99f332
@ -184,16 +184,6 @@ MarkObjectUnbarriered(JSTracer *trc, JSObject *obj, const char *name)
|
||||
Mark(trc, obj);
|
||||
}
|
||||
|
||||
void
|
||||
MarkObjectWithPrinterUnbarriered(JSTracer *trc, JSObject *obj, JSTraceNamePrinter printer,
|
||||
const void *arg, size_t index)
|
||||
{
|
||||
JS_ASSERT(trc);
|
||||
JS_ASSERT(obj);
|
||||
JS_SET_TRACING_DETAILS(trc, printer, arg, index);
|
||||
Mark(trc, obj);
|
||||
}
|
||||
|
||||
void
|
||||
MarkObject(JSTracer *trc, const MarkablePtr<JSObject> &obj, const char *name)
|
||||
{
|
||||
@ -675,30 +665,6 @@ MarkRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name)
|
||||
MarkIdRangeUnbarriered(trc, len, vec, name);
|
||||
}
|
||||
|
||||
static void
|
||||
PrintPropertyId(char *buf, size_t bufsize, jsid propid, const char *label)
|
||||
{
|
||||
JS_ASSERT(!JSID_IS_VOID(propid));
|
||||
if (JSID_IS_ATOM(propid)) {
|
||||
size_t n = PutEscapedString(buf, bufsize, JSID_TO_ATOM(propid), 0);
|
||||
if (n < bufsize)
|
||||
JS_snprintf(buf + n, bufsize - n, " %s", label);
|
||||
} else if (JSID_IS_INT(propid)) {
|
||||
JS_snprintf(buf, bufsize, "%d %s", JSID_TO_INT(propid), label);
|
||||
} else {
|
||||
JS_snprintf(buf, bufsize, "<object> %s", label);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
PrintPropertyGetterOrSetter(JSTracer *trc, char *buf, size_t bufsize)
|
||||
{
|
||||
JS_ASSERT(trc->debugPrinter == PrintPropertyGetterOrSetter);
|
||||
Shape *shape = (Shape *)trc->debugPrintArg;
|
||||
PrintPropertyId(buf, bufsize, shape->propid(),
|
||||
trc->debugPrintIndex ? js_setter_str : js_getter_str);
|
||||
}
|
||||
|
||||
static inline void
|
||||
ScanValue(GCMarker *gcmarker, const Value &v)
|
||||
{
|
||||
@ -999,15 +965,10 @@ MarkChildren(JSTracer *trc, const Shape *shape)
|
||||
void
|
||||
MarkChildren(JSTracer *trc, BaseShape *base)
|
||||
{
|
||||
if (base->hasGetterObject()) {
|
||||
MarkObjectWithPrinterUnbarriered(trc, base->getterObject(),
|
||||
PrintPropertyGetterOrSetter, base, 0);
|
||||
}
|
||||
|
||||
if (base->hasSetterObject()) {
|
||||
MarkObjectWithPrinterUnbarriered(trc, base->setterObject(),
|
||||
PrintPropertyGetterOrSetter, base, 0);
|
||||
}
|
||||
if (base->hasGetterObject())
|
||||
MarkObjectUnbarriered(trc, base->getterObject(), "getter");
|
||||
if (base->hasSetterObject())
|
||||
MarkObjectUnbarriered(trc, base->setterObject(), "setter");
|
||||
|
||||
if (base->isOwned())
|
||||
MarkBaseShapeUnbarriered(trc, base->baseUnowned(), "base");
|
||||
|
@ -11,7 +11,7 @@ if (typeof findReferences == "function") {
|
||||
o.alsoMyself = o; // multiple self-references should all be reported
|
||||
|
||||
assertEq(referencesVia(o, 'type; type_proto', C.prototype), true);
|
||||
assertEq(referencesVia(o, 'parent', this), true);
|
||||
assertEq(referencesVia(o, 'shape; base; parent', this), true);
|
||||
assertEq(referencesVia(o, 'x', o.x), true);
|
||||
assertEq(referencesVia(o, '42', o[42]), true);
|
||||
assertEq(referencesVia(o, 'myself', o), true);
|
||||
@ -20,22 +20,22 @@ if (typeof findReferences == "function") {
|
||||
function g() { return 42; }
|
||||
function s(v) { }
|
||||
var p = Object.defineProperty({}, 'a', { get:g, set:s });
|
||||
assertEq(referencesVia(p, 'shape; a getter', g), true);
|
||||
assertEq(referencesVia(p, 'shape; a setter', s), true);
|
||||
assertEq(referencesVia(p, 'shape; base; getter', g), true);
|
||||
assertEq(referencesVia(p, 'shape; base; setter', s), true);
|
||||
|
||||
// If there are multiple objects with the same shape referring to a getter
|
||||
// or setter, findReferences should get all of them, even though the shape
|
||||
// gets 'marked' the first time we visit it.
|
||||
var q = Object.defineProperty({}, 'a', { get:g, set:s });
|
||||
assertEq(referencesVia(p, 'shape; a getter', g), true);
|
||||
assertEq(referencesVia(q, 'shape; a getter', g), true);
|
||||
assertEq(referencesVia(p, 'shape; base; getter', g), true);
|
||||
assertEq(referencesVia(q, 'shape; base; getter', g), true);
|
||||
|
||||
// If we extend each object's shape chain, both should still be able to
|
||||
// reach the getter, even though the two shapes are each traversed twice.
|
||||
p.b = 9;
|
||||
q.b = 9;
|
||||
assertEq(referencesVia(p, 'shape; a getter', g), true);
|
||||
assertEq(referencesVia(q, 'shape; a getter', g), true);
|
||||
assertEq(referencesVia(p, 'shape; parent; base; getter', g), true);
|
||||
assertEq(referencesVia(q, 'shape; parent; base; getter', g), true);
|
||||
|
||||
// These are really just ordinary own property references.
|
||||
assertEq(referencesVia(C, 'prototype', Object.getPrototypeOf(o)), true);
|
||||
|
@ -13,14 +13,14 @@ if (typeof findReferences == "function") {
|
||||
assertEq(referencesVia(returnFlat(o), 'upvars[0]', o), true);
|
||||
|
||||
function returnHeavy(y) { eval(''); return function heavy() { return y; }; }
|
||||
assertEq(referencesVia(returnHeavy(o), 'parent; y', o), true);
|
||||
assertEq(referencesVia(returnHeavy(o), 'parent; parent', this), true);
|
||||
assertEq(referencesVia(returnHeavy(o), 'fun_callscope; y', o), true);
|
||||
assertEq(referencesVia(returnHeavy(o), 'fun_callscope; shape; base; parent', this), true);
|
||||
|
||||
function returnBlock(z) { eval(''); let(w = z) { return function block() { return w; }; }; }
|
||||
assertEq(referencesVia(returnBlock(o), 'parent; w', o), true);
|
||||
assertEq(referencesVia(returnBlock(o), 'fun_callscope; w', o), true);
|
||||
|
||||
function returnWithObj(v) { with(v) return function withObj() { return u; }; }
|
||||
assertEq(referencesVia(returnWithObj(o), 'parent; type; type_proto', o), true);
|
||||
assertEq(referencesVia(returnWithObj(o), 'fun_callscope; type; type_proto', o), true);
|
||||
|
||||
reportCompare(true, true);
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user