6 // Morph a slim wrapper into an XPCWN by generating a cross-compartment wrapper
7 // for it (we Morph in WrapperFactory::PrepareForWrapping).
8 function makeNonSlim(elem
) {
9 window
.parent
.someCCW
= elem
;
10 delete window
.parent
.someCCW
;
15 // Get a slim wrapper for |form|. This lives in scope 1.
16 var form
= document
.getElementById('myform');
18 // The gist here is that we want to create an input element that isn't part
19 // of a form, so that its PreCreate hook will cause it to be parented to the
20 // document. However, there are several considerations that make this more
23 // First, the crashtest becomes non-deterministics if we morph |form| before
24 // getting to scope 3 (as explained below). This means that we can't trigger
25 // the PreCreate hook for |input|, because that will call WrapNativeParent
26 // (Well... No, it won't: there is no WrapNativeParent, but there are also no
27 // more pre-create hooks, slimwrappers, parenting to the form, or any of the
28 // stuff this test is trying to test.)
29 // on the form, which will end up making a cross-compartment wrapper, which
30 // will morph form. But this puts us in a pickle, because appendChild returns
31 // the apppended child, which will trigger the PreCreate hook in
32 // NativeInterface2JSObject. So we do this little hack where we append a buch
33 // of dummy <div> children to the form, and use replaceChild (which returns
34 // the replacer, not the replacee) to stick the input elements as children of
37 // Second, the crashtest can also be non-deterministics if the final call to
38 // MoveWrappers iterates over the hashtable in such a way that it fixes up
39 // the Document before it fixes up the Input. If so, the Input will become
40 // orphaned, and we'll detect it and fix things up at the top of MoveWrapper.
41 // Since we can't control the hashtable ordering here, we just make 100 input
42 // elements, to make it a near-certainty (statistically) that we'll encounter
43 // one of them during iteration before encountering the Document.
45 // With all this, this testcase deterministically crashes on my machine. Whew!
47 // Create an input element. This isn't part of a form right now, so it gets
48 // parented to the document.
50 var placeHolders
= [];
51 for (var i
= 0; i
< 100; ++i
) {
52 var dummyDiv
= form
.appendChild(document
.createElement('div'));
53 var input
= document
.createElement('input');
56 placeHolders
.push(dummyDiv
);
59 // Blow away the document, forcing a transplan of all the XPCWNs in scope. This
60 // will transplant |input|, but |form| stays in the old scope (since it's slim).
64 // Now we're in scope 2. Associate |input| with |form| so that the next call to
65 // PreCreate will parent |input| to |form| rather than the document. But make
66 // sure to do it with replaceChild, rather than appendChild, so that we don't
67 // end up triggering the PreCreate hook for |form| in scope 2, which would make
68 // make it non-slim. If we didn't, the ensuing call to MoveWrappers might find
69 // |form| before |input| while iterating over the hashtable. If so, |form|
70 // would be rescued as an orphan and everything would be fixed before getting to // |input|.
71 for (var i
= 0; i
< inputs
.length
; ++i
)
72 form
.replaceChild(inputs
[i
], placeHolders
[i
]);
74 // Blow away the document a second time. This should cause the crash in
82 <form id=
"myform"></form>