jlaskey@3: /* jlaskey@7: * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. jlaskey@3: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. attila@962: * jlaskey@3: * This code is free software; you can redistribute it and/or modify it jlaskey@3: * under the terms of the GNU General Public License version 2 only, as jlaskey@3: * published by the Free Software Foundation. attila@962: * jlaskey@3: * This code is distributed in the hope that it will be useful, but WITHOUT jlaskey@3: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or jlaskey@3: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License jlaskey@3: * version 2 for more details (a copy is included in the LICENSE file that jlaskey@3: * accompanied this code). attila@962: * jlaskey@3: * You should have received a copy of the GNU General Public License version jlaskey@3: * 2 along with this work; if not, write to the Free Software Foundation, jlaskey@3: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. attila@962: * jlaskey@3: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA jlaskey@3: * or visit www.oracle.com if you need additional information or have any jlaskey@3: * questions. jlaskey@3: */ jlaskey@3: jlaskey@3: /** jlaskey@3: * NASHORN-207 : Implement strict mode. jlaskey@3: * jlaskey@3: * @test jlaskey@3: * @run jlaskey@3: */ jlaskey@3: jlaskey@3: // make sure that 'use strict' as first directive inside eval jlaskey@3: // also works the same way (as eval called from strict mode caller). jlaskey@3: jlaskey@3: try { jlaskey@3: eval("'use strict'; foo = 4;"); jlaskey@3: fail("#1 should have thrown ReferenceError"); jlaskey@3: } catch (e) { jlaskey@3: if (! (e instanceof ReferenceError)) { jlaskey@3: fail("#2 expected ReferenceError but got " + e); jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: if (typeof foo !== 'undefined') { jlaskey@3: fail("#3 strict mode eval defined var in global scope!"); jlaskey@3: } jlaskey@3: jlaskey@3: try { jlaskey@3: eval("'use strict'; var let = 23;"); jlaskey@3: fail("#4 should have thrown SyntaxError"); jlaskey@3: } catch (e) { jlaskey@3: if (! (e instanceof SyntaxError)) { jlaskey@3: fail("#5 SyntaxError expected but got " + e); jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: // non-strict mode, some of the future reserved words can be used jlaskey@3: // as identifiers. These include "let", "implements", "yield" etc. jlaskey@3: var let = 30; jlaskey@3: var implements = "hello"; jlaskey@3: function yield() {} jlaskey@3: function public() {} jlaskey@3: var private = false; jlaskey@3: var protected = "hello"; jlaskey@3: var interface = "interface"; jlaskey@3: function f(package) {} jlaskey@3: function static() {} jlaskey@3: jlaskey@3: // in strict mode, arguments does not alias named access jlaskey@3: function func(x, y) { jlaskey@3: 'use strict'; jlaskey@3: jlaskey@3: if (x !== arguments[0]) { jlaskey@3: fail("#6 arguments[0] !== x"); jlaskey@3: } jlaskey@3: jlaskey@3: if (y !== arguments[1]) { jlaskey@3: fail("#7 arguments[1] !== y"); jlaskey@3: } jlaskey@3: jlaskey@3: arguments[0] = 1; jlaskey@3: arguments[1] = 2; jlaskey@3: jlaskey@3: if (x === arguments[0]) { jlaskey@3: fail("#8 arguments[0] === x after assignment to it"); jlaskey@3: } jlaskey@3: jlaskey@3: if (y === arguments[1]) { jlaskey@3: fail("#9 arguments[1] === y after assignment to it "); jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: func(); jlaskey@3: jlaskey@3: // functions can not be declared everywhere!! jlaskey@3: try { jlaskey@3: eval("'use strict'; if (true) { function func() {} }"); jlaskey@3: fail("#10 should have thrown SyntaxError"); jlaskey@3: } catch (e) { jlaskey@3: if (! (e instanceof SyntaxError)) { jlaskey@3: fail("#11 SyntaxError expected got " + e); jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: // arguments.caller and arguments.callee can't read or written in strict mode jlaskey@3: function func2() { jlaskey@3: 'use strict'; jlaskey@3: jlaskey@3: try { jlaskey@3: print(arguments.callee); jlaskey@3: fail("#12 arguments.callee should have thrown TypeError"); jlaskey@3: } catch (e) { jlaskey@3: if (! (e instanceof TypeError)) { jlaskey@3: fail("#13 TypeError expected, got " + e); jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: try { jlaskey@3: print(arguments.caller); jlaskey@3: fail("#14 arguments.caller should have thrown TypeError"); jlaskey@3: } catch (e) { jlaskey@3: if (! (e instanceof TypeError)) { jlaskey@3: fail("#15 TypeError expected, got " + e); jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: try { jlaskey@3: arguments.caller = 10; jlaskey@3: fail("#16 arguments.caller assign should have thrown TypeError"); jlaskey@3: } catch (e) { jlaskey@3: if (! (e instanceof TypeError)) { jlaskey@3: fail("#17 TypeError expected, got " + e); jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: try { jlaskey@3: arguments.callee = true; jlaskey@3: fail("#18 arguments.callee assign should have thrown TypeError"); jlaskey@3: } catch (e) { jlaskey@3: if (! (e instanceof TypeError)) { jlaskey@3: fail("#19 TypeError expected, got " + e); jlaskey@3: } jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: func2(); jlaskey@3: jlaskey@3: // func.caller and func.arguments can't read or written in strict mode jlaskey@3: function func3() { jlaskey@3: 'use strict'; jlaskey@3: jlaskey@3: try { jlaskey@3: print(func3.arguments); jlaskey@3: fail("#20 func.arguments should have thrown TypeError"); jlaskey@3: } catch (e) { jlaskey@3: if (! (e instanceof TypeError)) { jlaskey@3: fail("#21 TypeError expected, got " + e); jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: try { jlaskey@3: print(func3.caller); jlaskey@3: fail("#22 func3.caller should have thrown TypeError"); jlaskey@3: } catch (e) { jlaskey@3: if (! (e instanceof TypeError)) { jlaskey@3: fail("#23 TypeError expected, got " + e); jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: try { jlaskey@3: func3.arguments = 10; jlaskey@3: fail("#24 func3.arguments assign should have thrown TypeError"); jlaskey@3: } catch (e) { jlaskey@3: if (! (e instanceof TypeError)) { jlaskey@3: fail("#25 TypeError expected, got " + e); jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: try { jlaskey@3: func3.caller = true; jlaskey@3: fail("#26 func3.caller assign should have thrown TypeError"); jlaskey@3: } catch (e) { jlaskey@3: if (! (e instanceof TypeError)) { jlaskey@3: fail("#27 TypeError expected, got " + e); jlaskey@3: } jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: func3(); jlaskey@3: jlaskey@3: try { jlaskey@3: eval("function eval() { 'use strict'; }"); jlaskey@3: fail("#28 should have thrown SyntaxError"); jlaskey@3: } catch (e) { jlaskey@3: if (! (e instanceof SyntaxError)) { jlaskey@3: fail("#29 SyntaxError expected, got " + e); jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: function func4() { jlaskey@3: 'use \ jlaskey@3: strict'; jlaskey@3: jlaskey@3: // The use strict directive can't contain line continuation. jlaskey@3: // So this is not a strict mode function!! jlaskey@3: with({}) {} jlaskey@3: } jlaskey@3: jlaskey@3: func4(); jlaskey@3: jlaskey@3: function func5() { jlaskey@3: 'use\u2028strict'; jlaskey@3: jlaskey@3: // The use strict directive can't contain unicode whitespace escapes jlaskey@3: // So this is not a strict mode function!! jlaskey@3: with({}) {} jlaskey@3: } jlaskey@3: jlaskey@3: func5(); jlaskey@3: jlaskey@3: function func6() { jlaskey@3: 'use\u2029strict'; jlaskey@3: jlaskey@3: // The use strict directive can't contain unicode whitespace escapes jlaskey@3: // So this is not a strict mode function!! jlaskey@3: with({}) {} jlaskey@3: } jlaskey@3: jlaskey@3: func6(); jlaskey@3: jlaskey@3: try { jlaskey@3: eval("'bogus directive'; 'use strict'; eval = 10"); jlaskey@3: fail("#30 SyntaxError expected from eval"); jlaskey@3: } catch (e) { jlaskey@3: if (! (e instanceof SyntaxError)) { jlaskey@3: fail("#31 SyntaxError expected but got " + e); jlaskey@3: } jlaskey@3: }