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