Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(97)

Side by Side Diff: test/cctest/test-parsing.cc

Issue 422923004: Track usage of "this" and "arguments" in Scope (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Do not propagate inner_uses_$foo out of normal functions, more tests Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/scopes.cc ('K') | « src/scopes.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 if (!bad) { 910 if (!bad) {
911 i += input_offset; 911 i += input_offset;
912 character_length -= output_adjust; 912 character_length -= output_adjust;
913 } 913 }
914 } 914 }
915 } 915 }
916 return character_length; 916 return character_length;
917 } 917 }
918 918
919 919
920 TEST(ScopeUsesThisAndArguments) {
921 static const struct {
922 const char* prefix;
923 const char* suffix;
924 } surroundings[] = {
925 { "function f() {", "}" },
926 { "var f = () => {", "}" },
927 };
928
929 static const struct {
930 const char* body;
931 bool uses_this;
932 bool uses_arguments;
933 bool inner_uses_this;
934 bool inner_uses_arguments;
935 } source_data[] = {
936 { "",
937 false, false, false, false },
938 { "return this",
939 true, false, false, false },
940 { "return arguments",
941 false, true, false, false },
942 { "return arguments[0]",
943 false, true, false, false },
944 { "return this + arguments[0]",
945 true, true, false, false },
946 { "return x => this + x",
947 false, false, true, false },
948 { "this.foo = 42;",
949 true, false, false, false },
950 { "this.foo();",
951 true, false, false, false },
952 { "if (foo()) { this.f() }",
953 true, false, false, false },
954 { "if (arguments.length) { this.f() }",
955 true, true, false, false },
956 { "while (true) { this.f() }",
957 true, false, false, false },
958 { "if (true) { while (true) this.foo(arguments) }",
959 true, true, false, false },
960 // Multiple nesting levels must work as well.
961 { "while (true) { while (true) { while (true) return this } }",
962 true, false, false, false },
963 { "if (1) { return () => { while (true) new this() } }",
964 false, false, true, false },
965 // Note that propagation of the inner_uses_this() value does not
966 // cross boundaries of normal functions onto parent scopes.
967 { "return function (x) { return this + x }",
968 false, false, false, false },
969 { "var x = function () { this.foo = 42 };",
970 false, false, false, false },
971 { "if (1) { return function () { while (true) new this() } }",
972 false, false, false, false },
973 { "return function (x) { return () => this }",
974 false, false, false, false },
975 // Flags must be correctly set when using block scoping.
976 { "\"use strict\"; while (true) { let x; this, arguments; }",
977 false, false, true, true },
978 { "\"use strict\"; if (foo()) { let x; this.f() }",
979 false, false, true, false },
980 { "\"use strict\"; if (1) {"
981 " let x; return function () { return this + arguments }"
982 "}",
983 false, false, false, false },
984 };
985
986 i::Isolate* isolate = CcTest::i_isolate();
987 i::Factory* factory = isolate->factory();
988
989 v8::HandleScope handles(CcTest::isolate());
990 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
991 v8::Context::Scope context_scope(context);
992
993 isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
994 128 * 1024);
995
996 for (unsigned j = 0; j < arraysize(surroundings); ++j) {
997 for (unsigned i = 0; i < arraysize(source_data); ++i) {
998 int kProgramByteSize = i::StrLength(surroundings[j].prefix) +
999 i::StrLength(surroundings[j].suffix) +
1000 i::StrLength(source_data[i].body);
1001 i::ScopedVector<char> program(kProgramByteSize + 1);
1002 i::SNPrintF(program, "%s%s%s", surroundings[j].prefix,
1003 source_data[i].body, surroundings[j].suffix);
1004 i::Handle<i::String> source =
1005 factory->NewStringFromUtf8(i::CStrVector(program.start()))
1006 .ToHandleChecked();
1007 i::Handle<i::Script> script = factory->NewScript(source);
1008 i::CompilationInfoWithZone info(script);
1009 i::Parser::ParseInfo parse_info = {isolate->stack_guard()->real_climit(),
1010 isolate->heap()->HashSeed(),
1011 isolate->unicode_cache()};
1012 i::Parser parser(&info, &parse_info);
1013 parser.set_allow_arrow_functions(true);
1014 parser.set_allow_harmony_scoping(true);
1015 info.MarkAsGlobal();
1016 parser.Parse();
1017 CHECK(i::Rewriter::Rewrite(&info));
1018 CHECK(i::Scope::Analyze(&info));
1019 CHECK(info.function() != NULL);
1020
1021 i::Scope* global_scope = info.function()->scope();
1022 CHECK(global_scope->is_global_scope());
1023 CHECK_EQ(1, global_scope->inner_scopes()->length());
1024
1025 i::Scope* scope = global_scope->inner_scopes()->at(0);
1026 CHECK_EQ(source_data[i].uses_this, scope->uses_this());
1027 CHECK_EQ(source_data[i].uses_arguments, scope->uses_arguments());
1028 CHECK_EQ(source_data[i].inner_uses_this, scope->inner_uses_this());
1029 CHECK_EQ(source_data[i].inner_uses_arguments,
1030 scope->inner_uses_arguments());
1031 }
1032 }
1033 }
1034
1035
920 TEST(ScopePositions) { 1036 TEST(ScopePositions) {
921 v8::internal::FLAG_harmony_scoping = true; 1037 v8::internal::FLAG_harmony_scoping = true;
922 1038
923 // Test the parser for correctly setting the start and end positions 1039 // Test the parser for correctly setting the start and end positions
924 // of a scope. We check the scope positions of exactly one scope 1040 // of a scope. We check the scope positions of exactly one scope
925 // nested in the global scope of a program. 'inner source' is the 1041 // nested in the global scope of a program. 'inner source' is the
926 // source code that determines the part of the source belonging 1042 // source code that determines the part of the source belonging
927 // to the nested scope. 'outer_prefix' and 'outer_suffix' are 1043 // to the nested scope. 'outer_prefix' and 'outer_suffix' are
928 // parts of the source that belong to the global scope. 1044 // parts of the source that belong to the global scope.
929 struct SourceData { 1045 struct SourceData {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
967 " }", "\n" 1083 " }", "\n"
968 " more;", i::BLOCK_SCOPE, i::STRICT }, 1084 " more;", i::BLOCK_SCOPE, i::STRICT },
969 { " start;\n" 1085 { " start;\n"
970 " function fun", "(a,b) { infunction; }", " more;", 1086 " function fun", "(a,b) { infunction; }", " more;",
971 i::FUNCTION_SCOPE, i::SLOPPY }, 1087 i::FUNCTION_SCOPE, i::SLOPPY },
972 { " start;\n" 1088 { " start;\n"
973 " function fun", "(a,b) {\n" 1089 " function fun", "(a,b) {\n"
974 " infunction;\n" 1090 " infunction;\n"
975 " }", "\n" 1091 " }", "\n"
976 " more;", i::FUNCTION_SCOPE, i::SLOPPY }, 1092 " more;", i::FUNCTION_SCOPE, i::SLOPPY },
977 // TODO(aperez): Change to use i::ARROW_SCOPE when implemented
978 { " start;\n", "(a,b) => a + b", "; more;", 1093 { " start;\n", "(a,b) => a + b", "; more;",
979 i::FUNCTION_SCOPE, i::SLOPPY }, 1094 i::ARROW_SCOPE, i::SLOPPY },
980 { " start;\n", "(a,b) => { return a+b; }", "\nmore;", 1095 { " start;\n", "(a,b) => { return a+b; }", "\nmore;",
981 i::FUNCTION_SCOPE, i::SLOPPY }, 1096 i::ARROW_SCOPE, i::SLOPPY },
982 { " start;\n" 1097 { " start;\n"
983 " (function fun", "(a,b) { infunction; }", ")();", 1098 " (function fun", "(a,b) { infunction; }", ")();",
984 i::FUNCTION_SCOPE, i::SLOPPY }, 1099 i::FUNCTION_SCOPE, i::SLOPPY },
985 { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;", 1100 { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;",
986 i::BLOCK_SCOPE, i::STRICT }, 1101 i::BLOCK_SCOPE, i::STRICT },
987 { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", "; more;", 1102 { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", "; more;",
988 i::BLOCK_SCOPE, i::STRICT }, 1103 i::BLOCK_SCOPE, i::STRICT },
989 { " for ", "(let x = 1 ; x < 10; ++ x) {\n" 1104 { " for ", "(let x = 1 ; x < 10; ++ x) {\n"
990 " block;\n" 1105 " block;\n"
991 " }", "\n" 1106 " }", "\n"
(...skipping 3088 matching lines...) Expand 10 before | Expand all | Expand 10 after
4080 4195
4081 const char* name_data[] = { 4196 const char* name_data[] = {
4082 "function* g() { ({yield}); }", 4197 "function* g() { ({yield}); }",
4083 NULL 4198 NULL
4084 }; 4199 };
4085 4200
4086 static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals}; 4201 static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
4087 RunParserSyncTest(context_data, name_data, kError, NULL, 0, 4202 RunParserSyncTest(context_data, name_data, kError, NULL, 0,
4088 always_flags, arraysize(always_flags)); 4203 always_flags, arraysize(always_flags));
4089 } 4204 }
OLDNEW
« src/scopes.cc ('K') | « src/scopes.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698