generate-builtins-tests.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #!/usr/bin/env python
  2. # Copyright 2014 the V8 project authors. All rights reserved.
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. # for py2/py3 compatibility
  6. from __future__ import print_function
  7. import json
  8. import optparse
  9. import os
  10. import random
  11. import shutil
  12. import subprocess
  13. import sys
  14. SKIPLIST = [
  15. # Skip special d8 functions.
  16. "load", "os", "print", "read", "readline", "quit"
  17. ]
  18. def GetRandomObject():
  19. return random.choice([
  20. "0", "1", "2.5", "0x1000", "\"string\"", "{foo: \"bar\"}", "[1, 2, 3]",
  21. "function() { return 0; }"
  22. ])
  23. g_var_index = 0
  24. def GetVars(result, num, first = []):
  25. global g_var_index
  26. variables = []
  27. for i in range(num):
  28. variables.append("__v_%d" % g_var_index)
  29. g_var_index += 1
  30. for var in variables:
  31. result.append("var %s = %s;" % (var, GetRandomObject()))
  32. return ", ".join(first + variables)
  33. # Wraps |string| in try..catch.
  34. def TryCatch(result, string, exception_behavior = ""):
  35. result.append("try { %s } catch(e) { %s }" % (string, exception_behavior))
  36. def BuildTests(function, full_name, options):
  37. assert function["type"] == "function"
  38. global g_var_index
  39. g_var_index = 0
  40. result = ["// AUTO-GENERATED BY tools/generate-builtins-tests.py.\n"]
  41. result.append("// Function call test:")
  42. length = function["length"]
  43. TryCatch(result, "%s(%s);" % (full_name, GetVars(result, length)))
  44. if "prototype" in function:
  45. proto = function["prototype"]
  46. result.append("\n// Constructor test:")
  47. TryCatch(result,
  48. "var recv = new %s(%s);" % (full_name, GetVars(result, length)),
  49. "var recv = new Object();")
  50. getters = []
  51. methods = []
  52. for prop in proto:
  53. proto_property = proto[prop]
  54. proto_property_type = proto_property["type"]
  55. if proto_property_type == "getter":
  56. getters.append(proto_property)
  57. result.append("recv.__defineGetter__(\"%s\", "
  58. "function() { return %s; });" %
  59. (proto_property["name"], GetVars(result, 1)))
  60. if proto_property_type == "number":
  61. result.append("recv.__defineGetter__(\"%s\", "
  62. "function() { return %s; });" %
  63. (proto_property["name"], GetVars(result, 1)))
  64. if proto_property_type == "function":
  65. methods.append(proto_property)
  66. if getters:
  67. result.append("\n// Getter tests:")
  68. for getter in getters:
  69. result.append("print(recv.%s);" % getter["name"])
  70. if methods:
  71. result.append("\n// Method tests:")
  72. for method in methods:
  73. args = GetVars(result, method["length"], ["recv"])
  74. call = "%s.prototype.%s.call(%s)" % (full_name, method["name"], args)
  75. TryCatch(result, call)
  76. filename = os.path.join(options.outdir, "%s.js" % (full_name))
  77. with open(filename, "w") as f:
  78. f.write("\n".join(result))
  79. f.write("\n")
  80. def VisitObject(obj, path, options):
  81. obj_type = obj["type"]
  82. obj_name = "%s%s" % (path, obj["name"])
  83. if obj_type == "function":
  84. BuildTests(obj, obj_name, options)
  85. if "properties" in obj:
  86. for prop_name in obj["properties"]:
  87. prop = obj["properties"][prop_name]
  88. VisitObject(prop, "%s." % (obj_name), options)
  89. def ClearGeneratedFiles(options):
  90. if os.path.exists(options.outdir):
  91. shutil.rmtree(options.outdir)
  92. def GenerateTests(options):
  93. ClearGeneratedFiles(options) # Re-generate everything.
  94. output = subprocess.check_output(
  95. "%s %s" % (options.d8, options.script), shell=True).strip()
  96. objects = json.loads(output)
  97. os.makedirs(options.outdir)
  98. for obj_name in objects:
  99. if obj_name in SKIPLIST: continue
  100. obj = objects[obj_name]
  101. VisitObject(obj, "", options)
  102. def BuildOptions():
  103. result = optparse.OptionParser()
  104. result.add_option("--d8", help="d8 binary to use",
  105. default="out/ia32.release/d8")
  106. result.add_option("--outdir", help="directory where to place generated tests",
  107. default="test/mjsunit/builtins-gen")
  108. result.add_option("--script", help="builtins detector script to run in d8",
  109. default="tools/detect-builtins.js")
  110. return result
  111. def Main():
  112. parser = BuildOptions()
  113. (options, args) = parser.parse_args()
  114. if len(args) != 1 or args[0] == "help":
  115. parser.print_help()
  116. return 1
  117. action = args[0]
  118. if action == "generate":
  119. GenerateTests(options)
  120. return 0
  121. if action == "clear":
  122. ClearGeneratedFiles(options)
  123. return 0
  124. print("Unknown action: %s" % action)
  125. parser.print_help()
  126. return 1
  127. if __name__ == "__main__":
  128. sys.exit(Main())