1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8.h" 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "test/cctest/compiler/function-tester.h" 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing namespace v8::internal; 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing namespace v8::internal::compiler; 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const char* throws = NULL; 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const char* load_tests[] = { 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var x = a; r = x", "123", "0", 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var x = (r = x)", "undefined", "undefined", 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var x = (a?1:2); r = x", "1", "2", 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "const x = a; r = x", "123", "0", 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "const x = (r = x)", "undefined", "undefined", 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "const x = (a?3:4); r = x", "3", "4", 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "'use strict'; const x = a; r = x", "123", "0", 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "'use strict'; const x = (r = x)", throws, throws, 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "'use strict'; const x = (a?5:6); r = x", "5", "6", 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "'use strict'; let x = a; r = x", "123", "0", 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "'use strict'; let x = (r = x)", throws, throws, 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "'use strict'; let x = (a?7:8); r = x", "7", "8", 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NULL}; 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const char* store_tests[] = { 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var x = 1; x = a; r = x", "123", "0", 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var x = (a?(x=4,2):3); r = x", "2", "3", 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var x = (a?4:5); x = a; r = x", "123", "0", 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "const x = 1; x = a; r = x", "1", "1", 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "const x = (a?(x=4,2):3); r = x", "2", "3", 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "const x = (a?4:5); x = a; r = x", "4", "5", 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Assignments to 'const' are SyntaxErrors, handled by the parser, 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // hence we cannot test them here because they are early errors. 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "'use strict'; let x = 1; x = a; r = x", "123", "0", 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "'use strict'; let x = (a?(x=4,2):3); r = x", throws, "3", 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "'use strict'; let x = (a?4:5); x = a; r = x", "123", "0", 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NULL}; 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const char* bind_tests[] = { 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "if (a) { const x = a }; r = x;", "123", "undefined", 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "for (; a > 0; a--) { const x = a }; r = x", "123", "undefined", 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Re-initialization of variables other than legacy 'const' is not 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // possible due to sane variable scoping, hence no tests here. 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NULL}; 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void RunVariableTests(const char* source, const char* tests[]) { 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FLAG_harmony_scoping = true; 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmbeddedVector<char, 512> buffer; 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; tests[i] != NULL; i += 3) { 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SNPrintF(buffer, source, tests[i]); 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("#%d: %s\n", i / 3, buffer.start()); 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FunctionTester T(buffer.start()); 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check function with non-falsey parameter. 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (tests[i + 1] != throws) { 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> r = v8::Utils::OpenHandle(*CompileRun(tests[i + 1])); 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T.CheckCall(r, T.Val(123), T.Val("result")); 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T.CheckThrows(T.Val(123), T.Val("result")); 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check function with falsey parameter. 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (tests[i + 2] != throws) { 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> r = v8::Utils::OpenHandle(*CompileRun(tests[i + 2])); 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T.CheckCall(r, T.Val(0.0), T.Val("result")); 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T.CheckThrows(T.Val(0.0), T.Val("result")); 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(StackLoadVariables) { 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* source = "(function(a,r) { %s; return r; })"; 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RunVariableTests(source, load_tests); 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(ContextLoadVariables) { 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* source = "(function(a,r) { %s; function f() {x} return r; })"; 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RunVariableTests(source, load_tests); 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(StackStoreVariables) { 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* source = "(function(a,r) { %s; return r; })"; 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RunVariableTests(source, store_tests); 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(ContextStoreVariables) { 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* source = "(function(a,r) { %s; function f() {x} return r; })"; 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RunVariableTests(source, store_tests); 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(StackInitializeVariables) { 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* source = "(function(a,r) { %s; return r; })"; 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RunVariableTests(source, bind_tests); 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(ContextInitializeVariables) { 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* source = "(function(a,r) { %s; function f() {x} return r; })"; 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RunVariableTests(source, bind_tests); 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(SelfReferenceVariable) { 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FunctionTester T("(function self() { return self; })"); 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T.CheckCall(T.function); 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("var self = 'not a function'"); 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T.CheckCall(T.function); 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 122