argumentsResolution.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. function generateTestFunctionAndCall(
  6. functionTypeAndName, // integer: 0 is declaration, 1 is declaration named 'arguments', 2 is unnamed expression, 3 is expression named 'arguments'
  7. parameterArguments, // boolean
  8. nestedFunctionType, // integer: 0 is no nested function, 1 is nested function declaration, 2 is nested function expression
  9. varDeclarationArgumentsType, // integer: 0 is no var declaration, 1 is var declaration, 2 is initialized var declaration
  10. callsEval) // boolean
  11. {
  12. var typeMap =
  13. {
  14. "function": "function",
  15. "number": "parameter",
  16. "string": "var",
  17. "object": "arguments"
  18. };
  19. // The generated function will look something like this:
  20. // safeCall(function ()
  21. // {
  22. // function arguments(arguments)
  23. // {
  24. // eval("");
  25. // (function arguments() { });
  26. // var arguments = "hi";
  27. // writeLine(typeMap[typeof (arguments)]);
  28. // }
  29. // arguments(1);
  30. // });
  31. var functionCode = "";
  32. switch (functionTypeAndName)
  33. {
  34. case 2:
  35. case 3:
  36. functionCode += "(";
  37. }
  38. functionCode += "function";
  39. var functionName = "";
  40. switch (functionTypeAndName)
  41. {
  42. case 0:
  43. functionName = "foo";
  44. break;
  45. case 1:
  46. case 3:
  47. functionName = "arguments";
  48. }
  49. functionCode += " " + functionName + "(";
  50. if (parameterArguments)
  51. functionCode += "arguments";
  52. functionCode += "){";
  53. if (callsEval)
  54. functionCode += 'eval("");';
  55. switch (nestedFunctionType)
  56. {
  57. case 1:
  58. functionCode += "function arguments(){}";
  59. break;
  60. case 2:
  61. functionCode += "(function arguments(){});";
  62. }
  63. switch (varDeclarationArgumentsType)
  64. {
  65. case 1:
  66. case 2:
  67. functionCode += "var arguments";
  68. if (varDeclarationArgumentsType === 2)
  69. functionCode += '="hi"';
  70. functionCode += ";";
  71. }
  72. functionCode += "writeLine(typeMap[typeof(arguments)]);}";
  73. switch (functionTypeAndName)
  74. {
  75. case 0:
  76. case 1:
  77. functionCode += functionName;
  78. break;
  79. case 2:
  80. case 3:
  81. functionCode += ")";
  82. }
  83. functionCode += "(1);";
  84. writeLine(functionCode);
  85. eval("safeCall(function(){" + functionCode + "});");
  86. }
  87. var booleans = [false, true];
  88. for (var functionTypeAndName = 0; functionTypeAndName <= 3; ++functionTypeAndName)
  89. {
  90. for (var parameterArgumentsIndex in booleans)
  91. {
  92. for (var nestedFunctionType = 0; nestedFunctionType <= 2; ++nestedFunctionType)
  93. {
  94. for (var varDeclarationArgumentsType = 0; varDeclarationArgumentsType <= 2; ++varDeclarationArgumentsType)
  95. {
  96. for (var callsEvalIndex in booleans)
  97. {
  98. var parameterArguments = booleans[parameterArgumentsIndex];
  99. var callsEval = booleans[callsEvalIndex];
  100. generateTestFunctionAndCall(
  101. functionTypeAndName,
  102. parameterArguments,
  103. nestedFunctionType,
  104. varDeclarationArgumentsType,
  105. callsEval);
  106. }
  107. }
  108. }
  109. }
  110. }
  111. // Helpers
  112. function writeLine(str)
  113. {
  114. WScript.Echo("" + str);
  115. }
  116. function safeCall(func)
  117. {
  118. try
  119. {
  120. return func();
  121. }
  122. catch (ex)
  123. {
  124. writeLine(ex.name + ": " + ex.message);
  125. }
  126. }