mirror of
				https://github.com/tc39/test262.git
				synced 2025-11-04 05:33:50 +01:00 
			
		
		
		
	sourceRevisionAtLastExport: 33f2fb0e53d135f0ee17cfccd9d993eb2a6f47de targetRevisionAtLastExport: 31340cbd9add103f586d501b0c3354b7b182abc0
		
			
				
	
	
		
			306 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			306 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// Copyright 2012 the V8 project authors. All rights reserved.
 | 
						|
// Redistribution and use in source and binary forms, with or without
 | 
						|
// modification, are permitted provided that the following conditions are
 | 
						|
// met:
 | 
						|
//
 | 
						|
//     * Redistributions of source code must retain the above copyright
 | 
						|
//       notice, this list of conditions and the following disclaimer.
 | 
						|
//     * Redistributions in binary form must reproduce the above
 | 
						|
//       copyright notice, this list of conditions and the following
 | 
						|
//       disclaimer in the documentation and/or other materials provided
 | 
						|
//       with the distribution.
 | 
						|
//     * Neither the name of Google Inc. nor the names of its
 | 
						|
//       contributors may be used to endorse or promote products derived
 | 
						|
//       from this software without specific prior written permission.
 | 
						|
//
 | 
						|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
						|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
						|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
						|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
						|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
						|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
						|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
						|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
						|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
						|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
						|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						|
 | 
						|
// Flags: --allow-natives-syntax
 | 
						|
 | 
						|
// Test for-in support in Crankshaft.  For simplicity this tests assumes certain
 | 
						|
// fixed iteration order for properties and will have to be adjusted if V8
 | 
						|
// stops following insertion order.
 | 
						|
 | 
						|
 | 
						|
function a(t) {
 | 
						|
  var result = [];
 | 
						|
  for (var i in t) {
 | 
						|
    result.push([i, t[i]]);
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
// Check that we correctly deoptimize on map check.
 | 
						|
function b(t) {
 | 
						|
  var result = [];
 | 
						|
  for (var i in t) {
 | 
						|
    result.push([i, t[i]]);
 | 
						|
    delete t[i];
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
// Check that we correctly deoptimize during preparation step.
 | 
						|
function c(t) {
 | 
						|
  var result = [];
 | 
						|
  for (var i in t) {
 | 
						|
    result.push([i, t[i]]);
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
// Check that we deoptimize to the place after side effect in the right state.
 | 
						|
function d(t) {
 | 
						|
  var result = [];
 | 
						|
  var o;
 | 
						|
  for (var i in (o = t())) {
 | 
						|
    result.push([i, o[i]]);
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
// Check that we correctly deoptimize on map check inserted for fused load.
 | 
						|
function e(t) {
 | 
						|
  var result = [];
 | 
						|
  for (var i in t) {
 | 
						|
    delete t[i];
 | 
						|
    t[i] = i;
 | 
						|
    result.push([i, t[i]]);
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
// Nested for-in loops.
 | 
						|
function f(t) {
 | 
						|
  var result = [];
 | 
						|
  for (var i in t) {
 | 
						|
    for (var j in t) {
 | 
						|
      result.push([i, j, t[i], t[j]]);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
// Deoptimization from the inner for-in loop.
 | 
						|
function g(t) {
 | 
						|
  var result = [];
 | 
						|
  for (var i in t) {
 | 
						|
    for (var j in t) {
 | 
						|
      result.push([i, j, t[i], t[j]]);
 | 
						|
      var v = t[i];
 | 
						|
      delete t[i];
 | 
						|
      t[i] = v;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Break from the inner for-in loop.
 | 
						|
function h(t, deopt) {
 | 
						|
  var result = [];
 | 
						|
  for (var i in t) {
 | 
						|
    for (var j in t) {
 | 
						|
      result.push([i, j, t[i], t[j]]);
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  deopt.deopt;
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
// Continue in the inner loop.
 | 
						|
function j(t, deopt) {
 | 
						|
  var result = [];
 | 
						|
  for (var i in t) {
 | 
						|
    for (var j in t) {
 | 
						|
      result.push([i, j, t[i], t[j]]);
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  deopt.deopt;
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
// Continue of the outer loop.
 | 
						|
function k(t, deopt) {
 | 
						|
  var result = [];
 | 
						|
  outer: for (var i in t) {
 | 
						|
    for (var j in t) {
 | 
						|
      result.push([i, j, t[i], t[j]]);
 | 
						|
      continue outer;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  deopt.deopt;
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
// Break of the outer loop.
 | 
						|
function l(t, deopt) {
 | 
						|
  var result = [];
 | 
						|
  outer: for (var i in t) {
 | 
						|
    for (var j in t) {
 | 
						|
      result.push([i, j, t[i], t[j]]);
 | 
						|
      break outer;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  deopt.deopt;
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
// Test deoptimization from inlined frame (currently it is not inlined).
 | 
						|
function m0(t, deopt) {
 | 
						|
  for (var i in t) {
 | 
						|
    for (var j in t) {
 | 
						|
      deopt.deopt;
 | 
						|
      return [i, j,  t[i], t[j]];
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function m(t, deopt) {
 | 
						|
  return m0(t, deopt);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
function tryFunction(result, mkT, f) {
 | 
						|
  var d = {deopt: false};
 | 
						|
  assertEquals(result, f(mkT(), d));
 | 
						|
  assertEquals(result, f(mkT(), d));
 | 
						|
  assertEquals(result, f(mkT(), d));
 | 
						|
  %OptimizeFunctionOnNextCall(f);
 | 
						|
  assertEquals(result, f(mkT(), d));
 | 
						|
  assertEquals(result, f(mkT(), {}));
 | 
						|
}
 | 
						|
 | 
						|
var expectedResult = [["a","1"],["b","2"],["c","3"],["d","4"]];
 | 
						|
function mkTable() { return { a: "1", b: "2", c: "3", d: "4" }; }
 | 
						|
 | 
						|
 | 
						|
tryFunction(expectedResult, mkTable, a);
 | 
						|
tryFunction(expectedResult, mkTable, b);
 | 
						|
 | 
						|
expectedResult = [["0","a"],["1","b"],["2","c"],["3","d"]];
 | 
						|
tryFunction(expectedResult, function () { return "abcd"; }, c);
 | 
						|
tryFunction(expectedResult, function () {
 | 
						|
  var cnt = false;
 | 
						|
  return function () {
 | 
						|
    cnt = true;
 | 
						|
    return "abcd";
 | 
						|
  }
 | 
						|
}, d);
 | 
						|
tryFunction([["a","a"],["b","b"],["c","c"],["d","d"]], mkTable, e);
 | 
						|
 | 
						|
function mkSmallTable() { return { a: "1", b: "2" }; }
 | 
						|
 | 
						|
tryFunction([
 | 
						|
    ["a","a","1","1"],["a","b","1","2"],
 | 
						|
    ["b","a","2","1"],["b","b","2","2"]],
 | 
						|
    mkSmallTable, f);
 | 
						|
tryFunction([
 | 
						|
    ["a","a","1","1"],["a","b","1","2"],
 | 
						|
    ["b","b","2","2"],["b","a","2","1"]],
 | 
						|
    mkSmallTable, g);
 | 
						|
tryFunction([["a","a","1","1"],["b","a","2","1"]], mkSmallTable, h);
 | 
						|
tryFunction([
 | 
						|
    ["a","a","1","1"],["a","b","1","2"],
 | 
						|
    ["b","a","2","1"],["b","b","2","2"]],
 | 
						|
    mkSmallTable, j);
 | 
						|
tryFunction([["a","a","1","1"],["b","a","2","1"]], mkSmallTable, h);
 | 
						|
tryFunction([["a","a","1","1"],["b","a","2","1"]], mkSmallTable, k);
 | 
						|
tryFunction([["a","a","1","1"]], mkSmallTable, l);
 | 
						|
tryFunction(["a","a","1","1"], mkSmallTable, m);
 | 
						|
 | 
						|
// Test handling of null.
 | 
						|
tryFunction("", function () {
 | 
						|
  return function () { return null; }
 | 
						|
}, function (t) {
 | 
						|
  for (var i in t()) { return i; }
 | 
						|
  return "";
 | 
						|
});
 | 
						|
 | 
						|
// Test smis.
 | 
						|
tryFunction("", function () {
 | 
						|
  return function () { return 11; }
 | 
						|
}, function (t) {
 | 
						|
  for (var i in t()) { return i; }
 | 
						|
  return "";
 | 
						|
});
 | 
						|
 | 
						|
// Test LoadFieldByIndex for out of object properties.
 | 
						|
function O() { this.a = 1; }
 | 
						|
for (var i = 0; i < 10; i++) new O();
 | 
						|
tryFunction([["a",1],["b",2],["c",3],["d",4],["e",5],["f",6]], function () {
 | 
						|
  var o = new O();
 | 
						|
  o.b = 2;
 | 
						|
  o.c = 3;
 | 
						|
  o.d = 4;
 | 
						|
  o.e = 5;
 | 
						|
  o.f = 6;
 | 
						|
  return o;
 | 
						|
}, function (t) {
 | 
						|
  var r = [];
 | 
						|
  for (var i in t) r.push([i, t[i]]);
 | 
						|
  return r;
 | 
						|
});
 | 
						|
 | 
						|
// Test OSR inside for-in.
 | 
						|
function osr_inner(t, limit) {
 | 
						|
  var r = 1;
 | 
						|
  for (var x in t) {
 | 
						|
    if (t.hasOwnProperty(x)) {
 | 
						|
      for (var i = 0; i < t[x].length; i++) {
 | 
						|
        r += t[x][i];
 | 
						|
        if (i === limit) %OptimizeOsr();
 | 
						|
      }
 | 
						|
      r += x;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return r;
 | 
						|
}
 | 
						|
 | 
						|
function osr_outer(t, osr_after) {
 | 
						|
  var r = 1;
 | 
						|
  for (var x in t) {
 | 
						|
    for (var i = 0; i < t[x].length; i++) {
 | 
						|
      r += t[x][i];
 | 
						|
    }
 | 
						|
    if (x === osr_after) %OptimizeOsr();
 | 
						|
    r += x;
 | 
						|
  }
 | 
						|
  return r;
 | 
						|
}
 | 
						|
 | 
						|
function osr_outer_and_deopt(t, osr_after) {
 | 
						|
  var r = 1;
 | 
						|
  for (var x in t) {
 | 
						|
    r += x;
 | 
						|
    if (x == osr_after) %OptimizeOsr();
 | 
						|
  }
 | 
						|
  return r;
 | 
						|
}
 | 
						|
 | 
						|
function test_osr() {
 | 
						|
  with ({}) {}  // Disable optimizations of this function.
 | 
						|
  var arr = new Array(20);
 | 
						|
  for (var i = 0; i < arr.length; i++) {
 | 
						|
    arr[i] = i + 1;
 | 
						|
  }
 | 
						|
  arr.push(":");  // Force deopt at the end of the loop.
 | 
						|
  assertEquals("211:x1234567891011121314151617181920:y", osr_inner({x: arr, y: arr}, (arr.length / 2) | 0));
 | 
						|
  assertEquals("7x456y", osr_outer({x: [1,2,3], y: [4,5,6]}, "x"));
 | 
						|
  assertEquals("101234567", osr_outer_and_deopt([1,2,3,4,5,6,7,8], "5"));
 | 
						|
}
 | 
						|
 | 
						|
test_osr();
 |