text: //-------------------------------------------------------------------------------------------------------
  // Copyright (C) Microsoft. All rights reserved.
  // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  //-------------------------------------------------------------------------------------------------------
  
  //Note: see function  ArraySpliceHelper of JavascriptArray.cpp
  
  if (this.WScript && this.WScript.LoadScriptFile) { // Check for running in ch
      this.WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
  }
  
  var restorePropertyFromDescriptor = function (obj, prop, desc) {
      if (typeof desc == 'undefined') {
          delete obj[prop];
      } else {
          Object.defineProperty(obj, prop, desc);
      }
  }
  
  var tests = [
      {
          name: "OS7342663:OOB writes using type confusion in InternalCopyArrayElements",
          body: function ()
          {
              function test() {
                  var arr1 = [0xdead, 0xbabe, 0xdead, 0xbabe];
  
                  class MyArray extends Uint32Array { }
                  Object.defineProperty(MyArray, Symbol.species, { value: function() { return arr1; } });
  
                  var float_val = 0xdaddeadbabe * 4.9406564584124654E-324;
                  var test = [float_val, float_val, float_val, float_val];
                  test.length = 0x1000;
                  test.__proto__ = new MyArray(0);
  
                  var res = Array.prototype.slice.apply(test, []);  // OOB write
                  assert.areEqual(0x1000, res.length, "res.length == 0x1000");
                  assert.areEqual(float_val, res[0], "res[0] == float_val");
                  assert.areEqual(float_val, res[1], "res[1] == float_val");
                  assert.areEqual(float_val, res[2], "res[2] == float_val");
                  assert.areEqual(float_val, res[3], "res[3] == float_val");
                  assert.areEqual(undefined, res[4], "res[4] == float_val");
                  assert.areEqual(undefined, res[0xfff], "res[0xfff] == undefined");
              }
              test();
              test();
              test();
          }
      },
      {
          name: "OS7342689:OOB writes using type confusion in InternalFillFromPrototypes",
          body: function ()
          {
              function test() {
                  var arr1 = [0xdead, 0xbabe, 0xdead, 0xbabe, 0xdead, 0xbabe, 0xdead, 0xbabe, 0xdead, 0xbabe, 0xdead,
                  0xbabe, 0xdead, 0xbabe, 0xdead, 0xbabe, 0xdead, 0xbabe, 0xdead, 0xbabe, 0xdead, 0xbabe, 0xdead, 0xbabe,
                  0xdead, 0xbabe, 0xdead, 0xbabe, 0xdead, 0xbabe, 0xdead, 0xbabe, 0xdead, 0xbabe, 0xdead, 0xbabe, 0xdead,
                  0xbabe, 0xdead, 0xbabe, 0xdead, 0xbabe, 0xdead, 0xbabe, 0xdead, 0xbabe, 0xdead, 0xbabe];
  
                  class MyArray extends Uint32Array { }
                  Object.defineProperty(MyArray, Symbol.species, { value: function() { return arr1; } });
  
                  var float_val = 0xdaddeadbabe * 4.9406564584124654E-324;
                  var test = [{}];
                  delete test[0];
                  test.length = 0x1000;
                  var src = [float_val, float_val, float_val, float_val, float_val, float_val, float_val, float_val,
                  float_val, float_val, float_val, float_val, float_val, float_val, float_val, float_val, float_val, float_val,
                  float_val, float_val, float_val, float_val, float_val, float_val, float_val, float_val, float_val, float_val,
                  float_val, float_val, float_val, float_val, float_val, float_val, float_val, float_val, float_val, float_val,
                  float_val, float_val, float_val, float_val, float_val, float_val, float_val, float_val, float_val, float_val, float_val];
                  test.__proto__ = src;
                  test.__proto__.__proto__ = new MyArray(0);
  
                 //this will write 0xfffc0daddeadbabe to [arr1] + 0x1D8
                  var res = Array.prototype.slice.apply(test, [])
                  assert.areEqual(0x1000, res.length, "res.length == 0x1000");
                  assert.areEqual(float_val, res[0], "res[0] == float_val");
                  assert.areEqual(float_val, res[1], "res[1] == float_val");
                  assert.areEqual(float_val, res[2], "res[2] == float_val");
                  assert.areEqual(float_val, res[src.length-1], "res[src.length-1] == float_val");
                  assert.areEqual(undefined, res[src.length], "res[src] == undefined");
                  assert.areEqual(undefined, res[0xfff], "res[0xfff] == undefined");
              }
              test();
              test();
              test();
          }
      },
      {
          name: "OS7307908:type confusion in Array.prototype.slice",
          body: function ()
          {
              function test() {
                  var arr = [1, 2]
                  var desc = Object.getOwnPropertyDescriptor(arr.constructor, Symbol.species);
  
                 //Our species function will get called during chakra!Js::JavascriptArray::SliceHelper<unsigned int>
                  Object.defineProperty(
                      arr.constructor,
                      Symbol.species,
                      {
                          value : function()
                          {
                             //change 'arr' from TypeIds_NativeIntArray to TypeIds_Array
                              arr[0] = WScript;
  
                             //return a TypeIds_NativeIntArray so we can read back out the 64 bit pointer as two 32bit ints.
                              return [];
                          }
                      }
                  );
  
                 //trigger the bug and retrieve a TypeIds_NativeIntArray array containing a pointer.
                  var brr = arr.slice();
  
                  assert.areEqual(2, brr.length, "brr.length == 2");
                  assert.areEqual(WScript, brr[0], "brr[0] == WScript");
                  assert.areEqual(2, brr[1], "brr[0] == WScript");
  
                  restorePropertyFromDescriptor(arr.constructor, Symbol.species, desc);
              }
              test();
              test();
              test();
          }
      },
      {
          name: "OS7342791:type confusion in Array.from",
          body: function ()
          {
              function test() {
                  var arr1 = [0xdead, 0xbabe, 0xdead, 0xbabe, 0xdead, 0xbabe, 0xdead, 0xbabe];
  
                  var float_val = 0xdaddeadbabe * 4.9406564584124654E-324;
                  var test = [float_val, float_val, float_val, float_val];
                  delete test[0];
                  delete test[1];
                  delete test[2];
  
                  var res = Array.from.apply(function(){return arr1}, [test]);
                  assert.areEqual(4, res.length, "res.length == 4");
                  assert.areEqual(undefined, res[0], "res[0] == undefined");
                  assert.areEqual(undefined, res[1], "res[1] == undefined");
                  assert.areEqual(undefined, res[2], "res[2] == undefined");
                  assert.areEqual(float_val, res[3], "res[3] == float_val");
  
                  assert.areEqual(['1','2','3'], Array.from.apply(()=>new Array(), ["123"]), "Array.from on iterable");
                  assert.areEqual([1,2,3], Array.from.apply(()=>new Array(), [{"0":1, "1":2, "2":3, "length":3}]), "Array.from on non-iterable");
              }
              test();
              test();
              test();
          }
      },
      {
          name: "OS7342844:type confusion in Array.of",
          body: function ()
          {
              function test() {
                  var brr = Array.of.call(()=>[ 1, 2, 3, 4 ],
                      WScript, // supply 2 copies of target so the brr array will have a length of 2 and we can read the 64bit pointer.
                      WScript
                  );
  
                  assert.areEqual(2, brr.length, "brr.length == 2");
                  assert.areEqual(WScript, brr[0], "res[0] == WScript");
                  assert.areEqual(WScript, brr[1], "res[1] == WScript");
                  assert.areEqual(undefined, brr[2], "res[2] == undefined");
                  assert.areEqual(undefined, brr[3], "res[3] == undefined");
              }
              test();
              test();
              test();
          }
      },
      {
          name: "OS7342907:type confusion in Array.prototype.map",
          body: function ()
          {
              function test() {
                  var arr = [ 1, 2 ];
                  var desc = Object.getOwnPropertyDescriptor(arr.constructor, Symbol.species);
  
                  Object.defineProperty(
                      arr.constructor,
                      Symbol.species,
                      {
                          value : function()
                          {
                              return [];
                          }
                      }
                  );
  
                 //The value returned from our callback is directly set into the array whose type we create via the species.
                  var brr = arr.map( function( v )
                      {
                          if( v == 1 )
                              return WScript;
                      }
                  );
  
                  assert.areEqual(2, brr.length, "brr.length == 2");
                  assert.areEqual(WScript, brr[0], "brr[0] == WScript");
                  assert.areEqual(undefined, brr[1], "brr[1] == undefined");
  
                  restorePropertyFromDescriptor(arr.constructor, Symbol.species, desc);
              }
              test();
              test();
              test();
          }
      },
      {
          name: "type confusion in Array.prototype.map with Proxy",
          body: function ()
          {
              function test() {
                  var d = [1,2,3];
                  class dummy {
                      constructor() {
                          return d;
                      }
                  }
  
                  var handler = {
                      get: function(target, name) {
                          if(name == "length") {
                              return 0x100;
                          }
  
                          return {[Symbol.species] : dummy};
                      },
  
                      has: function(target, name) {
                          return true;
                      }
                  };
  
                  var p = new Proxy([], handler);
                  var a = new Array(1,2,3);
  
                  function test(){
                      return 0x777777777777;
                  }
  
                  var o = a.map.call(p, test);
                  assert.areEqual(Array(0x100).fill(0x777777777777), o);
              }
              test();
              test();
              test();
          }
      },
      {
          name: "OS7342965:type confusion in Array.prototype.splice",
          body: function ()
          {
              function test() {
                 //create a TypeIds_Array holding two 64 bit values (The same amount of space for four 32 bit values).
                  var arr = [ WScript, WScript ];
                  var desc = Object.getOwnPropertyDescriptor(arr.constructor, Symbol.species);
  
                 //Our species function will get called during chakra!Js::JavascriptArray::EntrySplice
                  Object.defineProperty(
                      arr.constructor,
                      Symbol.species,
                      {
                          value : function()
                          {
                             //return a TypeIds_NativeIntArray so we can read back out a 64 bit pointer as two 32bit ints.
                              return [ 1, 2, 3, 4 ];
                          }
                      }
                  );
  
                 //trigger the bug and retrieve a TypeIds_NativeIntArray array containing a pointer. The helper
                 //method ArraySegmentSpliceHelper<Var> will directly copy over the TypeIds_Array segment data
                 //into the TypeIds_NativeIntArray segment.
                  var brr = arr.splice( 0, 2 );
  
                  assert.areEqual(2, brr.length, "brr.length == 2");
                  assert.areEqual(WScript, brr[0], "brr[0] == WScript");
                  assert.areEqual(WScript, brr[1], "brr[1] == WScript");
                  assert.areEqual(undefined, brr[2], "brr[2] == undefined");
                  assert.areEqual(undefined, brr[3], "brr[3] == undefined");
  
                  restorePropertyFromDescriptor(arr.constructor, Symbol.species, desc);
              }
              test();
              test();
              test();
          }
      },
      {
          name: "type confusion in Array.prototype.join",
          body: function ()
          {
              function test() {
                  var a = [0, 1, 2, 3];
                  var b = [];
                  delete a[0];
                  Object.setPrototypeOf(a, b)
                  Object.defineProperty(b, "0",
                      {
                          get: function() {
                                  a[2] = "abc";
                                  return -1;
                              }
                      });
  
                  assert.areEqual("-1,1,abc,3", a.join());
              }
              test();
              test();
              test();
          }
      },
      {
          name: "type confusion in Array.prototype.indexOf",
          body: function ()
          {
              function test() {
                  var float_val = 0xdaddeadbabe * 4.9406564584124654E-324;
                  var a = [0, 1, 2, 3];
                  var b = [];
                  delete a[1];
                  Object.setPrototypeOf(a, b);
                  Object.defineProperty(b, "1",
                      {
                          get: function() {
                                  a[2] = float_val; //"abc";
                                  return -1;
                              }
                      });
  
                  assert.areEqual(3, a.indexOf(3));
              }
              test();
              test();
              test();
          }
      },
      {
          name: "type confusion in Array.prototype.lastIndexOf",
          body: function ()
          {
              function test() {
                  var float_val = 0xdaddeadbabe * 4.9406564584124654E-324;
                  var a = [3, 2, 1, 0];
                  var b = [];
                  delete a[3];
                  Object.setPrototypeOf(a, b);
                  Object.defineProperty(b, "3",
                      {
                          get: function() {
                                  a[1] = float_val; //"abc";
                                  return -1;
                              }
                      });
  
                  assert.areEqual(0, a.lastIndexOf(3));
              }
              test();
              test();
              test();
          }
      },
      {
          name: "type confusion in Function.prototype.apply",
          body: function ()
          {
              function test() {
                  var t = [1,2,3];
  
                  function f(){
                      var h = [];
                      var a = [...arguments]
  
                      for(item in a){
                          var n = new Number(a[item]);
  
                          if( n < 0) {
                              n = n + 0x100000000;
                          }
  
                          h.push(n.toString(16));
                      }
  
                      return h;
                  }
  
                  var q = f;
  
                  t.length = 20;
                  var o = {};
                  Object.defineProperty(o, '3', {
                      get: function() {
                          var ta = [];
                          ta.fill.call(t, "natalie");
                          return 5;
                      }
                  });
  
                  t.__proto__ = o;
  
                  var j = [];
                  assert.areEqual("1,2,3,5,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN", f.apply(null, t).toString());
              }
              test();
              test();
              test();
          }
      },
      {
          name: "[MSRC34910] type confusion in Array.prototype.filter",
          body: function ()
          {
              function mappingFn(elem, index, arr) {
                  arr[1] = 'hello';
                  return true;
              }
  
              var arr = [1, 2, 3];
  
              var desc = Object.getOwnPropertyDescriptor(arr.constructor, Symbol.species);
              Object.defineProperty(arr.constructor, Symbol.species, { get : function () {  return function() { return [22, 33]; } } } );
              var b = Array.prototype.filter.call(arr, mappingFn);
              assert.areEqual('hello', b[1]);
  
              restorePropertyFromDescriptor(arr.constructor, Symbol.species, desc);
          }
      },
      {
          name: "[MSRC35046] heap overflow in Array.prototype.splice",
          body: function ()
          {
              var a = [];
              var o = {};
  
              Object.defineProperty(o, 'constructor', {
                  get: function() {
                      a.length = 0xfffffffe;
                      [].fill.call(a, 0, 0xfffff000, 0xfffffffe);
                      return Array;
                  }});
  
              a.__proto__ = o;
              var q = new Array(50).fill(1.1);
  
              var b = [].splice.call(a, 0, 0, ...q);
              assert.areEqual(50, a.length);
              assert.areEqual(q, a);
          }
      },
      {
          name: "[MSRC35086] type confusion in FillFromPrototypes",
          body: function ()
          {
              var a = new Array(0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x12121212);
  
              var handler = {
                      getPrototypeOf: function(target, name) {
                          return a;
                      }
                  };
  
              var p = new Proxy([], handler);
              var b = [{}, [], "abc"];
  
              b.__proto__ = p;
              b.length = 4;
              var c = [[],"abc",1145324612];
  
              a.shift.call(b);
              assert.areEqual(3, b.length);
              assert.areEqual([], b[0]);
              assert.areEqual("abc", b[1]);
              assert.areEqual(undefined, b[2]);
          }
      },
      {
          name: "[MSRC35272] type confusion in JSON.parse",
          body: function ()
          {
              var a = 1;
              var once = false;
              function f(){
                  if(!once){
                      a = new Array(2)
                      this[2] = a;
                  }
                  once = true;
                  return 0x41414141;
              }
  
              var r = JSON.parse("[1111, 22222, 333333]", f);
              assert.areEqual(0x41414141, r);
          }
      },
      {
          name: "[MSRC35383] type confusion in Array.prototype.concat",
          body: function ()
          {
              var n = [];
              for (var i = 0; i < 0x10; i++)
                  n.push([0x11111111, 0x11111111, 0, 0x11111111,0x11111111, 0x11111111, 0, 0x11111111,0x11111111, 0x11111111, 0, 0x11111111,0x11111111,0x11111111, 0, 0x11111111,0x11111111 ,1 ,2 ,3 ,4]);
  
              class fake extends Object {
                  static get [Symbol.species]() { return function() {  return n[3]; }; };
              }
  
              var f = function(a){ return a; }
  
              var x = ["dabao", 0, 0, 0x41414141];
              var y = new Proxy(x, {
                  get: function(t, p, r) {
                      return (p == "constructor") ? fake : x[p];
                  }
              });
  
              assert.areEqual(x, Array.prototype.concat.apply(y));
          }
      },
      {
          name: "[MSRC35389] type confusion in Array.prototype.splice",
          body: function ()
          {
              var arr = [0x41424344,0x41424344,0x41424344,0x41424344,0x41424344,0x41424344,0x41424344,0x41424344,0x41424344]
              class fake extends Object {
                  static get [Symbol.species]() { return function() {
                      return arr;
                  }; };
              }
  
              var x = [0, 2, 0, 0x41414141];
              var y = new Proxy(x, {
                  get: function(t, p, r) {
                      return (p == "constructor") ? fake : x[p];
                  }
              });
  
              Array.prototype.splice.apply(y);
              assert.areEqual(x, y);
          }
      },
      {
          name: "[MSRC35389 variation] type confusion in Array.prototype.slice",
          body: function ()
          {
              var arr = [0x41424344,0x41424344,0x41424344,0x41424344,0x41424344,0x41424344,0x41424344,0x41424344,0x41424344];
  
              class fake extends Object {
                  static get [Symbol.species]() { return function() {
                      return arr;
                  }; };
              }
  
              var x = [0, 2, 0, 0x41414141];
              var y = new Proxy(x, {
                  get: function(t, p, r) {
                      if (p == "constructor")
                          return fake
                      if (p == 'length');
                          return 1;
                      return x[p];
                  },
                  has: function() {
                      return false;
                  }
              });
  
              assert.areEqual([0x41424344], Array.prototype.slice.call(y));
          }
      },
      {
          name: "[MSRC34994,35226] heap overflow in Array.prototype.reverse",
          body: function ()
          {
              var count = 0;
              arr = new Array(100);
              var desc = Object.getOwnPropertyDescriptor(Array.prototype, 1);
              Object.defineProperty(Array.prototype, 1, { get: function () {
                      count++;
                      if (count == 1) {
                          arr.push(null);
                      }
                  }});
  
              arr.reverse();
              restorePropertyFromDescriptor(Array.prototype, 1, desc);
              assert.areEqual(101, arr.length);
          }
      },
      {
          name: "Heap overread when splice mutates the array when executing slice",
          body: function ()
          {
              var getterCalled = false;
              var a = [1, 2];
              for (var i = 0; i < 100 * 1024; i++) {
                  a.push(i);
              }
              delete a[0]; // Make a missing item
              var protoObj = [11];
              Object.defineProperty(protoObj, '0', {
                  get : function () {
                      getterCalled = true;
                      Object.setPrototypeOf(a, Array.prototype);
                      a.splice(0); // head seg is now length=0
                      return 42;
                  },
                  configurable : true
              });
              Object.setPrototypeOf(a, protoObj);
              var b = a.slice();
              assert.isTrue(getterCalled);
              assert.areEqual(0, a.length, "Getter will splice the array to zero length");
              assert.areEqual(100 * 1024 + 2, b.length, "Validating that slice will return the full array even though splice is deleting the whole array");
          }
      },
      {
          name: "reverse : Mutating the array's length from prototype should not be reversed",
          body: function ()
          {
              var getterCalled = false;
              var a = [11, 22, 33];
              a.length = 5;
              var o = {};
              Object.defineProperty(o, '4' , {
                  get: function () {
                      getterCalled = true;
                      a[5] = 55;
                      a[6] = 66;
                      a.length = 8; // Changing the length of the array while we are in the reverse call
                      return 44 ;
                  }, set : function(ab) {}, configurable : true
              });
              
              a.__proto__ = o;
              var r = [].reverse.call(a);
              a.__proto__ = Array.prototype;
              assert.isTrue(getterCalled);
              assert.areEqual(55, a[5], 'a[5] is added during the reverse call, so it should not be reversed');
              assert.areEqual(66, a[6], 'a[6] is added during the reverse call, so it should not be reversed');
              assert.areEqual(undefined, a[7], 'a[7] is undefined the reverse call, so it should remain undefined');
          }
      },
      {
          name: "reverse : Making current array an ES5Array from prototype should be part of reverse",
          body: function ()
          {
              var getterCalled = false;
              var a = [0, 1, 2, 3, 4];
              a.length = 6;
              var o = {};
              Object.defineProperty(o, '5' , {
                  get: function () {
                      Object.defineProperty(a, '1', {
                          get : function() { getterCalled = true; return 11;},
                          set : function(ab) { }, configurable : true });
                      return 51 ;
                  }, set : function(ab) { }, configurable : true
              });
              a.__proto__ = o;
  
              [].reverse.call(a);
              a.__proto__ = Array.prototype;
              assert.isTrue(getterCalled);
              assert.areEqual([51,11,3,2,11,], a, 'getter on a[1] is called when introduced during prototype walk on reverse call');
          }
      },
      {
          name: "reverse : Proxy object in the prototype chain",
          body: function ()
          {
              var getTrapCalled = false;
              var arr = [11, 22, 33];
              arr.length = 4;
              var handler = {
                  has : function() {
                      return true;
                  },
                  get : function(target, name) {
                      if (name == "3") {
                          getTrapCalled = true;
                          arr[4] = 55;
                          arr[5] = 66;
                          arr.length = 6;
                          return 44;
                      }
                  }
              };
              var p = new Proxy({}, handler);
              arr.__proto__ = p;
              [].reverse.call(arr);
              arr.__proto__ = Array.prototype;
              assert.isTrue(getTrapCalled);
              assert.areEqual([44,33,22,11,55,66], arr, 'Properties added in get trap should not part of the reverse logic (55 and 66 are remained on same position)');
          }
      },
      {
          name: "shift : Mutating the array's length from prototype should not be part of shift",
          body: function ()
          {
              var getterCalled = false;
              var a = [11, 22, 33];
              a.length = 5;
              var o = {};
              
              Object.defineProperty(o, '4' , {
                  get: function () {
                      getterCalled = true;
                      a[5] = 55;
                      a[6] = 66;
                      a.length = 8;
                      return 44;
                  }, set : function(ab) {}, configurable : true
              });
              a.__proto__ = o;
              var r = [].shift.call(a);
              a.__proto__ = Array.prototype;
              assert.isTrue(getterCalled);
              assert.areEqual([22,33,,44], a, 'a[5] and a[6] is not part of the shift');
              assert.areEqual(4, a.length, 'We started with length == 5 and shift will decrement by 1');
          }
      },
      {
          name: "unshift : Mutating the array's length from prototype should not be part of unshift",
          body: function ()
          {
              var getterCalled = false;
              var arr = [11, 22, 33];
              var obj = {};
              arr.length = 4;
              Object.defineProperty(obj, "3", {get : function() { 
                  getterCalled = true;
                  arr[4] = 66;
                  arr[5] = 77;
                  return 55;
                  }, set : function(bb) {}, configurable: true});
              arr.__proto__ = obj;
              var obj1 = [].unshift.call(arr, 201, 202);
              arr.__proto__ = Array.prototype;
              
              assert.isTrue(getterCalled);
              assert.areEqual([201,202,11,,33,55], arr, '66 and 77 were added after length deduced so they are not part of unshift');
              assert.areEqual(6, arr.length, 'we begin length == 4 and unshift adds 2 more');
          }
      },
      {
          name: "sort : Mutating the array's length from prototype should not be part of actual sort",
          body: function ()
          {
              var getterCalled = false;
              var arr = [33, 11, 22];
              var obj = {};
              arr.length = 4;
              Object.defineProperty(obj, "3", {get : function() { 
                  getterCalled = true;
                  arr[4] = 77;
                  arr[5] = 16;
                  return 101;
              }, set : function(bb) {}, configurable: true});
              arr.__proto__ = obj;
              var obj1 = [].sort.call(arr);
              arr.__proto__ = Array.prototype;
  
              assert.isTrue(getterCalled);
              assert.areEqual([101,11,22,,77,16], arr, '77 and 16 are not part of the sort so they are not sorted');
              assert.areEqual(6, arr.length);
          }
      },
      {
          name: "unshift : setter on the prototype will be called even though it is outside of current array's length",
          body: function ()
          {
              var setterCalled = false;
              var protoObj = {};
              var arr = [1, 2];
              // setter is put on the index outside of the current's array length (which is 2).
              Object.defineProperty(protoObj, 3, {get : function() {  }, set : function(a) { setterCalled = true;} });
              arr.__proto__ = protoObj;
              Array.prototype.unshift.call(arr, 101, 104);
              assert.isTrue(setterCalled);
          }
      },
      {
          name: "slice : the method slice should get property from prototype which is a proxy",
          body: function ()
          {
              var arr = [];
              arr.length = 100;
              arr.__proto__ = new Proxy([16], {} );
  
              arr.push(1);
              var ret = arr.slice(0, 10);
              assert.areEqual(16, ret[0]);
          }
      },
      {
          name: "splice : the method splice should get property from prototype which is a proxy",
          body: function ()
          {
              var v1 = [];
              v1.length = 20;
              var hasCalled = 0;
              v1.__proto__ = new Proxy([222], {has : function() { hasCalled++;} });
              v1.push(1);
              assert.areEqual(222, v1[0]);
              var ret  = v1.splice(0, 10);
              assert.areEqual(20, hasCalled);
          }
      },
  ];
  testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });
  