Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 5a338b9

Browse files
committed
Bug 858582 - Prevent callsite cloning of callsite clones. (r=bhackett)
1 parent eaf7d57 commit 5a338b9

2 files changed

Lines changed: 71 additions & 4 deletions

File tree

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// |jit-test| error: TypeError
2+
// Don't crash.
3+
gczeal(2);
4+
evaluate("\
5+
function assertAlmostEq(v1, v2) {\
6+
print(\"v2 = \" + v2);\
7+
print(\"% diff = \" + percent);\
8+
function assertStructuralEq(e1, e2) {}\
9+
function assertEqParallelArrayArray(a, b) {\
10+
try {} catch (e) {\
11+
print(\"...in index \", i, \" of \", l);\
12+
}\
13+
}\
14+
function assertEqArray(a, b) {\
15+
try {} catch (e) {}\
16+
}\
17+
function assertEqParallelArray(a, b) {\
18+
var shape = a.shape;\
19+
function bump(indices) {\
20+
var iv = shape.map(function () { return 0; });\
21+
print(\"...in indices \", iv, \" of \", shape);\
22+
}\
23+
} while (bump(iv));\
24+
}\
25+
function assertParallelArrayModesEq(modes, acc, opFunction, cmpFunction) {\
26+
modes.forEach(function (mode) {\
27+
var result = opFunction({ mode: mode, expect: \"success\" });\
28+
cmpFunction(acc, result);\
29+
});\
30+
function assertParallelArrayModesCommute(modes, opFunction) {\
31+
var acc = opFunction({ mode: modes[0], expect: \"success\" });\
32+
}\
33+
function comparePerformance(opts) {\
34+
print(\"Option \" + opts[i].name + \" took \" + diff + \"ms\");\
35+
print(\"Option \" + opts[i].name + \" relative to option \" +\
36+
opts[0].name + \": \" + (rel|0) + \"%\");\
37+
}\
38+
}\
39+
function compareAgainstArray(jsarray, opname, func, cmpFunction) {\
40+
var expected = jsarray[opname].apply(jsarray, [func]);\
41+
var parray = new ParallelArray(jsarray);\
42+
assertParallelArrayModesEq([\"seq\", \"par\", \"par\"], expected, function(m) {\
43+
var result = parray[opname].apply(parray, [func, m]);\
44+
}, cmpFunction);\
45+
}\
46+
function testFilter(jsarray, func, cmpFunction) {}\
47+
", { noScriptRval : true });
48+
compareAgainstArray([
49+
"a",
50+
"b",
51+
('captures: 1,1; RegExp.leftContext: ""; RegExp.rightContext: "123456"'),
52+
"d", "e",
53+
"f", "g", "h",
54+
"i", "j", "k", "l",
55+
"m", "n", "o", "p",
56+
"q", "r", "s", "t",
57+
(.6 ), "v", "w", "x", "y", "z"
58+
], "map", function(e) {
59+
return e != "u"
60+
&&
61+
(function b ( ) {
62+
} )
63+
!= "x";
64+
});

js/src/jscntxt.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -274,16 +274,19 @@ js::CloneFunctionAtCallsite(JSContext *cx, HandleFunction fun, HandleScript scri
274274
return p->value;
275275

276276
RootedObject parent(cx, fun->environment());
277-
RootedFunction clone(cx, CloneFunctionObject(cx, fun, parent,
278-
JSFunction::ExtendedFinalizeKind));
277+
RootedFunction clone(cx, CloneFunctionObject(cx, fun, parent));
279278
if (!clone)
280279
return NULL;
281280

282-
// Store a link back to the original for function.caller.
281+
/*
282+
* Store a link back to the original for function.caller and avoid cloning
283+
* clones.
284+
*/
285+
clone->nonLazyScript()->shouldCloneAtCallsite = false;
283286
clone->nonLazyScript()->isCallsiteClone = true;
284287
clone->nonLazyScript()->setOriginalFunctionObject(fun);
285288

286-
// Recalculate the hash if script or fun have been moved.
289+
/* Recalculate the hash if script or fun have been moved. */
287290
if (key.script != script && key.original != fun) {
288291
key.script = script;
289292
key.original = fun;

0 commit comments

Comments
 (0)