1// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Flags: --allow-natives-syntax
6
7// TODO(jkummerow): There are many ways to improve these tests, e.g.:
8// - more variance in randomized inputs
9// - better time complexity management
10// - better code readability and documentation of intentions.
11
12var RUN_WITH_ALL_ARGUMENT_ENTRIES = false;
13var kOnManyArgumentsRemove = 5;
14
15function makeArguments() {
16  var result = [ ];
17  result.push(17);
18  result.push(-31);
19  result.push(new Array(100));
20  var a = %NormalizeElements([]);
21  a.length = 100003;
22  result.push(a);
23  result.push(Number.MIN_VALUE);
24  result.push("whoops");
25  result.push("x");
26  result.push({"x": 1, "y": 2});
27  var slowCaseObj = {"a": 3, "b": 4, "c": 5};
28  delete slowCaseObj.c;
29  result.push(slowCaseObj);
30  result.push(function () { return 8; });
31  return result;
32}
33
34var kArgObjects = makeArguments().length;
35
36function makeFunction(name, argc) {
37  var args = [];
38  for (var i = 0; i < argc; i++)
39    args.push("x" + i);
40  var argsStr = args.join(", ");
41  return new Function(argsStr,
42                      "return %" + name + "(" + argsStr + ");");
43}
44
45function testArgumentCount(name, argc) {
46  for (var i = 0; i < 10; i++) {
47    var func = null;
48    try {
49      func = makeFunction(name, i);
50    } catch (e) {
51      if (e != "SyntaxError: Illegal access") throw e;
52    }
53    if (func === null && i == argc) {
54      throw "unexpected exception";
55    }
56    var args = [ ];
57    for (var j = 0; j < i; j++)
58      args.push(0);
59    try {
60      func.apply(void 0, args);
61    } catch (e) {
62      // we don't care what happens as long as we don't crash
63    }
64  }
65}
66
67function testArgumentTypes(name, argc) {
68  var type = 0;
69  var hasMore = true;
70  var func = makeFunction(name, argc);
71  while (hasMore) {
72    var argPool = makeArguments();
73    // When we have 5 or more arguments we lower the amount of tests cases
74    // by randomly removing kOnManyArgumentsRemove entries
75    var numArguments = RUN_WITH_ALL_ARGUMENT_ENTRIES ?
76      kArgObjects : kArgObjects - kOnManyArgumentsRemove;
77    if (kArgObjects >= 5 && !RUN_WITH_ALL_ARGUMENT_ENTRIES) {
78      for (var i = 0; i < kOnManyArgumentsRemove; i++) {
79        var rand = Math.floor(Math.random() * (kArgObjects - i));
80        argPool.splice(rand, 1);
81      }
82    }
83    var current = type;
84    hasMore = false;
85    var argList = [ ];
86    for (var i = 0; i < argc; i++) {
87      var index = current % numArguments;
88      current = (current / numArguments) << 0;
89      if (index != (numArguments - 1))
90        hasMore = true;
91      argList.push(argPool[index]);
92    }
93    try {
94      func.apply(void 0, argList);
95    } catch (e) {
96      // we don't care what happens as long as we don't crash
97    }
98    type++;
99  }
100}
101
102testArgumentCount(NAME, ARGC);
103testArgumentTypes(NAME, ARGC);
104