зеркало из https://github.com/mozilla/pjs.git
Bug 728086 - Poison the stack when not in use (r=luke)
This commit is contained in:
Родитель
d85e772fe4
Коммит
db42dc186d
|
@ -0,0 +1,65 @@
|
|||
var expected = '';
|
||||
function TestCase(n, d, e, a) {}
|
||||
function reportFailure (msg) {}
|
||||
function toPrinted(value) {
|
||||
value = value.replace(/\\\n/g, 'NL')
|
||||
.replace(/[^\x20-\x7E]+/g, escapeString);
|
||||
}
|
||||
function escapeString (str) {}
|
||||
function reportCompare (expected, actual, description) {
|
||||
var expected_t = typeof expected;
|
||||
var actual_t = typeof actual;
|
||||
var output = "";
|
||||
var testcase = new TestCase("unknown-test-name", description, expected, actual);
|
||||
reportFailure (description + " : " + output);
|
||||
}
|
||||
function enterFunc (funcName)
|
||||
callStack.push(funcName);
|
||||
try {
|
||||
reportCompare(expectCompile, actualCompile,
|
||||
summary + ': compile actual');
|
||||
} catch(ex) { }
|
||||
var lfcode = new Array();
|
||||
lfcode.push("gczeal(2);\
|
||||
enterFunc ('test');\
|
||||
");
|
||||
lfcode.push("{}");
|
||||
lfcode.push("noexist.js");
|
||||
lfcode.push("var BUGNUMBER = 305064;\
|
||||
var summary = 'Tests the trim, trimRight and trimLeft methods';\
|
||||
var trimMethods = ['trim', 'trimLeft', 'trimRight'];\
|
||||
var whitespace = [\
|
||||
{s : '\\u0009', t : 'HORIZONTAL TAB'},\
|
||||
{s : '\\u200A', t : 'HAIR SPACE'},\
|
||||
];\
|
||||
for (var j = 0; j < trimMethods.length; ++j)\
|
||||
var method = trimMethods[j];\
|
||||
reportCompare(true, true, 'Test skipped. String.prototype.' + method + ' is not supported');\
|
||||
str = '';\
|
||||
for (var i = 0; i < whitespace.length; ++i) {\
|
||||
var v = whitespace[i].s;\
|
||||
var t = (summary)[i].t;\
|
||||
v = v + v + v;\
|
||||
print('Test ' + method + ' with with leading whitespace. : ' + t);\
|
||||
actual = str[method]();\
|
||||
reportCompare(expected, actual, t + ':' + '\"' + toPrinted(str) + '\".' + method + '()');\
|
||||
str = v + 'a' + v;\
|
||||
}\
|
||||
");
|
||||
while (true) {
|
||||
var file = lfcode.shift(); if (file == undefined) { break; }
|
||||
if (file == "evaluate") {
|
||||
} else {
|
||||
loadFile(file);
|
||||
}
|
||||
}
|
||||
function loadFile(lfVarx) {
|
||||
try {
|
||||
if (lfVarx.substr(-3) == ".js") {
|
||||
switch (lfRunTypeId) {
|
||||
}
|
||||
} else {
|
||||
eval(lfVarx);
|
||||
}
|
||||
} catch (lfVare) { }
|
||||
}
|
|
@ -792,9 +792,9 @@ CrossCompartmentWrapper::nativeCall(JSContext *cx, JSObject *wrapper, Class *cla
|
|||
if (!Wrapper::nativeCall(cx, wrapper, clasp, native, dstArgs))
|
||||
return false;
|
||||
|
||||
srcArgs.rval() = dstArgs.rval();
|
||||
dstArgs.pop();
|
||||
call.leave();
|
||||
srcArgs.rval() = dstArgs.rval();
|
||||
return call.origin->wrap(cx, &srcArgs.rval());
|
||||
}
|
||||
|
||||
|
|
|
@ -413,6 +413,7 @@ StackSpace::init()
|
|||
trustedEnd_ = base_ + CAPACITY_VALS;
|
||||
conservativeEnd_ = defaultEnd_ = trustedEnd_ - BUFFER_VALS;
|
||||
#endif
|
||||
Debug_SetValueRangeToCrashOnTouch(base_, trustedEnd_);
|
||||
assertInvariants();
|
||||
return true;
|
||||
}
|
||||
|
@ -736,6 +737,8 @@ ContextStack::pushInvokeArgs(JSContext *cx, uintN argc, InvokeArgsGuard *iag)
|
|||
if (!firstUnused)
|
||||
return false;
|
||||
|
||||
MakeRangeGCSafe(firstUnused, argc);
|
||||
|
||||
ImplicitCast<CallArgs>(*iag) = CallArgsFromVp(argc, firstUnused);
|
||||
|
||||
seg_->pushCall(*iag);
|
||||
|
@ -751,9 +754,19 @@ ContextStack::popInvokeArgs(const InvokeArgsGuard &iag)
|
|||
JS_ASSERT(onTop());
|
||||
JS_ASSERT(space().firstUnused() == seg_->calls().end());
|
||||
|
||||
Value *oldend = seg_->end();
|
||||
Value *oldbeg;
|
||||
|
||||
seg_->popCall();
|
||||
if (iag.pushedSeg_)
|
||||
if (iag.pushedSeg_) {
|
||||
oldbeg = reinterpret_cast<Value *>(seg_);
|
||||
popSegment();
|
||||
} else {
|
||||
oldbeg = seg_->end();
|
||||
}
|
||||
|
||||
if (seg_)
|
||||
Debug_SetValueRangeToCrashOnTouch(oldbeg, oldend);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -866,9 +879,19 @@ ContextStack::popFrame(const FrameGuard &fg)
|
|||
if (fg.regs_.fp()->isNonEvalFunctionFrame())
|
||||
fg.regs_.fp()->functionEpilogue();
|
||||
|
||||
Value *oldend = seg_->end();
|
||||
Value *oldbeg;
|
||||
|
||||
seg_->popRegs(fg.prevRegs_);
|
||||
if (fg.pushedSeg_)
|
||||
if (fg.pushedSeg_) {
|
||||
oldbeg = reinterpret_cast<Value *>(seg_);
|
||||
popSegment();
|
||||
} else {
|
||||
oldbeg = seg_->end();
|
||||
}
|
||||
|
||||
if (seg_)
|
||||
Debug_SetValueRangeToCrashOnTouch(oldbeg, oldend);
|
||||
|
||||
/*
|
||||
* NB: this code can call out and observe the stack (e.g., through GC), so
|
||||
|
|
|
@ -95,10 +95,10 @@ namespace detail {
|
|||
*
|
||||
* SpiderMonkey uses a per-thread stack to store the activation records,
|
||||
* parameters, locals, and expression temporaries for the stack of actively
|
||||
* executing scripts, functions and generators. The per-thread stack is owned
|
||||
* by the StackSpace object stored in the thread's ThreadData.
|
||||
* executing scripts, functions and generators. The stack is owned by the
|
||||
* StackSpace object stored in the runtime.
|
||||
*
|
||||
* The per-thread stack is subdivided into contiguous segments of memory which
|
||||
* The stack is subdivided into contiguous segments of memory which
|
||||
* have a memory layout invariant that allows fixed offsets to be used for stack
|
||||
* access (by jit code) as well as fast call/return. This memory layout is
|
||||
* encapsulated by a set of types that describe different regions of memory.
|
||||
|
|
Загрузка…
Ссылка в новой задаче