OLD | NEW |
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 896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
907 if (!bad) { | 907 if (!bad) { |
908 i += input_offset; | 908 i += input_offset; |
909 character_length -= output_adjust; | 909 character_length -= output_adjust; |
910 } | 910 } |
911 } | 911 } |
912 } | 912 } |
913 return character_length; | 913 return character_length; |
914 } | 914 } |
915 | 915 |
916 | 916 |
| 917 TEST(ScopeUsesThisAndArguments) { |
| 918 static const struct { |
| 919 const char* prefix; |
| 920 const char* suffix; |
| 921 } surroundings[] = { |
| 922 { "function f() {", "}" }, |
| 923 { "function f() { \"use strict\";", "}" }, |
| 924 { "\"use strict\"; function f() {", "}" }, |
| 925 { "f = () => {", "}" }, |
| 926 { "f = () => { \"use strict\";", "}" }, |
| 927 { "\"use strict\"; f = () => {", "}" }, |
| 928 }; |
| 929 |
| 930 static const struct { |
| 931 const char* body; |
| 932 bool uses_this; |
| 933 bool uses_arguments; |
| 934 bool inner_uses_this; |
| 935 bool inner_uses_arguments; |
| 936 } source_data[] = { |
| 937 { "", |
| 938 false, false, false, false }, |
| 939 { "return this;", |
| 940 true, false, false, false }, |
| 941 { "return arguments;", |
| 942 false, true, false, false }, |
| 943 { "return arguments[0];", |
| 944 false, true, false, false }, |
| 945 { "return this + arguments[0];", |
| 946 true, true, false, false }, |
| 947 { "return () => this;", |
| 948 false, false, true, false }, |
| 949 { "var x = function () { this.foo = 42 };", |
| 950 false, false, true, false }, |
| 951 { "this.foo = 42;", |
| 952 true, false, false, false }, |
| 953 { "this.foo();", |
| 954 true, false, false, false }, |
| 955 { "if (foo()) { this.f() }", |
| 956 true, false, false, false }, |
| 957 { "if (arguments.length) { this.f() }", |
| 958 true, true, false, false }, |
| 959 { "while (true) { this.f() }", |
| 960 true, false, false, false }, |
| 961 { "if (true) { while (true) this.foo(arguments) }", |
| 962 true, true, false, false }, |
| 963 { "var f = function () { return this }", |
| 964 false, false, true, false }, |
| 965 { "var f = function () { return arguments[0] }", |
| 966 false, false, false, true }, |
| 967 }; |
| 968 |
| 969 i::Isolate* isolate = CcTest::i_isolate(); |
| 970 i::Factory* factory = isolate->factory(); |
| 971 |
| 972 v8::HandleScope handles(CcTest::isolate()); |
| 973 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); |
| 974 v8::Context::Scope context_scope(context); |
| 975 |
| 976 isolate->stack_guard()->SetStackLimit(GetCurrentStackPosition() - 128 * 1024); |
| 977 |
| 978 for (unsigned j = 0; j < ARRAY_SIZE(surroundings); ++j) { |
| 979 for (unsigned i = 0; i < ARRAY_SIZE(source_data); ++i) { |
| 980 int kProgramByteSize = i::StrLength(surroundings[j].prefix) + |
| 981 i::StrLength(surroundings[j].suffix) + |
| 982 i::StrLength(source_data[i].body); |
| 983 i::ScopedVector<char> program(kProgramByteSize + 1); |
| 984 i::SNPrintF(program, "%s%s%s", surroundings[j].prefix, |
| 985 source_data[i].body, surroundings[j].suffix); |
| 986 i::Handle<i::String> source = |
| 987 factory->NewStringFromUtf8(i::CStrVector(program.start())) |
| 988 .ToHandleChecked(); |
| 989 i::Handle<i::Script> script = factory->NewScript(source); |
| 990 i::CompilationInfoWithZone info(script); |
| 991 i::Parser parser(&info); |
| 992 parser.set_allow_arrow_functions(true); |
| 993 info.MarkAsGlobal(); |
| 994 parser.Parse(); |
| 995 CHECK(i::Rewriter::Rewrite(&info)); |
| 996 CHECK(i::Scope::Analyze(&info)); |
| 997 CHECK(info.function() != NULL); |
| 998 |
| 999 i::Scope* scope = info.function()->scope(); |
| 1000 CHECK(scope->is_global_scope()); |
| 1001 CHECK_EQ(1, scope->inner_scopes()->length()); |
| 1002 |
| 1003 i::Scope* inner_scope = scope->inner_scopes()->at(0); |
| 1004 CHECK_EQ(source_data[i].uses_this, inner_scope->uses_this()); |
| 1005 CHECK_EQ(source_data[i].uses_arguments, inner_scope->uses_arguments()); |
| 1006 CHECK_EQ(source_data[i].inner_uses_this, inner_scope->inner_uses_this()); |
| 1007 CHECK_EQ(source_data[i].inner_uses_arguments, |
| 1008 inner_scope->inner_uses_arguments()); |
| 1009 } |
| 1010 } |
| 1011 } |
| 1012 |
| 1013 |
917 TEST(ScopePositions) { | 1014 TEST(ScopePositions) { |
918 v8::internal::FLAG_harmony_scoping = true; | 1015 v8::internal::FLAG_harmony_scoping = true; |
919 | 1016 |
920 // Test the parser for correctly setting the start and end positions | 1017 // Test the parser for correctly setting the start and end positions |
921 // of a scope. We check the scope positions of exactly one scope | 1018 // of a scope. We check the scope positions of exactly one scope |
922 // nested in the global scope of a program. 'inner source' is the | 1019 // nested in the global scope of a program. 'inner source' is the |
923 // source code that determines the part of the source belonging | 1020 // source code that determines the part of the source belonging |
924 // to the nested scope. 'outer_prefix' and 'outer_suffix' are | 1021 // to the nested scope. 'outer_prefix' and 'outer_suffix' are |
925 // parts of the source that belong to the global scope. | 1022 // parts of the source that belong to the global scope. |
926 struct SourceData { | 1023 struct SourceData { |
(...skipping 2413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3340 | 3437 |
3341 // Arrow has more precedence, this is the same as: foo ? bar : (baz = {}) | 3438 // Arrow has more precedence, this is the same as: foo ? bar : (baz = {}) |
3342 "foo ? bar : baz => {}", | 3439 "foo ? bar : baz => {}", |
3343 NULL | 3440 NULL |
3344 }; | 3441 }; |
3345 | 3442 |
3346 static const ParserFlag always_flags[] = {kAllowArrowFunctions}; | 3443 static const ParserFlag always_flags[] = {kAllowArrowFunctions}; |
3347 RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, | 3444 RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, |
3348 always_flags, ARRAY_SIZE(always_flags)); | 3445 always_flags, ARRAY_SIZE(always_flags)); |
3349 } | 3446 } |
OLD | NEW |