mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1171177 - Remove UNQUALIFIED_VAROBJ Shape flags in favor of Class-checking. (r=luke)
This commit is contained in:
parent
d044662630
commit
c2526c016f
@ -216,16 +216,35 @@ class JSObject : public js::gc::Cell
|
||||
return setFlags(cx, js::BaseShape::WATCHED, GENERATE_SHAPE);
|
||||
}
|
||||
|
||||
/* See InterpreterFrame::varObj. */
|
||||
inline bool isQualifiedVarObj();
|
||||
// A "qualified" varobj is the object on which "qualified" variable
|
||||
// declarations (i.e., those defined with "var") are kept.
|
||||
//
|
||||
// Conceptually, when a var binding is defined, it is defined on the
|
||||
// innermost qualified varobj on the scope chain.
|
||||
//
|
||||
// Function scopes (CallObjects) are qualified varobjs, and there can be
|
||||
// no other qualified varobj that is more inner for var bindings in that
|
||||
// function. As such, all references to local var bindings in a function
|
||||
// may be statically bound to the function scope. This is subject to
|
||||
// further optimization. Unaliased bindings inside functions reside
|
||||
// entirely on the frame, not in CallObjects.
|
||||
//
|
||||
// Global scopes are also qualified varobjs. It is possible to statically
|
||||
// know, for a given script, that are no more inner qualified varobjs, so
|
||||
// free variable references can be statically bound to the global.
|
||||
//
|
||||
// Finally, there are non-syntactic qualified varobjs used by embedders
|
||||
// (e.g., Gecko and XPConnect), as they often wish to run scripts under a
|
||||
// scope that captures var bindings.
|
||||
inline bool isQualifiedVarObj() const;
|
||||
bool setQualifiedVarObj(js::ExclusiveContext* cx) {
|
||||
return setFlags(cx, js::BaseShape::QUALIFIED_VAROBJ);
|
||||
}
|
||||
|
||||
inline bool isUnqualifiedVarObj();
|
||||
bool setUnqualifiedVarObj(js::ExclusiveContext* cx) {
|
||||
return setFlags(cx, js::BaseShape::UNQUALIFIED_VAROBJ);
|
||||
}
|
||||
// An "unqualified" varobj is the object on which "unqualified"
|
||||
// assignments (i.e., bareword assignments for which the LHS does not
|
||||
// exist on the scope chain) are kept.
|
||||
inline bool isUnqualifiedVarObj() const;
|
||||
|
||||
/*
|
||||
* Objects with an uncacheable proto can have their prototype mutated
|
||||
|
@ -220,24 +220,25 @@ js::DeleteElement(JSContext* cx, HandleObject obj, uint32_t index, ObjectOpResul
|
||||
/* * */
|
||||
|
||||
inline bool
|
||||
JSObject::isQualifiedVarObj()
|
||||
JSObject::isQualifiedVarObj() const
|
||||
{
|
||||
if (is<js::DebugScopeObject>())
|
||||
return as<js::DebugScopeObject>().scope().isQualifiedVarObj();
|
||||
// TODO: We would like to assert that only GlobalObject or
|
||||
// NonSyntacticVariables object is a qualified varobj, but users of
|
||||
// js::Execute still need to be vetted. See bug 1171177.
|
||||
return hasAllFlags(js::BaseShape::QUALIFIED_VAROBJ);
|
||||
bool rv = hasAllFlags(js::BaseShape::QUALIFIED_VAROBJ);
|
||||
MOZ_ASSERT_IF(rv,
|
||||
is<js::GlobalObject>() ||
|
||||
is<js::CallObject>() ||
|
||||
is<js::NonSyntacticVariablesObject>() ||
|
||||
(is<js::DynamicWithObject>() && !as<js::DynamicWithObject>().isSyntactic()));
|
||||
return rv;
|
||||
}
|
||||
|
||||
inline bool
|
||||
JSObject::isUnqualifiedVarObj()
|
||||
JSObject::isUnqualifiedVarObj() const
|
||||
{
|
||||
if (is<js::DebugScopeObject>())
|
||||
return as<js::DebugScopeObject>().scope().isUnqualifiedVarObj();
|
||||
bool rv = hasAllFlags(js::BaseShape::UNQUALIFIED_VAROBJ);
|
||||
MOZ_ASSERT_IF(rv, is<js::GlobalObject>() || is<js::NonSyntacticVariablesObject>());
|
||||
return rv;
|
||||
return is<js::GlobalObject>() || is<js::NonSyntacticVariablesObject>();
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
@ -247,6 +247,7 @@ GlobalObject::createInternal(JSContext* cx, const Class* clasp)
|
||||
return nullptr;
|
||||
|
||||
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
|
||||
MOZ_ASSERT(global->isUnqualifiedVarObj());
|
||||
|
||||
// Initialize the private slot to null if present, as GC can call class
|
||||
// hooks before the caller gets to set this to a non-garbage value.
|
||||
@ -257,8 +258,6 @@ GlobalObject::createInternal(JSContext* cx, const Class* clasp)
|
||||
|
||||
if (!global->setQualifiedVarObj(cx))
|
||||
return nullptr;
|
||||
if (!global->setUnqualifiedVarObj(cx))
|
||||
return nullptr;
|
||||
if (!global->setDelegate(cx))
|
||||
return nullptr;
|
||||
|
||||
|
@ -579,12 +579,10 @@ NonSyntacticVariablesObject::create(JSContext* cx, Handle<GlobalObject*> global)
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
MOZ_ASSERT(obj->isUnqualifiedVarObj());
|
||||
if (!obj->setQualifiedVarObj(cx))
|
||||
return nullptr;
|
||||
|
||||
if (!obj->setUnqualifiedVarObj(cx))
|
||||
return nullptr;
|
||||
|
||||
obj->setEnclosingScope(global);
|
||||
return obj;
|
||||
}
|
||||
|
@ -353,16 +353,10 @@ class BaseShape : public gc::TenuredCell
|
||||
UNCACHEABLE_PROTO = 0x800,
|
||||
IMMUTABLE_PROTOTYPE = 0x1000,
|
||||
|
||||
// These two flags control which scope a new variables ends up on in the
|
||||
// scope chain. If the variable is "qualified" (i.e., if it was defined
|
||||
// using var, let, or const) then it ends up on the lowest scope in the
|
||||
// chain that has the QUALIFIED_VAROBJ flag set. If it's "unqualified"
|
||||
// (i.e., if it was introduced without any var, let, or const, which
|
||||
// incidentally is an error in strict mode) then it goes on the lowest
|
||||
// scope in the chain with the UNQUALIFIED_VAROBJ flag set (which is
|
||||
// typically the global).
|
||||
// See JSObject::isQualifiedVarObj().
|
||||
QUALIFIED_VAROBJ = 0x2000,
|
||||
UNQUALIFIED_VAROBJ = 0x4000,
|
||||
|
||||
// 0x4000 is unused.
|
||||
|
||||
// For a function used as an interpreted constructor, whether a 'new'
|
||||
// type had constructor information cleared.
|
||||
|
Loading…
Reference in New Issue
Block a user