# HG changeset patch # User attila # Date 1359989984 -3600 # Node ID 18e55b352d56e1a0c9deb1e20614786b3ab2415a # Parent 0d15274b2326ba597381d40f91d81aec7ff95e4a 8007460: var assignment to a parameter in a varargs method causes compilation error Reviewed-by: jlaskey, lagergren diff -r 0d15274b2326 -r 18e55b352d56 nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java Mon Feb 04 08:13:05 2013 -0400 +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java Mon Feb 04 15:59:44 2013 +0100 @@ -201,10 +201,7 @@ final Symbol symbol = identNode.getSymbol(); if (!symbol.isScope()) { - if(symbol.isParam()) { - return method.loadParam(symbol); - } - assert symbol.hasSlot() && symbol.getSlot() != 0 || symbol.isThis(); + assert symbol.hasSlot() || symbol.isParam(); return method.load(symbol); } @@ -3200,11 +3197,7 @@ } } else { assert symbol != null; - if(symbol.isParam()) { - method.storeParam(symbol); - } else { - method.store(symbol); - } + method.store(symbol); } return null; diff -r 0d15274b2326 -r 18e55b352d56 nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java --- a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java Mon Feb 04 08:13:05 2013 -0400 +++ b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java Mon Feb 04 15:59:44 2013 +0100 @@ -829,44 +829,26 @@ public MethodEmitter load(final Symbol symbol) { assert symbol != null; if (symbol.hasSlot()) { - debug("load symbol", symbol.getName() + " slot=" + symbol.getSlot()); - pushType(symbol.getSymbolType().load(method, symbol.getSlot())); - } - return this; - } - - /** - * Push a non-scope function parameter to the stack. Function parameters always arrive into a function as either - * explicit parameters on the stack, or collected into a final variable-arity {@code Object[]} parameter. If they - * end up being scoped (i.e. referenced from a child function or eval), then they're loaded as scoped symbols and - * this function is not invoked for them. If they aren't scoped, then they will be loaded from one of three places. - * First, if the function has an Arguments object, they're loaded from it. Otherwise, if the parameters come in a - * {@code Object[]} array, they are loaded from the array. Finally, if neither is the case, they're simply loaded - * from their bytecode slot. - * - * @param symbol the symbol representing the parameter. - * - * @return the method emitter - */ - public MethodEmitter loadParam(final Symbol symbol) { - assert symbol != null && symbol.isParam() && !symbol.isScope(); - if(symbol.hasSlot()) { - // Check that we aren't vararg, except if we're loading "this" - assert symbol.isThis() || !functionNode.isVarArg() : "Symbol=" + symbol + " functionNode=" + functionNode.getName(); - // Just load it from a local variable - return load(symbol); - } - assert functionNode.isVarArg(); - if(functionNode.needsArguments()) { - // ScriptObject.getArgument(int) on arguments - loadArguments(); - load(symbol.getFieldIndex()); - ScriptObject.GET_ARGUMENT.invoke(this); - } else { - // array load from __varargs__ - loadVarArgs(); - load(symbol.getFieldIndex()); - arrayload(); + final int slot = symbol.getSlot(); + debug("load symbol", symbol.getName(), " slot=", slot); + pushType(symbol.getSymbolType().load(method, slot)); + } else if (symbol.isParam()) { + assert !symbol.isScope(); + assert functionNode.isVarArg() : "Non-vararg functions have slotted parameters"; + final int index = symbol.getFieldIndex(); + if(functionNode.needsArguments()) { + // ScriptObject.getArgument(int) on arguments + debug("load symbol", symbol.getName(), " arguments index=", index); + loadArguments(); + load(index); + ScriptObject.GET_ARGUMENT.invoke(this); + } else { + // array load from __varargs__ + debug("load symbol", symbol.getName(), " array index=", index); + loadVarArgs(); + load(symbol.getFieldIndex()); + arrayload(); + } } return this; } @@ -1033,46 +1015,29 @@ public void store(final Symbol symbol) { assert symbol != null : "No symbol to store"; if (symbol.hasSlot()) { - debug("store", symbol); - popType(symbol.getSymbolType()).store(method, symbol.getSlot()); + final int slot = symbol.getSlot(); + debug("store symbol", symbol.getName(), " slot=", slot); + popType(symbol.getSymbolType()).store(method, slot); + } else if (symbol.isParam()) { + assert !symbol.isScope(); + assert functionNode.isVarArg() : "Non-vararg functions have slotted parameters"; + final int index = symbol.getFieldIndex(); + if(functionNode.needsArguments()) { + debug("store symbol", symbol.getName(), " arguments index=", index); + loadArguments(); + load(index); + ArgumentSetter.SET_ARGUMENT.invoke(this); + } else { + // varargs without arguments object - just do array store to __varargs__ + debug("store symbol", symbol.getName(), " array index=", index); + loadVarArgs(); + load(index); + ArgumentSetter.SET_ARRAY_ELEMENT.invoke(this); + } } } /** - * Pop a value from the stack and store it in a non-scope function parameter. Function parameters always arrive into - * a function as either explicit parameters on th stack, or collected into a final variable-arity {@code Object[]} - * parameter. If they end up being scoped (i.e. referenced from a child function or eval), then they're stored as - * scoped symbols are and this function is not invoked for them. If they aren't scoped, then they will be stored - * to one of three places. First, if the function has an Arguments object, they're stored to it. Otherwise, if the - * parameters come in a {@code Object[]} array, they are stored to the array. Finally, if neither is the case, - * they're simply stored to their bytecode slot. - * - * @param symbol the symbol representing the parameter. - * - */ - public void storeParam(final Symbol symbol) { - assert symbol != null && symbol.isParam() && !symbol.isScope(); - if(symbol.hasSlot()) { - assert !functionNode.isVarArg(); - // Just store it to a local variable - store(symbol); - return; - } - assert functionNode.isVarArg(); - if(functionNode.needsArguments()) { - loadArguments(); - load(symbol.getFieldIndex()); - ArgumentSetter.SET_ARGUMENT.invoke(this); - } else { - // varargs without arguments object - just do array store to __varargs__ - loadVarArgs(); - load(symbol.getFieldIndex()); - ArgumentSetter.SET_ARRAY_ELEMENT.invoke(this); - } - } - - - /** * Pop a value from the stack and store it in a given local variable * slot. * diff -r 0d15274b2326 -r 18e55b352d56 nashorn/test/script/basic/JDK-8007460.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8007460.js Mon Feb 04 15:59:44 2013 +0100 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8007460: code generation error for variable-argument function that has a var-assignment to one of its parameters + * + * @test + * @run + */ + +function f(y) { + print(y) + print(arguments[0]) + + var y = 1 + + print(y) + print(arguments[0]) +} +f(2) \ No newline at end of file diff -r 0d15274b2326 -r 18e55b352d56 nashorn/test/script/basic/JDK-8007460.js.EXPECTED --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8007460.js.EXPECTED Mon Feb 04 15:59:44 2013 +0100 @@ -0,0 +1,4 @@ +2 +2 +1 +1