guix-devel/gnu/packages/patches/icecat-CVE-2016-1930-pt09.p...

190 lines
7.1 KiB
Diff

Copied from: https://hg.mozilla.org/releases/mozilla-esr38/rev/f31d643afd41
Security advisory: https://www.mozilla.org/en-US/security/advisories/mfsa2016-01/
Mozilla Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1233925
# HG changeset patch
# User Jan de Mooij <jdemooij@mozilla.com>
# Date 1452110721 -3600
# Node ID f31d643afd4159b5422ae5aebcbbea0a088e018e
# Parent 4444e94a99cb9b00c0351cc8bf5459739cc036a5
Bug 1233925 - Treat functions with rest more like functions with lazy arguments. r=nbp a=ritu
diff --git a/js/src/jit/BacktrackingAllocator.cpp b/js/src/jit/BacktrackingAllocator.cpp
--- a/js/src/jit/BacktrackingAllocator.cpp
+++ b/js/src/jit/BacktrackingAllocator.cpp
@@ -201,20 +201,19 @@ BacktrackingAllocator::tryGroupRegisters
// constructor calling convention.
if (IsThisSlotDefinition(reg0->def()) || IsThisSlotDefinition(reg1->def())) {
if (*reg0->def()->output() != *reg1->def()->output())
return true;
}
// Registers which might spill to the frame's argument slots can only be
// grouped with other such registers if the frame might access those
- // arguments through a lazy arguments object.
+ // arguments through a lazy arguments object or rest parameter.
if (IsArgumentSlotDefinition(reg0->def()) || IsArgumentSlotDefinition(reg1->def())) {
- JSScript* script = graph.mir().entryBlock()->info().script();
- if (script && script->argumentsAliasesFormals()) {
+ if (graph.mir().entryBlock()->info().mayReadFrameArgsDirectly()) {
if (*reg0->def()->output() != *reg1->def()->output())
return true;
}
}
VirtualRegisterGroup* group0 = reg0->group(), *group1 = reg1->group();
if (!group0 && group1)
diff --git a/js/src/jit/CompileInfo.h b/js/src/jit/CompileInfo.h
--- a/js/src/jit/CompileInfo.h
+++ b/js/src/jit/CompileInfo.h
@@ -194,16 +194,17 @@ enum AnalysisMode {
class CompileInfo
{
public:
CompileInfo(JSScript* script, JSFunction* fun, jsbytecode* osrPc, bool constructing,
AnalysisMode analysisMode, bool scriptNeedsArgsObj,
InlineScriptTree* inlineScriptTree)
: script_(script), fun_(fun), osrPc_(osrPc), constructing_(constructing),
analysisMode_(analysisMode), scriptNeedsArgsObj_(scriptNeedsArgsObj),
+ mayReadFrameArgsDirectly_(script->mayReadFrameArgsDirectly()),
inlineScriptTree_(inlineScriptTree)
{
MOZ_ASSERT_IF(osrPc, JSOp(*osrPc) == JSOP_LOOPENTRY);
// The function here can flow in from anywhere so look up the canonical
// function to ensure that we do not try to embed a nursery pointer in
// jit-code. Precisely because it can flow in from anywhere, it's not
// guaranteed to be non-lazy. Hence, don't access its script!
@@ -222,17 +223,17 @@ class CompileInfo
fixedLexicalBegin_ = script->fixedLexicalBegin();
nstack_ = script->nslots() - script->nfixed();
nslots_ = nimplicit_ + nargs_ + nlocals_ + nstack_;
}
explicit CompileInfo(unsigned nlocals)
: script_(nullptr), fun_(nullptr), osrPc_(nullptr), osrStaticScope_(nullptr),
constructing_(false), analysisMode_(Analysis_None), scriptNeedsArgsObj_(false),
- inlineScriptTree_(nullptr)
+ mayReadFrameArgsDirectly_(false), inlineScriptTree_(nullptr)
{
nimplicit_ = 0;
nargs_ = 0;
nbodyfixed_ = 0;
nlocals_ = nlocals;
nstack_ = 1; /* For FunctionCompiler::pushPhiInput/popPhiOutput */
nslots_ = nlocals_ + nstack_;
fixedLexicalBegin_ = nlocals;
@@ -539,16 +540,20 @@ class CompileInfo
return false;
if (needsArgsObj() && isObservableArgumentSlot(slot))
return false;
return true;
}
+ bool mayReadFrameArgsDirectly() const {
+ return mayReadFrameArgsDirectly_;
+ }
+
private:
unsigned nimplicit_;
unsigned nargs_;
unsigned nbodyfixed_;
unsigned nlocals_;
unsigned nstack_;
unsigned nslots_;
unsigned fixedLexicalBegin_;
@@ -559,15 +564,17 @@ class CompileInfo
bool constructing_;
AnalysisMode analysisMode_;
// Whether a script needs an arguments object is unstable over compilation
// since the arguments optimization could be marked as failed on the main
// thread, so cache a value here and use it throughout for consistency.
bool scriptNeedsArgsObj_;
+ bool mayReadFrameArgsDirectly_;
+
InlineScriptTree* inlineScriptTree_;
};
} // namespace jit
} // namespace js
#endif /* jit_CompileInfo_h */
diff --git a/js/src/jit/JitFrames.cpp b/js/src/jit/JitFrames.cpp
--- a/js/src/jit/JitFrames.cpp
+++ b/js/src/jit/JitFrames.cpp
@@ -1002,17 +1002,17 @@ MarkThisAndArguments(JSTracer* trc, JitF
// formal arguments is taken care of by the frame's safepoint/snapshot,
// except when the script's lazy arguments object aliases those formals,
// in which case we mark them as well.
size_t nargs = layout->numActualArgs();
size_t nformals = 0;
if (CalleeTokenIsFunction(layout->calleeToken())) {
JSFunction* fun = CalleeTokenToFunction(layout->calleeToken());
- nformals = fun->nonLazyScript()->argumentsAliasesFormals() ? 0 : fun->nargs();
+ nformals = fun->nonLazyScript()->mayReadFrameArgsDirectly() ? 0 : fun->nargs();
}
Value* argv = layout->argv();
// Trace |this|.
gc::MarkValueRoot(trc, argv, "ion-thisv");
// Trace actual arguments beyond the formals. Note + 1 for thisv.
diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -3894,16 +3894,22 @@ JSScript::hasLoops()
JSTryNote* tnlimit = tn + trynotes()->length;
for (; tn < tnlimit; tn++) {
if (tn->kind == JSTRY_FOR_IN || tn->kind == JSTRY_LOOP)
return true;
}
return false;
}
+bool
+JSScript::mayReadFrameArgsDirectly()
+{
+ return argumentsHasVarBinding() || (function_ && function_->hasRest());
+}
+
static inline void
LazyScriptHash(uint32_t lineno, uint32_t column, uint32_t begin, uint32_t end,
HashNumber hashes[3])
{
HashNumber hash = lineno;
hash = RotateLeft(hash, 4) ^ column;
hash = RotateLeft(hash, 4) ^ begin;
hash = RotateLeft(hash, 4) ^ end;
diff --git a/js/src/jsscript.h b/js/src/jsscript.h
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -1397,16 +1397,20 @@ class JSScript : public js::gc::TenuredC
}
inline void setFunction(JSFunction* fun);
/*
* De-lazifies the canonical function. Must be called before entering code
* that expects the function to be non-lazy.
*/
inline void ensureNonLazyCanonicalFunction(JSContext* cx);
+ // Returns true if the script may read formal arguments on the stack
+ // directly, via lazy arguments or a rest parameter.
+ bool mayReadFrameArgsDirectly();
+
JSFlatString* sourceData(JSContext* cx);
static bool loadSource(JSContext* cx, js::ScriptSource* ss, bool* worked);
void setSourceObject(JSObject* object);
JSObject* sourceObject() const {
return sourceObject_;
}