test/script/trusted/JDK-8006529.js

changeset 82
abea4ba28901
parent 77
d7e83be6e7aa
child 89
43e32b36153c
     1.1 --- a/test/script/trusted/JDK-8006529.js	Sat Feb 09 16:58:48 2013 +0100
     1.2 +++ b/test/script/trusted/JDK-8006529.js	Mon Feb 11 21:26:06 2013 +0530
     1.3 @@ -29,23 +29,74 @@
     1.4   * @run
     1.5   */
     1.6  
     1.7 +/*
     1.8 + * This test script depends on nashorn Compiler internals. It uses reflection
     1.9 + * to get access to private field and many public methods of Compiler and
    1.10 + * FunctionNode classes. Note that this is trusted code and access to such
    1.11 + * internal package classes and methods is okay. But, if you modify any 
    1.12 + * Compiler or FunctionNode class, you may have to revisit this script.
    1.13 + * We cannot use direct Java class (via dynalink bean linker) to Compiler
    1.14 + * and FunctionNode because of package-access check and so reflective calls.
    1.15 + */
    1.16 +
    1.17 +var Compiler       = Java.type("jdk.nashorn.internal.codegen.Compiler")
    1.18 +var Context        = Java.type("jdk.nashorn.internal.runtime.Context")
    1.19 +var Source         = Java.type("jdk.nashorn.internal.runtime.Source")
    1.20 +var FunctionNode   = Java.type("jdk.nashorn.internal.ir.FunctionNode")
    1.21 +
    1.22 +// Compiler class methods and fields
    1.23 +
    1.24 +// Compiler.compile(Source, Context)
    1.25 +var compilerMethod = Compiler.class.getMethod("compiler", Source.class, Context.class);
    1.26 +// Compiler.compile()
    1.27 +var compileMethod  = Compiler.class.getMethod("compile");
    1.28 +
    1.29 +// NOTE: private field. But this is a trusted test!
    1.30 +// Compiler.functionNode
    1.31 +var functionNodeField = Compiler.class.getDeclaredField("functionNode");
    1.32 +functionNodeField.setAccessible(true);
    1.33 +
    1.34 +// FunctionNode methods
    1.35 +
    1.36 +// FunctionNode.getFunctions method
    1.37 +var getFunctionsMethod = FunctionNode.class.getMethod("getFunctions");
    1.38 +
    1.39 +// These are method names of methods in FunctionNode class
    1.40 +var allAssertionList = ['isVarArg', 'needsParentScope', 'needsCallee', 'needsScope', 'needsSelfSymbol', 'isSplit', 'hasEval', 'hasWith', 'hasDeepWithOrEval', 'varsInScope', 'isStrictMode']
    1.41 +
    1.42 +// corresponding Method objects of FunctionNode class
    1.43 +var functionNodeMethods = {};
    1.44 +// initialize FunctionNode methods
    1.45 +(function() {
    1.46 +    for (var f in allAssertionList) {
    1.47 +        var method = allAssertionList[f];
    1.48 +        functionNodeMethods[method] = FunctionNode.class.getMethod(method);
    1.49 +    }
    1.50 +})();
    1.51 +
    1.52 +// returns "script" functionNode from Compiler instance
    1.53 +function getScriptNode(compiler) {
    1.54 +    // compiler.functionNode
    1.55 +    return functionNodeField.get(compiler);
    1.56 +}
    1.57 +
    1.58 +// returns functionNode.getFunctions().get(0)
    1.59 +function getFirstFunction(functionNode) {
    1.60 +    // functionNode.getFunctions().get(0)
    1.61 +    return getFunctionsMethod.invoke(functionNode).get(0);
    1.62 +}
    1.63 +
    1.64  // compile(script) -- compiles a script specified as a string with its 
    1.65  // source code, returns a jdk.nashorn.internal.ir.FunctionNode object 
    1.66  // representing it.
    1.67 -var compile = (function() {
    1.68 -    var Compiler       = Java.type("jdk.nashorn.internal.codegen.Compiler")
    1.69 -    var Context        = Java.type("jdk.nashorn.internal.runtime.Context")
    1.70 -    var Source         = Java.type("jdk.nashorn.internal.runtime.Source")
    1.71 -    var CompilerAccess = Java.type("jdk.nashorn.internal.codegen.CompilerAccess")
    1.72 -    return function(source) {
    1.73 -	    var compiler = Compiler.compiler(new Source("<no name>", source), Context.getContext())
    1.74 -        compiler.compile()
    1.75 -        return CompilerAccess.getScriptNode(compiler)
    1.76 -    }
    1.77 -})();
    1.78 +function compile(source) {
    1.79 +   var compiler = compilerMethod.invoke(null,
    1.80 +       new Source("<no name>", source), Context.getContext())
    1.81 +   compileMethod.invoke(compiler);
    1.82 +   return getScriptNode(compiler)
    1.83 +};
    1.84  
    1.85  var allAssertions = (function() {
    1.86 -    var allAssertionList = ['isVarArg', 'needsParentScope', 'needsCallee', 'needsScope', 'needsSelfSymbol', 'isSplit', 'hasEval', 'hasWith', 'hasDeepWithOrEval', 'varsInScope', 'isStrictMode']
    1.87      var allAssertions = {}
    1.88      for(var assertion in allAssertionList) {
    1.89          allAssertions[allAssertionList[assertion]] = true
    1.90 @@ -53,6 +104,7 @@
    1.91      return allAssertions;
    1.92  })();
    1.93  
    1.94 +
    1.95  // test(f[, assertions...]) tests whether all the specified assertions on the
    1.96  // passed function node are true.
    1.97  function test(f) {
    1.98 @@ -66,10 +118,7 @@
    1.99      }
   1.100      for(var assertion in allAssertions) {
   1.101          var expectedValue = !!assertions[assertion]
   1.102 -        if(f[assertion] == null) {
   1.103 -            throw "Can't find " + assertion + " on " + f;
   1.104 -        }
   1.105 -        if(f[assertion]() !== expectedValue) {
   1.106 +        if(functionNodeMethods[assertion].invoke(f) !== expectedValue) {
   1.107              throw "Expected " + assertion + " === " + expectedValue + " for " + f;
   1.108          }
   1.109      }
   1.110 @@ -79,7 +128,7 @@
   1.111  // assertions are true in the first function in the given script; "script"
   1.112  // is a string with the source text of the script.
   1.113  function testFirstFn(script) {
   1.114 -    arguments[0] = compile(script).functions[0]
   1.115 +    arguments[0] = getFirstFunction(compile(script))
   1.116      test.apply(null, arguments)
   1.117  }
   1.118  

mercurial