mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 749371 - Remove now-unnecessary JS_ClearScope defense (r=bhackett)
This commit is contained in:
parent
3595a4cdb6
commit
872a0e6b97
@ -4193,7 +4193,7 @@ struct JSClass {
|
||||
* with the following flags. Failure to use JSCLASS_GLOBAL_FLAGS was
|
||||
* prevously allowed, but is now an ES5 violation and thus unsupported.
|
||||
*/
|
||||
#define JSCLASS_GLOBAL_SLOT_COUNT (JSProto_LIMIT * 3 + 24)
|
||||
#define JSCLASS_GLOBAL_SLOT_COUNT (JSProto_LIMIT * 3 + 23)
|
||||
#define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \
|
||||
(JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n)))
|
||||
#define JSCLASS_GLOBAL_FLAGS \
|
||||
|
@ -1135,7 +1135,7 @@ UnknownPropertyAccess(JSScript *script, Type type)
|
||||
{
|
||||
return type.isUnknown()
|
||||
|| type.isAnyObject()
|
||||
|| (!type.isObject() && !script->hasGlobal());
|
||||
|| (!type.isObject() && !script->compileAndGo);
|
||||
}
|
||||
|
||||
template <PropertyAccessKind access>
|
||||
@ -1448,7 +1448,7 @@ TypeConstraintTransformThis::newType(JSContext *cx, TypeSet *source, Type type)
|
||||
* Note: if |this| is null or undefined, the pushed value is the outer window. We
|
||||
* can't use script->getGlobalType() here because it refers to the inner window.
|
||||
*/
|
||||
if (!script->hasGlobal() ||
|
||||
if (!script->compileAndGo ||
|
||||
type.isPrimitive(JSVAL_TYPE_NULL) ||
|
||||
type.isPrimitive(JSVAL_TYPE_UNDEFINED)) {
|
||||
target->addType(cx, Type::UnknownType());
|
||||
@ -2141,7 +2141,7 @@ types::UseNewTypeForInitializer(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
bool
|
||||
types::ArrayPrototypeHasIndexedProperty(JSContext *cx, JSScript *script)
|
||||
{
|
||||
if (!cx->typeInferenceEnabled() || !script->hasGlobal())
|
||||
if (!cx->typeInferenceEnabled() || !script->compileAndGo)
|
||||
return true;
|
||||
|
||||
JSObject *proto = script->global().getOrCreateArrayPrototype(cx);
|
||||
@ -3320,7 +3320,7 @@ CheckNextTest(jsbytecode *pc)
|
||||
static inline TypeObject *
|
||||
GetInitializerType(JSContext *cx, JSScript *script, jsbytecode *pc)
|
||||
{
|
||||
if (!script->hasGlobal())
|
||||
if (!script->compileAndGo)
|
||||
return NULL;
|
||||
|
||||
JSOp op = JSOp(*pc);
|
||||
@ -3503,7 +3503,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset,
|
||||
break;
|
||||
|
||||
case JSOP_REGEXP:
|
||||
if (script->hasGlobal()) {
|
||||
if (script->compileAndGo) {
|
||||
TypeObject *object = TypeScript::StandardType(cx, script, JSProto_RegExp);
|
||||
if (!object)
|
||||
return false;
|
||||
@ -3715,7 +3715,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset,
|
||||
|
||||
case JSOP_REST: {
|
||||
StackTypeSet *types = script->analysis()->bytecodeTypes(pc);
|
||||
if (script->hasGlobal()) {
|
||||
if (script->compileAndGo) {
|
||||
TypeObject *rest = TypeScript::InitObject(cx, script, pc, JSProto_Array);
|
||||
if (!rest)
|
||||
return false;
|
||||
@ -3850,7 +3850,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset,
|
||||
res = &pushed[0];
|
||||
|
||||
if (res) {
|
||||
if (script->hasGlobal() && !UseNewTypeForClone(obj->toFunction()))
|
||||
if (script->compileAndGo && !UseNewTypeForClone(obj->toFunction()))
|
||||
res->addType(cx, Type::ObjectType(obj));
|
||||
else
|
||||
res->addType(cx, Type::UnknownType());
|
||||
@ -3916,7 +3916,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset,
|
||||
}
|
||||
|
||||
TypeObject *initializer = GetInitializerType(cx, script, pc);
|
||||
if (script->hasGlobal()) {
|
||||
if (script->compileAndGo) {
|
||||
if (!initializer)
|
||||
return false;
|
||||
types->addType(cx, Type::ObjectType(initializer));
|
||||
@ -4100,7 +4100,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset,
|
||||
|
||||
case JSOP_GENERATOR:
|
||||
if (script->function()) {
|
||||
if (script->hasGlobal()) {
|
||||
if (script->compileAndGo) {
|
||||
JSObject *proto = script->global().getOrCreateGeneratorPrototype(cx);
|
||||
if (!proto)
|
||||
return false;
|
||||
@ -4153,7 +4153,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset,
|
||||
|
||||
case JSOP_CALLEE: {
|
||||
JSFunction *fun = script->function();
|
||||
if (script->hasGlobal() && !UseNewTypeForClone(fun))
|
||||
if (script->compileAndGo && !UseNewTypeForClone(fun))
|
||||
pushed[0].addType(cx, Type::ObjectType(fun));
|
||||
else
|
||||
pushed[0].addType(cx, Type::UnknownType());
|
||||
@ -4179,17 +4179,6 @@ ScriptAnalysis::analyzeTypes(JSContext *cx)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Refuse to analyze the types in a script which is compileAndGo but is
|
||||
* running against a global with a cleared scope. Per GlobalObject::clear,
|
||||
* we won't be running anymore compileAndGo code against the global
|
||||
* (moreover, after clearing our analysis results will be wrong for the
|
||||
* script and trying to reanalyze here can cause reentrance problems if we
|
||||
* try to reinitialize standard classes that were cleared).
|
||||
*/
|
||||
if (script->hasClearedGlobal())
|
||||
return;
|
||||
|
||||
if (!ranSSA()) {
|
||||
analyzeSSA(cx);
|
||||
if (failed())
|
||||
@ -4414,9 +4403,6 @@ AnalyzeNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun, JSO
|
||||
return false;
|
||||
}
|
||||
|
||||
if (script->hasClearedGlobal())
|
||||
return false;
|
||||
|
||||
ScriptAnalysis *analysis = script->analysis();
|
||||
|
||||
/*
|
||||
|
@ -683,7 +683,7 @@ TypeScript::InitObject(JSContext *cx, JSScript *script, jsbytecode *pc, JSProtoK
|
||||
/* :XXX: Limit script->length so we don't need to check the offset up front? */
|
||||
uint32_t offset = pc - script->code;
|
||||
|
||||
if (!cx->typeInferenceEnabled() || !script->hasGlobal() || offset >= AllocationSiteKey::OFFSET_LIMIT)
|
||||
if (!cx->typeInferenceEnabled() || !script->compileAndGo || offset >= AllocationSiteKey::OFFSET_LIMIT)
|
||||
return GetTypeNewObject(cx, kind);
|
||||
|
||||
AllocationSiteKey key;
|
||||
|
@ -270,14 +270,6 @@ js::RunScript(JSContext *cx, JSScript *script, StackFrame *fp)
|
||||
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
|
||||
/* FIXME: Once bug 470510 is fixed, make this an assert. */
|
||||
if (script->compileAndGo) {
|
||||
if (fp->global().isCleared()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CLEARED_SCOPE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
struct CheckStackBalance {
|
||||
JSContext *cx;
|
||||
@ -2424,16 +2416,9 @@ BEGIN_CASE(JSOP_FUNCALL)
|
||||
goto error;
|
||||
|
||||
InitialFrameFlags initial = construct ? INITIAL_CONSTRUCT : INITIAL_NONE;
|
||||
|
||||
bool newType = cx->typeInferenceEnabled() && UseNewType(cx, script, regs.pc);
|
||||
|
||||
JSScript *newScript = fun->script();
|
||||
|
||||
if (newScript->compileAndGo && newScript->hasClearedGlobal()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CLEARED_SCOPE);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!cx->stack.pushInlineFrame(cx, regs, args, *fun, newScript, initial))
|
||||
goto error;
|
||||
|
||||
|
@ -580,9 +580,6 @@ struct JSScript : public js::gc::Cell
|
||||
|
||||
inline void clearPropertyReadTypes();
|
||||
|
||||
inline bool hasGlobal() const;
|
||||
inline bool hasClearedGlobal() const;
|
||||
|
||||
inline js::GlobalObject &global() const;
|
||||
|
||||
/* See StaticScopeIter comment. */
|
||||
|
@ -120,17 +120,6 @@ JSScript::isEmpty() const
|
||||
return JSOp(*pc) == JSOP_STOP;
|
||||
}
|
||||
|
||||
inline bool
|
||||
JSScript::hasGlobal() const
|
||||
{
|
||||
/*
|
||||
* Make sure that we don't try to query information about global objects
|
||||
* which have had their scopes cleared. compileAndGo code should not run
|
||||
* anymore against such globals.
|
||||
*/
|
||||
return compileAndGo && !global().isCleared();
|
||||
}
|
||||
|
||||
inline js::GlobalObject &
|
||||
JSScript::global() const
|
||||
{
|
||||
@ -141,13 +130,6 @@ JSScript::global() const
|
||||
return *compartment()->maybeGlobal();
|
||||
}
|
||||
|
||||
inline bool
|
||||
JSScript::hasClearedGlobal() const
|
||||
{
|
||||
JS_ASSERT(types);
|
||||
return global().isCleared();
|
||||
}
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
inline bool
|
||||
JSScript::ensureHasMJITInfo(JSContext *cx)
|
||||
|
@ -59,7 +59,7 @@ mjit::Compiler::Compiler(JSContext *cx, JSScript *outerScript,
|
||||
isConstructing(isConstructing),
|
||||
outerChunk(outerJIT()->chunkDescriptor(chunkIndex)),
|
||||
ssa(cx, outerScript),
|
||||
globalObj(cx, outerScript->hasGlobal() ? &outerScript->global() : NULL),
|
||||
globalObj(cx, outerScript->compileAndGo ? &outerScript->global() : NULL),
|
||||
globalSlots(globalObj ? globalObj->getRawSlots() : NULL),
|
||||
sps(&cx->runtime->spsProfiler, &script, &PC),
|
||||
masm(&sps),
|
||||
@ -134,11 +134,6 @@ mjit::Compiler::compile()
|
||||
CompileStatus
|
||||
mjit::Compiler::checkAnalysis(HandleScript script)
|
||||
{
|
||||
if (script->hasClearedGlobal()) {
|
||||
JaegerSpew(JSpew_Abort, "script has a cleared global\n");
|
||||
return Compile_Abort;
|
||||
}
|
||||
|
||||
if (!script->ensureRanAnalysis(cx))
|
||||
return Compile_Error;
|
||||
|
||||
@ -193,7 +188,7 @@ mjit::Compiler::scanInlineCalls(uint32_t index, uint32_t depth)
|
||||
ScriptAnalysis *analysis = script->analysis();
|
||||
|
||||
/* Don't inline from functions which could have a non-global scope object. */
|
||||
if (!script->hasGlobal() ||
|
||||
if (!script->compileAndGo ||
|
||||
&script->global() != globalObj ||
|
||||
(script->function() && script->function()->getParent() != globalObj) ||
|
||||
(script->function() && script->function()->isHeavyweight()) ||
|
||||
|
@ -881,7 +881,7 @@ class GetPropCompiler : public PICStubCompiler
|
||||
|
||||
LookupStatus generateStringPropertyStub()
|
||||
{
|
||||
if (!f.fp()->script()->hasGlobal())
|
||||
if (!f.fp()->script()->compileAndGo)
|
||||
return disable("String.prototype without compile-and-go global");
|
||||
|
||||
RecompilationMonitor monitor(f.cx);
|
||||
|
@ -2092,7 +2092,7 @@ class Debugger::ScriptQuery {
|
||||
for (CompartmentSet::Range r = compartments.all(); !r.empty(); r.popFront()) {
|
||||
for (gc::CellIter i(r.front(), gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
|
||||
JSScript *script = i.get<JSScript>();
|
||||
if (script->hasGlobal() && !script->isForEval()) {
|
||||
if (script->compileAndGo && !script->isForEval()) {
|
||||
if (!consider(script, &script->global(), vector))
|
||||
return false;
|
||||
}
|
||||
|
@ -10,18 +10,6 @@
|
||||
|
||||
namespace js {
|
||||
|
||||
inline void
|
||||
GlobalObject::setFlags(int32_t flags)
|
||||
{
|
||||
setSlot(FLAGS, Int32Value(flags));
|
||||
}
|
||||
|
||||
inline void
|
||||
GlobalObject::initFlags(int32_t flags)
|
||||
{
|
||||
initSlot(FLAGS, Int32Value(flags));
|
||||
}
|
||||
|
||||
inline void
|
||||
GlobalObject::setDetailsForKey(JSProtoKey key, JSObject *ctor, JSObject *proto)
|
||||
{
|
||||
|
@ -488,9 +488,8 @@ GlobalObject::create(JSContext *cx, Class *clasp)
|
||||
JSObject *res = RegExpStatics::create(cx, global);
|
||||
if (!res)
|
||||
return NULL;
|
||||
global->initSlot(REGEXP_STATICS, ObjectValue(*res));
|
||||
global->initFlags(0);
|
||||
|
||||
global->initSlot(REGEXP_STATICS, ObjectValue(*res));
|
||||
return global;
|
||||
}
|
||||
|
||||
@ -533,60 +532,6 @@ GlobalObject::initStandardClasses(JSContext *cx, Handle<GlobalObject*> global)
|
||||
GlobalObject::initSetIteratorProto(cx, global);
|
||||
}
|
||||
|
||||
void
|
||||
GlobalObject::clear(JSContext *cx)
|
||||
{
|
||||
for (int key = JSProto_Null; key < JSProto_LIMIT * 3; key++)
|
||||
setSlot(key, UndefinedValue());
|
||||
|
||||
/* Clear regexp statics. */
|
||||
getRegExpStatics()->clear();
|
||||
|
||||
/* Clear the runtime-codegen-enabled cache. */
|
||||
setSlot(RUNTIME_CODEGEN_ENABLED, UndefinedValue());
|
||||
|
||||
/*
|
||||
* Clear all slots storing values in case throwing trying to execute a
|
||||
* script for this global must reinitialize standard classes. See
|
||||
* bug 470150.
|
||||
*/
|
||||
setSlot(BOOLEAN_VALUEOF, UndefinedValue());
|
||||
setSlot(EVAL, UndefinedValue());
|
||||
setSlot(CREATE_DATAVIEW_FOR_THIS, UndefinedValue());
|
||||
setSlot(THROWTYPEERROR, UndefinedValue());
|
||||
setSlot(INTRINSICS, UndefinedValue());
|
||||
setSlot(PROTO_GETTER, UndefinedValue());
|
||||
|
||||
/*
|
||||
* Mark global as cleared. If we try to execute any compile-and-go
|
||||
* scripts from here on, we will throw.
|
||||
*/
|
||||
int32_t flags = getSlot(FLAGS).toInt32();
|
||||
flags |= FLAGS_CLEARED;
|
||||
setSlot(FLAGS, Int32Value(flags));
|
||||
|
||||
/*
|
||||
* Reset the new object cache in the compartment, which assumes that
|
||||
* prototypes cached on the global object are immutable.
|
||||
*/
|
||||
cx->runtime->newObjectCache.purge();
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
/*
|
||||
* Destroy compiled code for any scripts parented to this global. Call ICs
|
||||
* can directly call scripts which have associated JIT code, and do so
|
||||
* without checking whether the script's global has been cleared.
|
||||
*/
|
||||
for (gc::CellIter i(cx->compartment, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
|
||||
JSScript *script = i.get<JSScript>();
|
||||
if (script->compileAndGo && script->hasMJITInfo() && script->hasClearedGlobal()) {
|
||||
mjit::Recompiler::clearStackReferences(cx->runtime->defaultFreeOp(), script);
|
||||
mjit::ReleaseScriptCode(cx->runtime->defaultFreeOp(), script);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
GlobalObject::isRuntimeCodeGenEnabled(JSContext *cx)
|
||||
{
|
||||
|
@ -98,8 +98,7 @@ class GlobalObject : public JSObject
|
||||
static const unsigned REGEXP_STATICS = SET_ITERATOR_PROTO + 1;
|
||||
static const unsigned FUNCTION_NS = REGEXP_STATICS + 1;
|
||||
static const unsigned RUNTIME_CODEGEN_ENABLED = FUNCTION_NS + 1;
|
||||
static const unsigned FLAGS = RUNTIME_CODEGEN_ENABLED + 1;
|
||||
static const unsigned DEBUGGERS = FLAGS + 1;
|
||||
static const unsigned DEBUGGERS = RUNTIME_CODEGEN_ENABLED + 1;
|
||||
static const unsigned INTRINSICS = DEBUGGERS + 1;
|
||||
|
||||
/* Total reserved-slot count for global objects. */
|
||||
@ -114,11 +113,6 @@ class GlobalObject : public JSObject
|
||||
JS_STATIC_ASSERT(JSCLASS_GLOBAL_SLOT_COUNT == RESERVED_SLOTS);
|
||||
}
|
||||
|
||||
static const int32_t FLAGS_CLEARED = 0x1;
|
||||
|
||||
inline void setFlags(int32_t flags);
|
||||
inline void initFlags(int32_t flags);
|
||||
|
||||
friend JSObject *
|
||||
::js_InitObjectClass(JSContext *cx, JSObject *obj);
|
||||
friend JSObject *
|
||||
@ -413,12 +407,6 @@ class GlobalObject : public JSObject
|
||||
return getSlot(PROTO_GETTER);
|
||||
}
|
||||
|
||||
void clear(JSContext *cx);
|
||||
|
||||
bool isCleared() const {
|
||||
return getSlot(FLAGS).toInt32() & FLAGS_CLEARED;
|
||||
}
|
||||
|
||||
bool isRuntimeCodeGenEnabled(JSContext *cx);
|
||||
|
||||
const Value &getOriginalEval() const {
|
||||
|
Loading…
Reference in New Issue
Block a user