# HG changeset patch # User sundar # Date 1442494433 -19800 # Node ID 67bab332bcb3344024abeb24bcea91295075f8dc # Parent d62c5288738a2eeb0e3ffbd02283aeff951717d3 8136694: Megemorphic scope access does not throw ReferenceError when property is missing Reviewed-by: attila, hannesw diff -r d62c5288738a -r 67bab332bcb3 src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java Wed Sep 16 18:44:47 2015 +0200 +++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java Thu Sep 17 18:23:53 2015 +0530 @@ -2402,17 +2402,15 @@ */ protected Object invokeNoSuchProperty(final String name, final boolean isScope, final int programPoint) { final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true); + final Object func = (find != null)? find.getObjectValue() : null; Object ret = UNDEFINED; - - if (find != null) { - final Object func = find.getObjectValue(); - - if (func instanceof ScriptFunction) { - final ScriptFunction sfunc = (ScriptFunction)func; - final Object self = isScope && sfunc.isStrict()? UNDEFINED : this; - ret = ScriptRuntime.apply(sfunc, self, name); - } + if (func instanceof ScriptFunction) { + final ScriptFunction sfunc = (ScriptFunction)func; + final Object self = isScope && sfunc.isStrict()? UNDEFINED : this; + ret = ScriptRuntime.apply(sfunc, self, name); + } else if (isScope) { + throw referenceError("not.defined", name); } if (isValid(programPoint)) { @@ -2438,6 +2436,9 @@ final Object value = find.getObjectValue(); if (!(value instanceof ScriptFunction)) { + if (isScope) { + throw referenceError("not.defined", name); + } return UNDEFINED; } diff -r d62c5288738a -r 67bab332bcb3 test/script/basic/JDK-8044750.js --- a/test/script/basic/JDK-8044750.js Wed Sep 16 18:44:47 2015 +0200 +++ b/test/script/basic/JDK-8044750.js Thu Sep 17 18:23:53 2015 +0530 @@ -25,6 +25,8 @@ * JDK-8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook * * @test + * @fork + * @option -Dnashorn.unstable.relink.threshold=16 * @run */ @@ -40,7 +42,9 @@ } } -for (var i = 0; i < 20; i++) { +var LIMIT = 20; // should be more than megamorphic threshold set via @option + +for (var i = 0; i < LIMIT; i++) { var obj = {}; obj.foo = i; obj[i] = i; @@ -51,3 +55,30 @@ // callsite inside func should see __noSuchProperty__ // hook on global scope object. func({}); + +function checkFoo() { + with({}) { + try { + foo; + return true; + } catch (e) { + return false; + } + } +} + +var oldNoSuchProperty = this.__noSuchProperty__; +delete this.__noSuchProperty__; + +// keep deleting/restorting __noSuchProperty__ alternatively +// to make "foo" access in checkFoo function megamorphic! + +for (var i = 0; i < LIMIT; i++) { + // no __noSuchProperty__ and 'with' scope object has no 'foo' + delete __noSuchProperty__; + Assert.assertFalse(checkFoo(), "Expected false in iteration " + i); + + // __noSuchProperty__ is exists but 'with' scope object has no 'foo' + this.__noSuchProperty__ = oldNoSuchProperty; + Assert.assertTrue(checkFoo(), "Expected true in iteration " + i); +} diff -r d62c5288738a -r 67bab332bcb3 test/script/basic/JDK-8136694.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8136694.js Thu Sep 17 18:23:53 2015 +0530 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2015, 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-8136694: Megemorphic scope access does not throw ReferenceError when property is missing + * + * @test + * @fork + * @option -Dnashorn.unstable.relink.threshold=16 + * @run + */ + +function checkFoo() { + try { + // The 'foo' access becomes megamorphic + foo; + return true; + } catch (e) { + return false; + } +} + + +// Similar check for 'with' blocks as well. +function checkFooInWith() { + with({}) { + try { + // The 'foo' access becomes megamorphic + foo; + return true; + } catch (e) { + return false; + } + } +} + +function loop(checker) { + // LIMIT has to be more than the megamorphic threashold + // set via @option in this test header! + var LIMIT = 20; + for (var i = 0; i < LIMIT; i++) { + // make sure global has no "foo" + delete foo; + Assert.assertFalse(checker(), "Expected false in interation " + i); + + // now add 'foo' in global + foo = 44; + Assert.assertTrue(checker(), "Expected true in interation " + i); + } +} + + +loop(checkFoo); +loop(checkFooInWith);