Path: blob/aarch64-shenandoah-jdk8u272-b10/nashorn/test/script/trusted/JDK-8006529.js
32284 views
/*1* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/**24* JDK-8006529 : Methods should not always get callee parameter, and they25* should not be too eager in creation of scopes.26*27* @test28* @run29*/3031/*32* This test script depends on nashorn Compiler internals. It uses reflection33* to get access to private field and many public methods of Compiler and34* FunctionNode classes. Note that this is trusted code and access to such35* internal package classes and methods is okay. But, if you modify any36* Compiler or FunctionNode class, you may have to revisit this script.37* We cannot use direct Java class (via dynalink bean linker) to Compiler38* and FunctionNode because of package-access check and so reflective calls.39*/4041var forName = java.lang.Class["forName(String)"];42var Parser = forName("jdk.nashorn.internal.parser.Parser").static43var Compiler = forName("jdk.nashorn.internal.codegen.Compiler").static44var CompilationPhases = forName("jdk.nashorn.internal.codegen.Compiler$CompilationPhases").static;45var Context = forName("jdk.nashorn.internal.runtime.Context").static46var CodeInstaller = forName("jdk.nashorn.internal.runtime.CodeInstaller").static47var ScriptEnvironment = forName("jdk.nashorn.internal.runtime.ScriptEnvironment").static48var Source = forName("jdk.nashorn.internal.runtime.Source").static49var FunctionNode = forName("jdk.nashorn.internal.ir.FunctionNode").static50var Block = forName("jdk.nashorn.internal.ir.Block").static51var VarNode = forName("jdk.nashorn.internal.ir.VarNode").static52var ExpressionStatement = forName("jdk.nashorn.internal.ir.ExpressionStatement").static53var UnaryNode = forName("jdk.nashorn.internal.ir.UnaryNode").static54var BinaryNode = forName("jdk.nashorn.internal.ir.BinaryNode").static55var ThrowErrorManager = forName("jdk.nashorn.internal.runtime.Context$ThrowErrorManager").static56var ErrorManager = forName("jdk.nashorn.internal.runtime.ErrorManager").static57var Debug = forName("jdk.nashorn.internal.runtime.Debug").static58var String = forName("java.lang.String").static59var boolean = Java.type("boolean");6061var parseMethod = Parser.class.getMethod("parse");62var compileMethod = Compiler.class.getMethod("compile", FunctionNode.class, CompilationPhases.class);63var getBodyMethod = FunctionNode.class.getMethod("getBody");64var getStatementsMethod = Block.class.getMethod("getStatements");65var getInitMethod = VarNode.class.getMethod("getInit");66var getExpressionMethod = ExpressionStatement.class.getMethod("getExpression")67var rhsMethod = UnaryNode.class.getMethod("getExpression")68var lhsMethod = BinaryNode.class.getMethod("lhs")69var binaryRhsMethod = BinaryNode.class.getMethod("rhs")70var debugIdMethod = Debug.class.getMethod("id", java.lang.Object.class)71var compilePhases = CompilationPhases.class.getField("COMPILE_UPTO_BYTECODE").get(null);7273// These are method names of methods in FunctionNode class74var allAssertionList = ['isVarArg', 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'usesSelfSymbol', 'isSplit', 'hasEval', 'allVarsInScope', 'isStrict']7576// corresponding Method objects of FunctionNode class77var functionNodeMethods = {};78// initialize FunctionNode methods79(function() {80for (var f in allAssertionList) {81var method = allAssertionList[f];82functionNodeMethods[method] = FunctionNode.class.getMethod(method);83}84})();8586// returns functionNode.getBody().getStatements().get(0)87function getFirstFunction(functionNode) {88var f = findFunction(getBodyMethod.invoke(functionNode))89if (f == null) {90throw new Error();91}92return f;93}9495function findFunction(node) {96if(node instanceof Block) {97var stmts = getStatementsMethod.invoke(node)98for(var i = 0; i < stmts.size(); ++i) {99var retval = findFunction(stmts.get(i))100if(retval != null) {101return retval;102}103}104} else if(node instanceof VarNode) {105return findFunction(getInitMethod.invoke(node))106} else if(node instanceof UnaryNode) {107return findFunction(rhsMethod.invoke(node))108} else if(node instanceof BinaryNode) {109return findFunction(lhsMethod.invoke(node)) || findFunction(binaryRhsMethod.invoke(node))110} else if(node instanceof ExpressionStatement) {111return findFunction(getExpressionMethod.invoke(node))112} else if(node instanceof FunctionNode) {113return node114}115}116117var getContextMethod = Context.class.getMethod("getContext")118var getEnvMethod = Context.class.getMethod("getEnv")119120var sourceForMethod = Source.class.getMethod("sourceFor", java.lang.String.class, java.lang.String.class)121var ParserConstructor = Parser.class.getConstructor(ScriptEnvironment.class, Source.class, ErrorManager.class)122var CompilerConstructor = Compiler.class.getMethod("forNoInstallerCompilation", Context.class, Source.class, boolean.class);123124// compile(script) -- compiles a script specified as a string with its125// source code, returns a jdk.nashorn.internal.ir.FunctionNode object126// representing it.127function compile(source, phases) {128var source = sourceForMethod.invoke(null, "<no name>", source);129130var ctxt = getContextMethod.invoke(null);131var env = getEnvMethod.invoke(ctxt);132133var parser = ParserConstructor.newInstance(env, source, ThrowErrorManager.class.newInstance());134var func = parseMethod.invoke(parser);135136var compiler = CompilerConstructor.invoke(null, ctxt, source, false);137138return compileMethod.invoke(compiler, func, phases);139};140141var allAssertions = (function() {142var allAssertions = {}143for(var assertion in allAssertionList) {144allAssertions[allAssertionList[assertion]] = true145}146return allAssertions;147})();148149150// test(f[, assertions...]) tests whether all the specified assertions on the151// passed function node are true.152function test(f) {153var assertions = {}154for(var i = 1; i < arguments.length; ++i) {155var assertion = arguments[i]156if(!allAssertions[assertion]) {157throw "Unknown assertion " + assertion + " for " + f;158}159assertions[assertion] = true160}161for(var assertion in allAssertions) {162var expectedValue = !!assertions[assertion]163var actualValue = functionNodeMethods[assertion].invoke(f)164if(actualValue !== expectedValue) {165throw "Expected " + assertion + " === " + expectedValue + ", got " + actualValue + " for " + f + ":" + debugIdMethod.invoke(null, f);166}167}168}169170// testFirstFn(script[, assertions...] tests whether all the specified171// assertions are true in the first function in the given script; "script"172// is a string with the source text of the script.173function testFirstFn(script) {174arguments[0] = getFirstFunction(compile(script, compilePhases));175test.apply(null, arguments);176}177178// ---------------------------------- ACTUAL TESTS START HERE --------------179180// The simplest possible functions have no attributes set181testFirstFn("function f() { }")182testFirstFn("function f(x) { x }")183184// A function referencing a global needs parent scope, and it needs callee185// (because parent scope is passed through callee)186testFirstFn("function f() { x }", 'needsCallee', 'needsParentScope')187188// A function referencing "arguments" will have to be vararg. It also needs189// the callee, as it needs to fill out "arguments.callee".190testFirstFn("function f() { arguments }", 'needsCallee', 'isVarArg')191192// A function referencing "arguments" will have to be vararg. If it is193// strict, it will not have to have a callee, though.194testFirstFn("function f() {'use strict'; arguments }", 'isVarArg', 'isStrict')195196// A function defining "arguments" as a parameter will not be vararg.197testFirstFn("function f(arguments) { arguments }")198199// A function defining "arguments" as a nested function will not be vararg.200testFirstFn("function f() { function arguments() {}; arguments; }")201202// A function defining "arguments" as a local variable will be vararg.203testFirstFn("function f() { var arguments; arguments; }", 'isVarArg', 'needsCallee')204205// A self-referencing function defined as a statement doesn't need a self206// symbol, as it'll rather obtain itself from the parent scope.207testFirstFn("function f() { f() }", 'needsCallee', 'needsParentScope')208209// A self-referencing function defined as an expression needs a self symbol,210// as it can't obtain itself from the parent scope.211testFirstFn("(function f() { f() })", 'needsCallee', 'usesSelfSymbol')212213// A child function accessing parent's variable triggers the need for scope214// in parent215testFirstFn("(function f() { var x; function g() { x } })", 'hasScopeBlock')216217// A child function accessing parent's parameter triggers the need for scope218// in parent219testFirstFn("(function f(x) { function g() { x } })", 'hasScopeBlock')220221// A child function accessing a global variable triggers the need for parent222// scope in parent223testFirstFn("(function f() { function g() { x } })", 'needsParentScope', 'needsCallee')224225// A child function redefining a local variable from its parent should not226// affect the parent function in any way227testFirstFn("(function f() { var x; function g() { var x; x } })")228229// Using "with" on its own doesn't do much.230testFirstFn("(function f() { var o; with(o) {} })")231232// "with" referencing a local variable triggers scoping.233testFirstFn("(function f() { var x; var y; with(x) { y } })", 'hasScopeBlock')234235// "with" referencing a non-local variable triggers parent scope.236testFirstFn("(function f() { var x; with(x) { y } })", 'needsCallee', 'needsParentScope')237238// Nested function using "with" is pretty much the same as the parent239// function needing with.240testFirstFn("(function f() { function g() { var o; with(o) {} } })")241242// Nested function using "with" referencing a local variable.243testFirstFn("(function f() { var x; function g() { var o; with(o) { x } } })", 'hasScopeBlock')244245// Using "eval" triggers pretty much everything. The function even needs to be246// vararg, 'cause we don't know if eval will be using "arguments".247testFirstFn("(function f() { eval() })", 'usesSelfSymbol', 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'hasEval', 'isVarArg', 'allVarsInScope')248249// Nested function using "eval" is almost the same as parent function using250// eval, but at least the parent doesn't have to be vararg.251testFirstFn("(function f() { function g() { eval() } })", 'usesSelfSymbol', 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'allVarsInScope')252253// Function with 250 named parameters is ordinary254testFirstFn("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 }")255256// Function with 251 named parameters is variable arguments257// NOTE: hasScopeBlock should be optimized away. Implementation of JDK-8038942 should take care of it.258testFirstFn("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', 'hasScopeBlock')259260261