mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 883630 - Watch for lazy functions when iterating inline Ion frames, clean up methods for accessing function scripts.
This commit is contained in:
parent
aebd81764e
commit
9a5791cb47
@ -5316,7 +5316,10 @@ GenerateEntries(ModuleCompiler &m)
|
||||
static inline bool
|
||||
TryEnablingIon(JSContext *cx, AsmJSModule::ExitDatum *exitDatum, int32_t argc, Value *argv)
|
||||
{
|
||||
JSScript *script = exitDatum->fun->maybeNonLazyScript();
|
||||
if (!exitDatum->fun->hasScript())
|
||||
return true;
|
||||
|
||||
JSScript *script = exitDatum->fun->nonLazyScript();
|
||||
if (!script)
|
||||
return true;
|
||||
|
||||
|
@ -1267,7 +1267,12 @@ InlineFrameIteratorMaybeGC<allowGC>::findNextFrame()
|
||||
si_.nextFrame();
|
||||
|
||||
callee_ = funval.toObject().toFunction();
|
||||
script_ = callee_->nonLazyScript();
|
||||
|
||||
// Inlined functions may be clones that still point to the lazy script
|
||||
// for the executed script, if they are clones. The actual script
|
||||
// exists though, just make sure the function points to it.
|
||||
script_ = callee_->getExistingScript();
|
||||
|
||||
pc_ = script_->code + si_.pcOffset();
|
||||
}
|
||||
|
||||
|
@ -634,8 +634,8 @@ CreateLazyScriptsForCompartment(JSContext *cx)
|
||||
if (obj->compartment() == cx->compartment() && obj->isFunction()) {
|
||||
JSFunction *fun = obj->toFunction();
|
||||
if (fun->isInterpretedLazy()) {
|
||||
LazyScript *lazy = fun->lazyScript();
|
||||
if (lazy->sourceObject() && !lazy->maybeScript()) {
|
||||
LazyScript *lazy = fun->lazyScriptOrNull();
|
||||
if (lazy && lazy->sourceObject() && !lazy->maybeScript()) {
|
||||
if (!lazyFunctions.append(fun))
|
||||
return false;
|
||||
}
|
||||
@ -666,8 +666,11 @@ CreateLazyScriptsForCompartment(JSContext *cx)
|
||||
JSObject *obj = i.get<JSObject>();
|
||||
if (obj->compartment() == cx->compartment() && obj->isFunction()) {
|
||||
JSFunction *fun = obj->toFunction();
|
||||
if (fun->isInterpretedLazy() && fun->lazyScript()->maybeScript())
|
||||
JS_ALWAYS_TRUE(fun->getOrCreateScript(cx));
|
||||
if (fun->isInterpretedLazy()) {
|
||||
LazyScript *lazy = fun->lazyScriptOrNull();
|
||||
if (lazy && lazy->maybeScript())
|
||||
fun->getExistingScript();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,6 +208,27 @@ class JSFunction : public JSObject
|
||||
|
||||
static bool createScriptForLazilyInterpretedFunction(JSContext *cx, js::HandleFunction fun);
|
||||
|
||||
// Function Scripts
|
||||
//
|
||||
// Interpreted functions may either have an explicit JSScript (hasScript())
|
||||
// or be lazy with sufficient information to construct the JSScript if
|
||||
// necessary (isInterpretedLazy()).
|
||||
//
|
||||
// A lazy function will have a LazyScript if the function came from parsed
|
||||
// source, or NULL if the function is a clone of a self hosted function.
|
||||
//
|
||||
// There are several methods to get the script of an interpreted function:
|
||||
//
|
||||
// - For all interpreted functions, getOrCreateScript() will get the
|
||||
// JSScript, delazifying the function if necessary. This is the safest to
|
||||
// use, but has extra checks, requires a cx and may trigger a GC.
|
||||
//
|
||||
// - For functions which may have a LazyScript but whose JSScript is known
|
||||
// to exist, getExistingScript() will get the script and delazify the
|
||||
// function if necessary.
|
||||
//
|
||||
// - For functions known to have a JSScript, nonLazyScript() will get it.
|
||||
|
||||
JSScript *getOrCreateScript(JSContext *cx) {
|
||||
JS_ASSERT(isInterpreted());
|
||||
JS_ASSERT(cx);
|
||||
@ -222,35 +243,18 @@ class JSFunction : public JSObject
|
||||
return u.i.s.script_;
|
||||
}
|
||||
|
||||
static bool maybeGetOrCreateScript(JSContext *cx, js::HandleFunction fun,
|
||||
js::MutableHandle<JSScript*> script)
|
||||
{
|
||||
if (fun->isNative()) {
|
||||
script.set(NULL);
|
||||
return true;
|
||||
}
|
||||
script.set(fun->getOrCreateScript(cx));
|
||||
return fun->hasScript();
|
||||
}
|
||||
inline JSScript *getExistingScript();
|
||||
|
||||
JSScript *nonLazyScript() const {
|
||||
JS_ASSERT(hasScript());
|
||||
return JS::HandleScript::fromMarkedLocation(&u.i.s.script_);
|
||||
}
|
||||
|
||||
JSScript *maybeNonLazyScript() const {
|
||||
return hasScript() ? nonLazyScript() : NULL;
|
||||
}
|
||||
|
||||
js::HeapPtrScript &mutableScript() {
|
||||
JS_ASSERT(isInterpreted());
|
||||
return *(js::HeapPtrScript *)&u.i.s.script_;
|
||||
}
|
||||
|
||||
// A lazily interpreted function will have an associated LazyScript if the
|
||||
// script has not yet been parsed. For functions whose scripts are lazily
|
||||
// cloned from self hosted code, there is no LazyScript.
|
||||
|
||||
js::LazyScript *lazyScript() const {
|
||||
JS_ASSERT(isInterpretedLazy() && u.i.s.lazy_);
|
||||
return u.i.s.lazy_;
|
||||
|
@ -223,6 +223,25 @@ CloneFunctionObjectIfNotSingleton(JSContext *cx, HandleFunction fun, HandleObjec
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
inline JSScript *
|
||||
JSFunction::getExistingScript()
|
||||
{
|
||||
JS_ASSERT(isInterpreted());
|
||||
if (isInterpretedLazy()) {
|
||||
js::LazyScript *lazy = lazyScript();
|
||||
JS_ASSERT(lazy->maybeScript());
|
||||
|
||||
if (zone()->needsBarrier())
|
||||
js::LazyScript::writeBarrierPre(lazy);
|
||||
|
||||
flags &= ~INTERPRETED_LAZY;
|
||||
flags |= INTERPRETED;
|
||||
initScript(lazy->maybeScript());
|
||||
}
|
||||
JS_ASSERT(hasScript());
|
||||
return u.i.s.script_;
|
||||
}
|
||||
|
||||
inline void
|
||||
JSFunction::setScript(JSScript *script_)
|
||||
{
|
||||
|
@ -1444,11 +1444,15 @@ ValueToScript(JSContext *cx, jsval v, JSFunction **funp = NULL)
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
RootedScript script(cx);
|
||||
JSFunction::maybeGetOrCreateScript(cx, fun, &script);
|
||||
if (!script)
|
||||
|
||||
if (!fun->isInterpreted()) {
|
||||
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_SCRIPTS_ONLY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JSScript *script = fun->getOrCreateScript(cx);
|
||||
if (!script)
|
||||
return NULL;
|
||||
|
||||
if (fun && funp)
|
||||
*funp = fun;
|
||||
@ -1891,13 +1895,14 @@ DisassembleScript(JSContext *cx, HandleScript script, HandleFunction fun, bool l
|
||||
JSObject *obj = objects->vector[i];
|
||||
if (obj->isFunction()) {
|
||||
Sprint(sp, "\n");
|
||||
RootedFunction f(cx, obj->toFunction());
|
||||
RootedScript script(cx);
|
||||
JSFunction::maybeGetOrCreateScript(cx, f, &script);
|
||||
if (!script)
|
||||
RootedFunction fun(cx, obj->toFunction());
|
||||
if (fun->isInterpreted()) {
|
||||
RootedScript script(cx, fun->getOrCreateScript(cx));
|
||||
if (!script || !DisassembleScript(cx, script, fun, lines, recursive, sp))
|
||||
return false;
|
||||
} else {
|
||||
Sprint(sp, "[native code]\n");
|
||||
else if (!DisassembleScript(cx, script, fun, lines, recursive, sp))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user