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

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

Issue 1634153002: [Interpreter] Adds support for const/let variables to interpreter. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased the patch. Created 4 years, 10 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
« no previous file with comments | « test/cctest/interpreter/test-bytecode-generator.cc ('k') | test/mjsunit/mjsunit.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/execution.h" 7 #include "src/execution.h"
8 #include "src/handles.h" 8 #include "src/handles.h"
9 #include "src/interpreter/bytecode-array-builder.h" 9 #include "src/interpreter/bytecode-array-builder.h"
10 #include "src/interpreter/interpreter.h" 10 #include "src/interpreter/interpreter.h"
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 : InterpreterTester(isolate, source, MaybeHandle<BytecodeArray>(), 89 : InterpreterTester(isolate, source, MaybeHandle<BytecodeArray>(),
90 MaybeHandle<TypeFeedbackVector>(), filter) {} 90 MaybeHandle<TypeFeedbackVector>(), filter) {}
91 91
92 virtual ~InterpreterTester() {} 92 virtual ~InterpreterTester() {}
93 93
94 template <class... A> 94 template <class... A>
95 InterpreterCallable<A...> GetCallable() { 95 InterpreterCallable<A...> GetCallable() {
96 return InterpreterCallable<A...>(isolate_, GetBytecodeFunction<A...>()); 96 return InterpreterCallable<A...>(isolate_, GetBytecodeFunction<A...>());
97 } 97 }
98 98
99 Local<Message> CheckThrowsReturnMessage() {
100 TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate_));
101 auto callable = GetCallable<>();
102 MaybeHandle<Object> no_result = callable();
103 CHECK(isolate_->has_pending_exception());
104 CHECK(try_catch.HasCaught());
105 CHECK(no_result.is_null());
106 isolate_->OptionalRescheduleException(true);
107 CHECK(!try_catch.Message().IsEmpty());
108 return try_catch.Message();
109 }
110
99 static Handle<Object> NewObject(const char* script) { 111 static Handle<Object> NewObject(const char* script) {
100 return v8::Utils::OpenHandle(*CompileRun(script)); 112 return v8::Utils::OpenHandle(*CompileRun(script));
101 } 113 }
102 114
103 static Handle<String> GetName(Isolate* isolate, const char* name) { 115 static Handle<String> GetName(Isolate* isolate, const char* name) {
104 Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(name); 116 Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(name);
105 return isolate->factory()->string_table()->LookupString(isolate, result); 117 return isolate->factory()->string_table()->LookupString(isolate, result);
106 } 118 }
107 119
108 static std::string SourceForBody(const char* body) { 120 static std::string SourceForBody(const char* body) {
(...skipping 3737 matching lines...) Expand 10 before | Expand all | Expand 10 after
3846 for (size_t i = 0; i < arraysize(examples); ++i) { 3858 for (size_t i = 0; i < arraysize(examples); ++i) {
3847 std::string source(InterpreterTester::SourceForBody(examples[i].first)); 3859 std::string source(InterpreterTester::SourceForBody(examples[i].first));
3848 InterpreterTester tester(handles.main_isolate(), source.c_str()); 3860 InterpreterTester tester(handles.main_isolate(), source.c_str());
3849 auto callable = tester.GetCallable<>(); 3861 auto callable = tester.GetCallable<>();
3850 3862
3851 Handle<i::Object> return_value = callable().ToHandleChecked(); 3863 Handle<i::Object> return_value = callable().ToHandleChecked();
3852 CHECK(return_value->SameValue(*examples[i].second)); 3864 CHECK(return_value->SameValue(*examples[i].second));
3853 } 3865 }
3854 } 3866 }
3855 3867
3868 TEST(InterpreterConstDeclaration) {
3869 HandleAndZoneScope handles;
3870 i::Isolate* isolate = handles.main_isolate();
3871 i::Factory* factory = isolate->factory();
3872
3873 std::pair<const char*, Handle<Object>> const_decl[] = {
3874 {"const x = 3; return x;", handle(Smi::FromInt(3), isolate)},
3875 {"let x = 10; x = x + 20; return x;", handle(Smi::FromInt(30), isolate)},
3876 {"let x = 10; x = 20; return x;", handle(Smi::FromInt(20), isolate)},
3877 {"let x; x = 20; return x;", handle(Smi::FromInt(20), isolate)},
3878 {"let x; return x;", factory->undefined_value()},
3879 {"var x = 10; { let x = 30; } return x;",
3880 handle(Smi::FromInt(10), isolate)},
3881 {"let x = 10; { let x = 20; } return x;",
3882 handle(Smi::FromInt(10), isolate)},
3883 {"var x = 10; eval('let x = 20;'); return x;",
3884 handle(Smi::FromInt(10), isolate)},
3885 {"var x = 10; eval('const x = 20;'); return x;",
3886 handle(Smi::FromInt(10), isolate)},
3887 {"var x = 10; { const x = 20; } return x;",
3888 handle(Smi::FromInt(10), isolate)},
3889 {"var x = 10; { const x = 20; return x;} return -1;",
3890 handle(Smi::FromInt(20), isolate)},
3891 {"var a = 10;\n"
3892 "for (var i = 0; i < 10; ++i) {\n"
3893 " const x = i;\n" // const declarations are block scoped.
3894 " a = a + x;\n"
3895 "}\n"
3896 "return a;\n",
3897 handle(Smi::FromInt(55), isolate)},
3898 };
3899
3900 // Tests for sloppy mode.
3901 for (size_t i = 0; i < arraysize(const_decl); i++) {
3902 std::string source(InterpreterTester::SourceForBody(const_decl[i].first));
3903 InterpreterTester tester(handles.main_isolate(), source.c_str());
3904 auto callable = tester.GetCallable<>();
3905
3906 Handle<i::Object> return_value = callable().ToHandleChecked();
3907 CHECK(return_value->SameValue(*const_decl[i].second));
3908 }
3909
3910 // Tests for strict mode.
3911 for (size_t i = 0; i < arraysize(const_decl); i++) {
3912 std::string strict_body =
3913 "'use strict'; " + std::string(const_decl[i].first);
3914 std::string source(InterpreterTester::SourceForBody(strict_body.c_str()));
3915 InterpreterTester tester(handles.main_isolate(), source.c_str());
3916 auto callable = tester.GetCallable<>();
3917
3918 Handle<i::Object> return_value = callable().ToHandleChecked();
3919 CHECK(return_value->SameValue(*const_decl[i].second));
3920 }
3921 }
3922
3923 TEST(InterpreterConstDeclarationLookupSlots) {
3924 HandleAndZoneScope handles;
3925 i::Isolate* isolate = handles.main_isolate();
3926 i::Factory* factory = isolate->factory();
3927
3928 std::pair<const char*, Handle<Object>> const_decl[] = {
3929 {"const x = 3; function f1() {return x;}; return x;",
3930 handle(Smi::FromInt(3), isolate)},
3931 {"let x = 10; x = x + 20; function f1() {return x;}; return x;",
3932 handle(Smi::FromInt(30), isolate)},
3933 {"let x; x = 20; function f1() {return x;}; return x;",
3934 handle(Smi::FromInt(20), isolate)},
3935 {"let x; function f1() {return x;}; return x;",
3936 factory->undefined_value()},
3937 };
3938
3939 // Tests for sloppy mode.
3940 for (size_t i = 0; i < arraysize(const_decl); i++) {
3941 std::string source(InterpreterTester::SourceForBody(const_decl[i].first));
3942 InterpreterTester tester(handles.main_isolate(), source.c_str());
3943 auto callable = tester.GetCallable<>();
3944
3945 Handle<i::Object> return_value = callable().ToHandleChecked();
3946 CHECK(return_value->SameValue(*const_decl[i].second));
3947 }
3948
3949 // Tests for strict mode.
3950 for (size_t i = 0; i < arraysize(const_decl); i++) {
3951 std::string strict_body =
3952 "'use strict'; " + std::string(const_decl[i].first);
3953 std::string source(InterpreterTester::SourceForBody(strict_body.c_str()));
3954 InterpreterTester tester(handles.main_isolate(), source.c_str());
3955 auto callable = tester.GetCallable<>();
3956
3957 Handle<i::Object> return_value = callable().ToHandleChecked();
3958 CHECK(return_value->SameValue(*const_decl[i].second));
3959 }
3960 }
3961
3962 TEST(InterpreterConstInLookupContextChain) {
3963 HandleAndZoneScope handles;
3964 i::Isolate* isolate = handles.main_isolate();
3965
3966 const char* prologue =
3967 "function OuterMost() {\n"
3968 " const outerConst = 10;\n"
3969 " let outerLet = 20;\n"
3970 " function Outer() {\n"
3971 " function Inner() {\n"
3972 " this.innerFunc = function() { ";
3973 const char* epilogue =
3974 " }\n"
3975 " }\n"
3976 " this.getInnerFunc ="
3977 " function() {return new Inner().innerFunc;}\n"
3978 " }\n"
3979 " this.getOuterFunc ="
3980 " function() {return new Outer().getInnerFunc();}"
3981 "}\n"
3982 "var f = new OuterMost().getOuterFunc();\n"
3983 "f();\n";
3984 std::pair<const char*, Handle<Object>> const_decl[] = {
3985 {"return outerConst;", handle(Smi::FromInt(10), isolate)},
3986 {"return outerLet;", handle(Smi::FromInt(20), isolate)},
3987 {"outerLet = 30; return outerLet;", handle(Smi::FromInt(30), isolate)},
3988 {"var outerLet = 40; return outerLet;",
3989 handle(Smi::FromInt(40), isolate)},
3990 {"var outerConst = 50; return outerConst;",
3991 handle(Smi::FromInt(50), isolate)},
3992 {"try { outerConst = 30 } catch(e) { return -1; }",
3993 handle(Smi::FromInt(-1), isolate)}};
3994
3995 for (size_t i = 0; i < arraysize(const_decl); i++) {
3996 std::string script = std::string(prologue) +
3997 std::string(const_decl[i].first) +
3998 std::string(epilogue);
3999 InterpreterTester tester(handles.main_isolate(), script.c_str(), "*");
4000 auto callable = tester.GetCallable<>();
4001
4002 Handle<i::Object> return_value = callable().ToHandleChecked();
4003 CHECK(return_value->SameValue(*const_decl[i].second));
4004 }
4005
4006 // Tests for Legacy constant.
4007 bool old_flag_legacy_const = FLAG_legacy_const;
4008 FLAG_legacy_const = true;
4009
4010 std::pair<const char*, Handle<Object>> legacy_const_decl[] = {
4011 {"return outerConst = 23;", handle(Smi::FromInt(23), isolate)},
4012 {"outerConst = 30; return outerConst;",
4013 handle(Smi::FromInt(10), isolate)},
4014 };
4015
4016 for (size_t i = 0; i < arraysize(legacy_const_decl); i++) {
4017 std::string script = std::string(prologue) +
4018 std::string(legacy_const_decl[i].first) +
4019 std::string(epilogue);
4020 InterpreterTester tester(handles.main_isolate(), script.c_str(), "*");
4021 auto callable = tester.GetCallable<>();
4022
4023 Handle<i::Object> return_value = callable().ToHandleChecked();
4024 CHECK(return_value->SameValue(*legacy_const_decl[i].second));
4025 }
4026
4027 FLAG_legacy_const = old_flag_legacy_const;
4028 }
4029
4030 TEST(InterpreterIllegalConstDeclaration) {
4031 HandleAndZoneScope handles;
4032
4033 std::pair<const char*, const char*> const_decl[] = {
4034 {"const x = x = 10 + 3; return x;",
4035 "Uncaught ReferenceError: x is not defined"},
4036 {"const x = 10; x = 20; return x;",
4037 "Uncaught TypeError: Assignment to constant variable."},
4038 {"const x = 10; { x = 20; } return x;",
4039 "Uncaught TypeError: Assignment to constant variable."},
4040 {"const x = 10; eval('x = 20;'); return x;",
4041 "Uncaught TypeError: Assignment to constant variable."},
4042 {"let x = x + 10; return x;",
4043 "Uncaught ReferenceError: x is not defined"},
4044 {"'use strict'; (function f1() { f1 = 123; })() ",
4045 "Uncaught TypeError: Assignment to constant variable."},
4046 };
4047
4048 // Tests for sloppy mode.
4049 for (size_t i = 0; i < arraysize(const_decl); i++) {
4050 std::string source(InterpreterTester::SourceForBody(const_decl[i].first));
4051 InterpreterTester tester(handles.main_isolate(), source.c_str());
4052 v8::Local<v8::String> message = tester.CheckThrowsReturnMessage()->Get();
4053 v8::Local<v8::String> expected_string = v8_str(const_decl[i].second);
4054 CHECK(
4055 message->Equals(CcTest::isolate()->GetCurrentContext(), expected_string)
4056 .FromJust());
4057 }
4058
4059 // Tests for strict mode.
4060 for (size_t i = 0; i < arraysize(const_decl); i++) {
4061 std::string strict_body =
4062 "'use strict'; " + std::string(const_decl[i].first);
4063 std::string source(InterpreterTester::SourceForBody(strict_body.c_str()));
4064 InterpreterTester tester(handles.main_isolate(), source.c_str());
4065 v8::Local<v8::String> message = tester.CheckThrowsReturnMessage()->Get();
4066 v8::Local<v8::String> expected_string = v8_str(const_decl[i].second);
4067 CHECK(
4068 message->Equals(CcTest::isolate()->GetCurrentContext(), expected_string)
4069 .FromJust());
4070 }
4071 }
4072
4073 TEST(InterpreterLegacyConstDeclaration) {
4074 bool old_flag_legacy_const = FLAG_legacy_const;
4075 FLAG_legacy_const = true;
4076
4077 HandleAndZoneScope handles;
4078 i::Isolate* isolate = handles.main_isolate();
4079
4080 std::pair<const char*, Handle<Object>> const_decl[] = {
4081 {"const x = (x = 10) + 3; return x;", handle(Smi::FromInt(13), isolate)},
4082 {"const x = 10; x = 20; return x;", handle(Smi::FromInt(10), isolate)},
4083 {"var a = 10;\n"
4084 "for (var i = 0; i < 10; ++i) {\n"
4085 " const x = i;\n" // Legacy constants are not block scoped.
4086 " a = a + x;\n"
4087 "}\n"
4088 "return a;\n",
4089 handle(Smi::FromInt(10), isolate)},
4090 {"const x = 20; eval('x = 10;'); return x;",
4091 handle(Smi::FromInt(20), isolate)},
4092 };
4093
4094 for (size_t i = 0; i < arraysize(const_decl); i++) {
4095 std::string source(InterpreterTester::SourceForBody(const_decl[i].first));
4096 InterpreterTester tester(handles.main_isolate(), source.c_str());
4097 auto callable = tester.GetCallable<>();
4098
4099 Handle<i::Object> return_value = callable().ToHandleChecked();
4100 CHECK(return_value->SameValue(*const_decl[i].second));
4101 }
4102
4103 FLAG_legacy_const = old_flag_legacy_const;
4104 }
4105
3856 } // namespace interpreter 4106 } // namespace interpreter
3857 } // namespace internal 4107 } // namespace internal
3858 } // namespace v8 4108 } // namespace v8
OLDNEW
« no previous file with comments | « test/cctest/interpreter/test-bytecode-generator.cc ('k') | test/mjsunit/mjsunit.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698