test/script/trusted/JDK-8006529.js

Wed, 27 Apr 2016 01:36:41 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:36:41 +0800
changeset 0
b1a7da25b547
child 952
6d5471a497fb
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/nashorn/
changeset: 1034:4b9cc65dd24d
tag: jdk8u25-b17

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 */
aoqi@0 23
aoqi@0 24 /**
aoqi@0 25 * JDK-8006529 : Methods should not always get callee parameter, and they
aoqi@0 26 * should not be too eager in creation of scopes.
aoqi@0 27 *
aoqi@0 28 * @test
aoqi@0 29 * @run
aoqi@0 30 */
aoqi@0 31
aoqi@0 32 /*
aoqi@0 33 * This test script depends on nashorn Compiler internals. It uses reflection
aoqi@0 34 * to get access to private field and many public methods of Compiler and
aoqi@0 35 * FunctionNode classes. Note that this is trusted code and access to such
aoqi@0 36 * internal package classes and methods is okay. But, if you modify any
aoqi@0 37 * Compiler or FunctionNode class, you may have to revisit this script.
aoqi@0 38 * We cannot use direct Java class (via dynalink bean linker) to Compiler
aoqi@0 39 * and FunctionNode because of package-access check and so reflective calls.
aoqi@0 40 */
aoqi@0 41
aoqi@0 42 var forName = java.lang.Class["forName(String)"];
aoqi@0 43 var Parser = forName("jdk.nashorn.internal.parser.Parser").static
aoqi@0 44 var Compiler = forName("jdk.nashorn.internal.codegen.Compiler").static
aoqi@0 45 var Context = forName("jdk.nashorn.internal.runtime.Context").static
aoqi@0 46 var ScriptEnvironment = forName("jdk.nashorn.internal.runtime.ScriptEnvironment").static
aoqi@0 47 var Source = forName("jdk.nashorn.internal.runtime.Source").static
aoqi@0 48 var FunctionNode = forName("jdk.nashorn.internal.ir.FunctionNode").static
aoqi@0 49 var Block = forName("jdk.nashorn.internal.ir.Block").static
aoqi@0 50 var VarNode = forName("jdk.nashorn.internal.ir.VarNode").static
aoqi@0 51 var ExpressionStatement = forName("jdk.nashorn.internal.ir.ExpressionStatement").static
aoqi@0 52 var UnaryNode = forName("jdk.nashorn.internal.ir.UnaryNode").static
aoqi@0 53 var BinaryNode = forName("jdk.nashorn.internal.ir.BinaryNode").static
aoqi@0 54 var ThrowErrorManager = forName("jdk.nashorn.internal.runtime.Context$ThrowErrorManager").static
aoqi@0 55 var ErrorManager = forName("jdk.nashorn.internal.runtime.ErrorManager").static
aoqi@0 56 var Debug = forName("jdk.nashorn.internal.runtime.Debug").static
aoqi@0 57
aoqi@0 58 var parseMethod = Parser.class.getMethod("parse");
aoqi@0 59 var compileMethod = Compiler.class.getMethod("compile", FunctionNode.class);
aoqi@0 60 var getBodyMethod = FunctionNode.class.getMethod("getBody");
aoqi@0 61 var getStatementsMethod = Block.class.getMethod("getStatements");
aoqi@0 62 var getInitMethod = VarNode.class.getMethod("getInit");
aoqi@0 63 var getExpressionMethod = ExpressionStatement.class.getMethod("getExpression")
aoqi@0 64 var rhsMethod = UnaryNode.class.getMethod("rhs")
aoqi@0 65 var lhsMethod = BinaryNode.class.getMethod("lhs")
aoqi@0 66 var binaryRhsMethod = BinaryNode.class.getMethod("rhs")
aoqi@0 67 var debugIdMethod = Debug.class.getMethod("id", java.lang.Object.class)
aoqi@0 68
aoqi@0 69 // These are method names of methods in FunctionNode class
aoqi@0 70 var allAssertionList = ['isVarArg', 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'needsSelfSymbol', 'isSplit', 'hasEval', 'allVarsInScope', 'isStrict']
aoqi@0 71
aoqi@0 72 // corresponding Method objects of FunctionNode class
aoqi@0 73 var functionNodeMethods = {};
aoqi@0 74 // initialize FunctionNode methods
aoqi@0 75 (function() {
aoqi@0 76 for (var f in allAssertionList) {
aoqi@0 77 var method = allAssertionList[f];
aoqi@0 78 functionNodeMethods[method] = FunctionNode.class.getMethod(method);
aoqi@0 79 }
aoqi@0 80 })();
aoqi@0 81
aoqi@0 82 // returns functionNode.getBody().getStatements().get(0)
aoqi@0 83 function getFirstFunction(functionNode) {
aoqi@0 84 var f = findFunction(getBodyMethod.invoke(functionNode))
aoqi@0 85 if (f == null) {
aoqi@0 86 throw new Error();
aoqi@0 87 }
aoqi@0 88 return f;
aoqi@0 89 }
aoqi@0 90
aoqi@0 91 function findFunction(node) {
aoqi@0 92 if(node instanceof Block) {
aoqi@0 93 var stmts = getStatementsMethod.invoke(node)
aoqi@0 94 for(var i = 0; i < stmts.size(); ++i) {
aoqi@0 95 var retval = findFunction(stmts.get(i))
aoqi@0 96 if(retval != null) {
aoqi@0 97 return retval;
aoqi@0 98 }
aoqi@0 99 }
aoqi@0 100 } else if(node instanceof VarNode) {
aoqi@0 101 return findFunction(getInitMethod.invoke(node))
aoqi@0 102 } else if(node instanceof UnaryNode) {
aoqi@0 103 return findFunction(rhsMethod.invoke(node))
aoqi@0 104 } else if(node instanceof BinaryNode) {
aoqi@0 105 return findFunction(lhsMethod.invoke(node)) || findFunction(binaryRhsMethod.invoke(node))
aoqi@0 106 } else if(node instanceof ExpressionStatement) {
aoqi@0 107 return findFunction(getExpressionMethod.invoke(node))
aoqi@0 108 } else if(node instanceof FunctionNode) {
aoqi@0 109 return node
aoqi@0 110 }
aoqi@0 111 }
aoqi@0 112
aoqi@0 113 var getContextMethod = Context.class.getMethod("getContext")
aoqi@0 114 var getEnvMethod = Context.class.getMethod("getEnv")
aoqi@0 115
aoqi@0 116 var sourceForMethod = Source.class.getMethod("sourceFor", java.lang.String.class, java.lang.String.class)
aoqi@0 117 var ParserConstructor = Parser.class.getConstructor(ScriptEnvironment.class, Source.class, ErrorManager.class)
aoqi@0 118 var CompilerConstructor = Compiler.class.getConstructor(ScriptEnvironment.class)
aoqi@0 119
aoqi@0 120 // compile(script) -- compiles a script specified as a string with its
aoqi@0 121 // source code, returns a jdk.nashorn.internal.ir.FunctionNode object
aoqi@0 122 // representing it.
aoqi@0 123 function compile(source) {
aoqi@0 124 var source = sourceForMethod.invoke(null, "<no name>", source);
aoqi@0 125
aoqi@0 126 var env = getEnvMethod.invoke(getContextMethod.invoke(null))
aoqi@0 127
aoqi@0 128 var parser = ParserConstructor.newInstance(env, source, ThrowErrorManager.class.newInstance());
aoqi@0 129 var func = parseMethod.invoke(parser);
aoqi@0 130
aoqi@0 131 var compiler = CompilerConstructor.newInstance(env);
aoqi@0 132
aoqi@0 133 return compileMethod.invoke(compiler, func);
aoqi@0 134 };
aoqi@0 135
aoqi@0 136 var allAssertions = (function() {
aoqi@0 137 var allAssertions = {}
aoqi@0 138 for(var assertion in allAssertionList) {
aoqi@0 139 allAssertions[allAssertionList[assertion]] = true
aoqi@0 140 }
aoqi@0 141 return allAssertions;
aoqi@0 142 })();
aoqi@0 143
aoqi@0 144
aoqi@0 145 // test(f[, assertions...]) tests whether all the specified assertions on the
aoqi@0 146 // passed function node are true.
aoqi@0 147 function test(f) {
aoqi@0 148 var assertions = {}
aoqi@0 149 for(var i = 1; i < arguments.length; ++i) {
aoqi@0 150 var assertion = arguments[i]
aoqi@0 151 if(!allAssertions[assertion]) {
aoqi@0 152 throw "Unknown assertion " + assertion + " for " + f;
aoqi@0 153 }
aoqi@0 154 assertions[assertion] = true
aoqi@0 155 }
aoqi@0 156 for(var assertion in allAssertions) {
aoqi@0 157 var expectedValue = !!assertions[assertion]
aoqi@0 158 var actualValue = functionNodeMethods[assertion].invoke(f)
aoqi@0 159 if(actualValue !== expectedValue) {
aoqi@0 160 throw "Expected " + assertion + " === " + expectedValue + ", got " + actualValue + " for " + f + ":" + debugIdMethod.invoke(null, f);
aoqi@0 161 }
aoqi@0 162 }
aoqi@0 163 }
aoqi@0 164
aoqi@0 165 // testFirstFn(script[, assertions...] tests whether all the specified
aoqi@0 166 // assertions are true in the first function in the given script; "script"
aoqi@0 167 // is a string with the source text of the script.
aoqi@0 168 function testFirstFn(script) {
aoqi@0 169 arguments[0] = getFirstFunction(compile(script))
aoqi@0 170 test.apply(null, arguments)
aoqi@0 171 }
aoqi@0 172
aoqi@0 173 // ---------------------------------- ACTUAL TESTS START HERE --------------
aoqi@0 174
aoqi@0 175 // The simplest possible functions have no attributes set
aoqi@0 176 testFirstFn("function f() { }")
aoqi@0 177 testFirstFn("function f(x) { x }")
aoqi@0 178
aoqi@0 179 // A function referencing a global needs parent scope, and it needs callee
aoqi@0 180 // (because parent scope is passed through callee)
aoqi@0 181 testFirstFn("function f() { x }", 'needsCallee', 'needsParentScope')
aoqi@0 182
aoqi@0 183 // A function referencing "arguments" will have to be vararg. It also needs
aoqi@0 184 // the callee, as it needs to fill out "arguments.callee".
aoqi@0 185 testFirstFn("function f() { arguments }", 'needsCallee', 'isVarArg')
aoqi@0 186
aoqi@0 187 // A function referencing "arguments" will have to be vararg. If it is
aoqi@0 188 // strict, it will not have to have a callee, though.
aoqi@0 189 testFirstFn("function f() {'use strict'; arguments }", 'isVarArg', 'isStrict')
aoqi@0 190
aoqi@0 191 // A function defining "arguments" as a parameter will not be vararg.
aoqi@0 192 testFirstFn("function f(arguments) { arguments }")
aoqi@0 193
aoqi@0 194 // A function defining "arguments" as a nested function will not be vararg.
aoqi@0 195 testFirstFn("function f() { function arguments() {}; arguments; }")
aoqi@0 196
aoqi@0 197 // A function defining "arguments" as a local variable will be vararg.
aoqi@0 198 testFirstFn("function f() { var arguments; arguments; }", 'isVarArg', 'needsCallee')
aoqi@0 199
aoqi@0 200 // A self-referencing function defined as a statement doesn't need a self
aoqi@0 201 // symbol, as it'll rather obtain itself from the parent scope.
aoqi@0 202 testFirstFn("function f() { f() }", 'needsCallee', 'needsParentScope')
aoqi@0 203
aoqi@0 204 // A self-referencing function defined as an expression needs a self symbol,
aoqi@0 205 // as it can't obtain itself from the parent scope.
aoqi@0 206 testFirstFn("(function f() { f() })", 'needsCallee', 'needsSelfSymbol')
aoqi@0 207
aoqi@0 208 // A child function accessing parent's variable triggers the need for scope
aoqi@0 209 // in parent
aoqi@0 210 testFirstFn("(function f() { var x; function g() { x } })", 'hasScopeBlock')
aoqi@0 211
aoqi@0 212 // A child function accessing parent's parameter triggers the need for scope
aoqi@0 213 // in parent
aoqi@0 214 testFirstFn("(function f(x) { function g() { x } })", 'hasScopeBlock')
aoqi@0 215
aoqi@0 216 // A child function accessing a global variable triggers the need for parent
aoqi@0 217 // scope in parent
aoqi@0 218 testFirstFn("(function f() { function g() { x } })", 'needsParentScope', 'needsCallee')
aoqi@0 219
aoqi@0 220 // A child function redefining a local variable from its parent should not
aoqi@0 221 // affect the parent function in any way
aoqi@0 222 testFirstFn("(function f() { var x; function g() { var x; x } })")
aoqi@0 223
aoqi@0 224 // Using "with" on its own doesn't do much.
aoqi@0 225 testFirstFn("(function f() { var o; with(o) {} })")
aoqi@0 226
aoqi@0 227 // "with" referencing a local variable triggers scoping.
aoqi@0 228 testFirstFn("(function f() { var x; var y; with(x) { y } })", 'hasScopeBlock')
aoqi@0 229
aoqi@0 230 // "with" referencing a non-local variable triggers parent scope.
aoqi@0 231 testFirstFn("(function f() { var x; with(x) { y } })", 'needsCallee', 'needsParentScope')
aoqi@0 232
aoqi@0 233 // Nested function using "with" is pretty much the same as the parent
aoqi@0 234 // function needing with.
aoqi@0 235 testFirstFn("(function f() { function g() { var o; with(o) {} } })")
aoqi@0 236
aoqi@0 237 // Nested function using "with" referencing a local variable.
aoqi@0 238 testFirstFn("(function f() { var x; function g() { var o; with(o) { x } } })", 'hasScopeBlock')
aoqi@0 239
aoqi@0 240 // Using "eval" triggers pretty much everything. The function even needs to be
aoqi@0 241 // vararg, 'cause we don't know if eval will be using "arguments".
aoqi@0 242 testFirstFn("(function f() { eval() })", 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'hasEval', 'isVarArg', 'allVarsInScope')
aoqi@0 243
aoqi@0 244 // Nested function using "eval" is almost the same as parent function using
aoqi@0 245 // eval, but at least the parent doesn't have to be vararg.
aoqi@0 246 testFirstFn("(function f() { function g() { eval() } })", 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'allVarsInScope')
aoqi@0 247
aoqi@0 248 // Function with 250 named parameters is ordinary
aoqi@0 249 testFirstFn("function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54, p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81, p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95, p96, p97, p98, p99, p100, p101, p102, p103, p104, p105, p106, p107, p108, p109, p110, p111, p112, p113, p114, p115, p116, p117, p118, p119, p120, p121, p122, p123, p124, p125, p126, p127, p128, p129, p130, p131, p132, p133, p134, p135, p136, p137, p138, p139, p140, p141, p142, p143, p144, p145, p146, p147, p148, p149, p150, p151, p152, p153, p154, p155, p156, p157, p158, p159, p160, p161, p162, p163, p164, p165, p166, p167, p168, p169, p170, p171, p172, p173, p174, p175, p176, p177, p178, p179, p180, p181, p182, p183, p184, p185, p186, p187, p188, p189, p190, p191, p192, p193, p194, p195, p196, p197, p198, p199, p200, p201, p202, p203, p204, p205, p206, p207, p208, p209, p210, p211, p212, p213, p214, p215, p216, p217, p218, p219, p220, p221, p222, p223, p224, p225, p226, p227, p228, p229, p230, p231, p232, p233, p234, p235, p236, p237, p238, p239, p240, p241, p242, p243, p244, p245, p246, p247, p248, p249, p250) { p250 = p249 }")
aoqi@0 250
aoqi@0 251 // Function with 251 named parameters is variable arguments
aoqi@0 252 testFirstFn("function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54, p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81, p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95, p96, p97, p98, p99, p100, p101, p102, p103, p104, p105, p106, p107, p108, p109, p110, p111, p112, p113, p114, p115, p116, p117, p118, p119, p120, p121, p122, p123, p124, p125, p126, p127, p128, p129, p130, p131, p132, p133, p134, p135, p136, p137, p138, p139, p140, p141, p142, p143, p144, p145, p146, p147, p148, p149, p150, p151, p152, p153, p154, p155, p156, p157, p158, p159, p160, p161, p162, p163, p164, p165, p166, p167, p168, p169, p170, p171, p172, p173, p174, p175, p176, p177, p178, p179, p180, p181, p182, p183, p184, p185, p186, p187, p188, p189, p190, p191, p192, p193, p194, p195, p196, p197, p198, p199, p200, p201, p202, p203, p204, p205, p206, p207, p208, p209, p210, p211, p212, p213, p214, p215, p216, p217, p218, p219, p220, p221, p222, p223, p224, p225, p226, p227, p228, p229, p230, p231, p232, p233, p234, p235, p236, p237, p238, p239, p240, p241, p242, p243, p244, p245, p246, p247, p248, p249, p250, p251) { p250 = p251 }", 'isVarArg')

mercurial