mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Track whether default 'new' types need unknown properties on the prototype, bug 700501.
This commit is contained in:
parent
d2fe69d826
commit
708b16abe9
13
js/src/jit-test/tests/basic/bug700501.js
Normal file
13
js/src/jit-test/tests/basic/bug700501.js
Normal file
@ -0,0 +1,13 @@
|
||||
Function.prototype.__proto__["p"] = 3
|
||||
c = [].__proto__
|
||||
c[5] = 3
|
||||
Namespace.prototype.__proto__[4] = function() {}
|
||||
gc()
|
||||
Function("\
|
||||
{\
|
||||
function f(d) {}\
|
||||
for each(let z in[0]) {\
|
||||
f(z)\
|
||||
}\
|
||||
}\
|
||||
")()
|
@ -3172,8 +3172,8 @@ JS_NewObject(JSContext *cx, JSClass *jsclasp, JSObject *proto, JSObject *parent)
|
||||
JS_ASSERT(clasp != &FunctionClass);
|
||||
JS_ASSERT(!(clasp->flags & JSCLASS_IS_GLOBAL));
|
||||
|
||||
if (proto)
|
||||
proto->getNewType(cx, NULL, /* markUnknown = */ true);
|
||||
if (proto && !proto->setNewTypeUnknown(cx))
|
||||
return NULL;
|
||||
|
||||
JSObject *obj = NewObjectWithClassProto(cx, clasp, proto, parent);
|
||||
if (obj) {
|
||||
|
@ -3662,7 +3662,8 @@ js_InitArrayClass(JSContext *cx, JSObject *obj)
|
||||
return NULL;
|
||||
|
||||
/* The default 'new' object for Array.prototype has unknown properties. */
|
||||
arrayProto->getNewType(cx, NULL, /* markUnknown = */ true);
|
||||
if (!arrayProto->setNewTypeUnknown(cx))
|
||||
return NULL;
|
||||
|
||||
if (!LinkConstructorAndPrototype(cx, ctor, arrayProto))
|
||||
return NULL;
|
||||
|
@ -5726,8 +5726,29 @@ JSObject::hasNewType(TypeObject *type)
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
bool
|
||||
JSObject::setNewTypeUnknown(JSContext *cx)
|
||||
{
|
||||
if (!setFlag(cx, js::BaseShape::NEW_TYPE_UNKNOWN))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* If the object already has a new type, mark that type as unknown. It will
|
||||
* not have the SETS_MARKED_UNKNOWN bit set, so may require a type set
|
||||
* crawl if prototypes of the object change dynamically in the future.
|
||||
*/
|
||||
JSCompartment::NewTypeObjectSet &table = compartment()->newTypeObjects;
|
||||
if (table.initialized()) {
|
||||
JSCompartment::NewTypeObjectSet::Ptr p = table.lookup(this);
|
||||
if (p)
|
||||
MarkTypeObjectUnknownProperties(cx, *p);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TypeObject *
|
||||
JSObject::getNewType(JSContext *cx, JSFunction *fun, bool markUnknown)
|
||||
JSObject::getNewType(JSContext *cx, JSFunction *fun)
|
||||
{
|
||||
if (!setDelegate(cx))
|
||||
return NULL;
|
||||
@ -5754,12 +5775,12 @@ JSObject::getNewType(JSContext *cx, JSFunction *fun, bool markUnknown)
|
||||
*/
|
||||
if (type->newScript && type->newScript->fun != fun)
|
||||
type->clearNewScript(cx);
|
||||
if (markUnknown && cx->typeInferenceEnabled() && !type->unknownProperties())
|
||||
type->markUnknown(cx);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
bool markUnknown = lastProperty()->hasObjectFlag(BaseShape::NEW_TYPE_UNKNOWN);
|
||||
|
||||
TypeObject *type = cx->compartment->types.newTypeObject(cx, NULL,
|
||||
JSProto_Object, this, markUnknown);
|
||||
if (!type)
|
||||
|
@ -4997,8 +4997,11 @@ SetProto(JSContext *cx, JSObject *obj, JSObject *proto, bool checkForCycles)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (proto && !proto->setNewTypeUnknown(cx))
|
||||
return false;
|
||||
|
||||
TypeObject *type = proto
|
||||
? proto->getNewType(cx, NULL, /* markUnknown = */ true)
|
||||
? proto->getNewType(cx, NULL)
|
||||
: cx->compartment->getEmptyType(cx);
|
||||
if (!type)
|
||||
return false;
|
||||
|
@ -817,15 +817,27 @@ struct JSObject : js::gc::Cell
|
||||
|
||||
inline void setType(js::types::TypeObject *newType);
|
||||
|
||||
js::types::TypeObject *getNewType(JSContext *cx, JSFunction *fun = NULL,
|
||||
bool markUnknown = false);
|
||||
js::types::TypeObject *getNewType(JSContext *cx, JSFunction *fun = NULL);
|
||||
|
||||
#ifdef DEBUG
|
||||
bool hasNewType(js::types::TypeObject *newType);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Mark an object that has been iterated over and is a singleton. We need
|
||||
* to recover this information in the object's type information after it
|
||||
* is purged on GC.
|
||||
*/
|
||||
inline bool setIteratedSingleton(JSContext *cx);
|
||||
|
||||
/*
|
||||
* Mark an object as requiring its default 'new' type to have unknown
|
||||
* properties. This is set for a few builtins like Object.prototype and
|
||||
* Array.prototype; several places in the VM require that the default
|
||||
* type for these objects have unknown contents.
|
||||
*/
|
||||
bool setNewTypeUnknown(JSContext *cx);
|
||||
|
||||
/* Set a new prototype for an object with a singleton type. */
|
||||
bool splicePrototype(JSContext *cx, JSObject *proto);
|
||||
|
||||
|
@ -1428,8 +1428,8 @@ js::NewProxyObject(JSContext *cx, ProxyHandler *handler, const Value &priv, JSOb
|
||||
* their properties and so that we don't need to walk the compartment if
|
||||
* their prototype changes later.
|
||||
*/
|
||||
if (proto)
|
||||
proto->getNewType(cx, NULL, /* markUnknown = */ true);
|
||||
if (proto && !proto->setNewTypeUnknown(cx))
|
||||
return NULL;
|
||||
|
||||
JSObject *obj = NewObjectWithGivenProto(cx, clasp, proto, parent);
|
||||
if (!obj)
|
||||
|
@ -368,8 +368,9 @@ class BaseShape : public js::gc::Cell
|
||||
VAROBJ = 0x200,
|
||||
WATCHED = 0x400,
|
||||
ITERATED_SINGLETON = 0x800,
|
||||
NEW_TYPE_UNKNOWN = 0x1000,
|
||||
|
||||
OBJECT_FLAG_MASK = 0xff0
|
||||
OBJECT_FLAG_MASK = 0x1ff0
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -103,7 +103,11 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
|
||||
JSObject *objectProto = NewObjectWithGivenProto(cx, &ObjectClass, NULL, this);
|
||||
if (!objectProto || !objectProto->setSingletonType(cx))
|
||||
return NULL;
|
||||
types::TypeObject *objectType = objectProto->getNewType(cx, NULL, /* markUnknown = */ true);
|
||||
|
||||
if (!objectProto->setNewTypeUnknown(cx))
|
||||
return NULL;
|
||||
|
||||
types::TypeObject *objectType = objectProto->getNewType(cx);
|
||||
if (!objectType || !objectType->getEmptyShape(cx, &ObjectClass, gc::FINALIZE_OBJECT0))
|
||||
return NULL;
|
||||
|
||||
@ -138,7 +142,10 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
|
||||
if (!proto->setSingletonType(cx))
|
||||
return NULL;
|
||||
|
||||
types::TypeObject *functionType = proto->getNewType(cx, NULL, /* markUnknown = */ true);
|
||||
if (!proto->setNewTypeUnknown(cx))
|
||||
return NULL;
|
||||
|
||||
types::TypeObject *functionType = proto->getNewType(cx);
|
||||
if (!functionType || !functionType->getEmptyShape(cx, &FunctionClass, gc::FINALIZE_OBJECT0))
|
||||
return NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user