OLD | NEW |
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" |
11 #include "test/cctest/cctest.h" | 11 #include "test/cctest/cctest.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 namespace interpreter { | 15 namespace interpreter { |
16 | 16 |
| 17 |
| 18 static MaybeHandle<Object> CallInterpreter(Isolate* isolate, |
| 19 Handle<JSFunction> function) { |
| 20 return Execution::Call(isolate, function, |
| 21 isolate->factory()->undefined_value(), 0, nullptr, |
| 22 false); |
| 23 } |
| 24 |
| 25 |
| 26 template <class... A> |
| 27 static MaybeHandle<Object> CallInterpreter(Isolate* isolate, |
| 28 Handle<JSFunction> function, |
| 29 A... args) { |
| 30 Handle<Object> argv[] = { args... }; |
| 31 return Execution::Call(isolate, function, |
| 32 isolate->factory()->undefined_value(), sizeof...(args), |
| 33 argv, false); |
| 34 } |
| 35 |
| 36 |
| 37 template <class... A> |
17 class InterpreterCallable { | 38 class InterpreterCallable { |
18 public: | 39 public: |
19 InterpreterCallable(Isolate* isolate, Handle<JSFunction> function) | 40 InterpreterCallable(Isolate* isolate, Handle<JSFunction> function) |
20 : isolate_(isolate), function_(function) {} | 41 : isolate_(isolate), function_(function) {} |
21 virtual ~InterpreterCallable() {} | 42 virtual ~InterpreterCallable() {} |
22 | 43 |
23 MaybeHandle<Object> operator()() { | 44 MaybeHandle<Object> operator()(A... args) { |
24 return Execution::Call(isolate_, function_, | 45 return CallInterpreter(isolate_, function_, args...); |
25 isolate_->factory()->undefined_value(), 0, nullptr, | |
26 false); | |
27 } | 46 } |
28 | 47 |
29 private: | 48 private: |
30 Isolate* isolate_; | 49 Isolate* isolate_; |
31 Handle<JSFunction> function_; | 50 Handle<JSFunction> function_; |
32 }; | 51 }; |
33 | 52 |
| 53 |
34 class InterpreterTester { | 54 class InterpreterTester { |
35 public: | 55 public: |
36 InterpreterTester(Isolate* isolate, Handle<BytecodeArray> bytecode) | 56 InterpreterTester(Isolate* isolate, Handle<BytecodeArray> bytecode) |
37 : isolate_(isolate), function_(GetBytecodeFunction(isolate, bytecode)) { | 57 : isolate_(isolate), bytecode_(bytecode) { |
38 i::FLAG_ignition = true; | 58 i::FLAG_ignition = true; |
39 // Ensure handler table is generated. | 59 // Ensure handler table is generated. |
40 isolate->interpreter()->Initialize(); | 60 isolate->interpreter()->Initialize(); |
41 } | 61 } |
42 virtual ~InterpreterTester() {} | 62 virtual ~InterpreterTester() {} |
43 | 63 |
44 InterpreterCallable GetCallable() { | 64 template <class... A> |
45 return InterpreterCallable(isolate_, function_); | 65 InterpreterCallable<A...> GetCallable() { |
| 66 return InterpreterCallable<A...>(isolate_, GetBytecodeFunction<A...>()); |
46 } | 67 } |
47 | 68 |
48 private: | 69 private: |
49 Isolate* isolate_; | 70 Isolate* isolate_; |
50 Handle<JSFunction> function_; | 71 Handle<BytecodeArray> bytecode_; |
51 | 72 |
52 static Handle<JSFunction> GetBytecodeFunction( | 73 template <class... A> |
53 Isolate* isolate, Handle<BytecodeArray> bytecode_array) { | 74 Handle<JSFunction> GetBytecodeFunction() { |
| 75 int arg_count = sizeof...(A); |
| 76 std::string function_text("(function("); |
| 77 for (int i = 0; i < arg_count; i++) { |
| 78 function_text += i == 0 ? "a" : ", a"; |
| 79 } |
| 80 function_text += "){})"; |
| 81 |
54 Handle<JSFunction> function = v8::Utils::OpenHandle( | 82 Handle<JSFunction> function = v8::Utils::OpenHandle( |
55 *v8::Handle<v8::Function>::Cast(CompileRun("(function(){})"))); | 83 *v8::Handle<v8::Function>::Cast(CompileRun(function_text.c_str()))); |
56 function->ReplaceCode(*isolate->builtins()->InterpreterEntryTrampoline()); | 84 function->ReplaceCode(*isolate_->builtins()->InterpreterEntryTrampoline()); |
57 function->shared()->set_function_data(*bytecode_array); | 85 function->shared()->set_function_data(*bytecode_); |
58 return function; | 86 return function; |
59 } | 87 } |
60 | 88 |
61 DISALLOW_COPY_AND_ASSIGN(InterpreterTester); | 89 DISALLOW_COPY_AND_ASSIGN(InterpreterTester); |
62 }; | 90 }; |
63 | 91 |
64 } // namespace interpreter | 92 } // namespace interpreter |
65 } // namespace internal | 93 } // namespace internal |
66 } // namespace v8 | 94 } // namespace v8 |
67 | 95 |
68 using v8::internal::BytecodeArray; | 96 using v8::internal::BytecodeArray; |
69 using v8::internal::Handle; | 97 using v8::internal::Handle; |
70 using v8::internal::Object; | 98 using v8::internal::Object; |
71 using v8::internal::Smi; | 99 using v8::internal::Smi; |
72 using v8::internal::Token; | 100 using v8::internal::Token; |
73 using namespace v8::internal::interpreter; | 101 using namespace v8::internal::interpreter; |
74 | 102 |
75 TEST(TestInterpreterReturn) { | 103 TEST(InterpreterReturn) { |
76 InitializedHandleScope handles; | 104 InitializedHandleScope handles; |
77 Handle<Object> undefined_value = | 105 Handle<Object> undefined_value = |
78 handles.main_isolate()->factory()->undefined_value(); | 106 handles.main_isolate()->factory()->undefined_value(); |
79 | 107 |
80 BytecodeArrayBuilder builder(handles.main_isolate()); | 108 BytecodeArrayBuilder builder(handles.main_isolate()); |
81 builder.set_locals_count(0); | 109 builder.set_locals_count(0); |
| 110 builder.set_parameter_count(1); |
82 builder.Return(); | 111 builder.Return(); |
83 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 112 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
84 | 113 |
85 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 114 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
86 InterpreterCallable callable(tester.GetCallable()); | 115 auto callable = tester.GetCallable<>(); |
87 Handle<Object> return_val = callable().ToHandleChecked(); | 116 Handle<Object> return_val = callable().ToHandleChecked(); |
88 CHECK(return_val.is_identical_to(undefined_value)); | 117 CHECK(return_val.is_identical_to(undefined_value)); |
89 } | 118 } |
90 | 119 |
91 | 120 |
92 TEST(TestInterpreterLoadUndefined) { | 121 TEST(InterpreterLoadUndefined) { |
93 InitializedHandleScope handles; | 122 InitializedHandleScope handles; |
94 Handle<Object> undefined_value = | 123 Handle<Object> undefined_value = |
95 handles.main_isolate()->factory()->undefined_value(); | 124 handles.main_isolate()->factory()->undefined_value(); |
96 | 125 |
97 BytecodeArrayBuilder builder(handles.main_isolate()); | 126 BytecodeArrayBuilder builder(handles.main_isolate()); |
98 builder.set_locals_count(0); | 127 builder.set_locals_count(0); |
| 128 builder.set_parameter_count(1); |
99 builder.LoadUndefined().Return(); | 129 builder.LoadUndefined().Return(); |
100 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 130 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
101 | 131 |
102 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 132 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
103 InterpreterCallable callable(tester.GetCallable()); | 133 auto callable = tester.GetCallable<>(); |
104 Handle<Object> return_val = callable().ToHandleChecked(); | 134 Handle<Object> return_val = callable().ToHandleChecked(); |
105 CHECK(return_val.is_identical_to(undefined_value)); | 135 CHECK(return_val.is_identical_to(undefined_value)); |
106 } | 136 } |
107 | 137 |
108 | 138 |
109 TEST(TestInterpreterLoadNull) { | 139 TEST(InterpreterLoadNull) { |
110 InitializedHandleScope handles; | 140 InitializedHandleScope handles; |
111 Handle<Object> null_value = handles.main_isolate()->factory()->null_value(); | 141 Handle<Object> null_value = handles.main_isolate()->factory()->null_value(); |
112 | 142 |
113 BytecodeArrayBuilder builder(handles.main_isolate()); | 143 BytecodeArrayBuilder builder(handles.main_isolate()); |
114 builder.set_locals_count(0); | 144 builder.set_locals_count(0); |
| 145 builder.set_parameter_count(1); |
115 builder.LoadNull().Return(); | 146 builder.LoadNull().Return(); |
116 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 147 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
117 | 148 |
118 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 149 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
119 InterpreterCallable callable(tester.GetCallable()); | 150 auto callable = tester.GetCallable<>(); |
120 Handle<Object> return_val = callable().ToHandleChecked(); | 151 Handle<Object> return_val = callable().ToHandleChecked(); |
121 CHECK(return_val.is_identical_to(null_value)); | 152 CHECK(return_val.is_identical_to(null_value)); |
122 } | 153 } |
123 | 154 |
124 | 155 |
125 TEST(TestInterpreterLoadTheHole) { | 156 TEST(InterpreterLoadTheHole) { |
126 InitializedHandleScope handles; | 157 InitializedHandleScope handles; |
127 Handle<Object> the_hole_value = | 158 Handle<Object> the_hole_value = |
128 handles.main_isolate()->factory()->the_hole_value(); | 159 handles.main_isolate()->factory()->the_hole_value(); |
129 | 160 |
130 BytecodeArrayBuilder builder(handles.main_isolate()); | 161 BytecodeArrayBuilder builder(handles.main_isolate()); |
131 builder.set_locals_count(0); | 162 builder.set_locals_count(0); |
| 163 builder.set_parameter_count(1); |
132 builder.LoadTheHole().Return(); | 164 builder.LoadTheHole().Return(); |
133 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 165 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
134 | 166 |
135 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 167 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
136 InterpreterCallable callable(tester.GetCallable()); | 168 auto callable = tester.GetCallable<>(); |
137 Handle<Object> return_val = callable().ToHandleChecked(); | 169 Handle<Object> return_val = callable().ToHandleChecked(); |
138 CHECK(return_val.is_identical_to(the_hole_value)); | 170 CHECK(return_val.is_identical_to(the_hole_value)); |
139 } | 171 } |
140 | 172 |
141 | 173 |
142 TEST(TestInterpreterLoadTrue) { | 174 TEST(InterpreterLoadTrue) { |
143 InitializedHandleScope handles; | 175 InitializedHandleScope handles; |
144 Handle<Object> true_value = handles.main_isolate()->factory()->true_value(); | 176 Handle<Object> true_value = handles.main_isolate()->factory()->true_value(); |
145 | 177 |
146 BytecodeArrayBuilder builder(handles.main_isolate()); | 178 BytecodeArrayBuilder builder(handles.main_isolate()); |
147 builder.set_locals_count(0); | 179 builder.set_locals_count(0); |
| 180 builder.set_parameter_count(1); |
148 builder.LoadTrue().Return(); | 181 builder.LoadTrue().Return(); |
149 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 182 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
150 | 183 |
151 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 184 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
152 InterpreterCallable callable(tester.GetCallable()); | 185 auto callable = tester.GetCallable<>(); |
153 Handle<Object> return_val = callable().ToHandleChecked(); | 186 Handle<Object> return_val = callable().ToHandleChecked(); |
154 CHECK(return_val.is_identical_to(true_value)); | 187 CHECK(return_val.is_identical_to(true_value)); |
155 } | 188 } |
156 | 189 |
157 | 190 |
158 TEST(TestInterpreterLoadFalse) { | 191 TEST(InterpreterLoadFalse) { |
159 InitializedHandleScope handles; | 192 InitializedHandleScope handles; |
160 Handle<Object> false_value = handles.main_isolate()->factory()->false_value(); | 193 Handle<Object> false_value = handles.main_isolate()->factory()->false_value(); |
161 | 194 |
162 BytecodeArrayBuilder builder(handles.main_isolate()); | 195 BytecodeArrayBuilder builder(handles.main_isolate()); |
163 builder.set_locals_count(0); | 196 builder.set_locals_count(0); |
| 197 builder.set_parameter_count(1); |
164 builder.LoadFalse().Return(); | 198 builder.LoadFalse().Return(); |
165 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 199 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
166 | 200 |
167 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 201 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
168 InterpreterCallable callable(tester.GetCallable()); | 202 auto callable = tester.GetCallable<>(); |
169 Handle<Object> return_val = callable().ToHandleChecked(); | 203 Handle<Object> return_val = callable().ToHandleChecked(); |
170 CHECK(return_val.is_identical_to(false_value)); | 204 CHECK(return_val.is_identical_to(false_value)); |
171 } | 205 } |
172 | 206 |
173 | 207 |
174 TEST(TestInterpreterLoadLiteral) { | 208 TEST(InterpreterLoadLiteral) { |
175 InitializedHandleScope handles; | 209 InitializedHandleScope handles; |
176 for (int i = -128; i < 128; i++) { | 210 for (int i = -128; i < 128; i++) { |
177 BytecodeArrayBuilder builder(handles.main_isolate()); | 211 BytecodeArrayBuilder builder(handles.main_isolate()); |
178 builder.set_locals_count(0); | 212 builder.set_locals_count(0); |
| 213 builder.set_parameter_count(1); |
179 builder.LoadLiteral(Smi::FromInt(i)).Return(); | 214 builder.LoadLiteral(Smi::FromInt(i)).Return(); |
180 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 215 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
181 | 216 |
182 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 217 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
183 InterpreterCallable callable(tester.GetCallable()); | 218 auto callable = tester.GetCallable<>(); |
184 Handle<Object> return_val = callable().ToHandleChecked(); | 219 Handle<Object> return_val = callable().ToHandleChecked(); |
185 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(i)); | 220 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(i)); |
186 } | 221 } |
187 } | 222 } |
188 | 223 |
189 | 224 |
190 TEST(TestInterpreterLoadStoreRegisters) { | 225 TEST(InterpreterLoadStoreRegisters) { |
191 InitializedHandleScope handles; | 226 InitializedHandleScope handles; |
192 Handle<Object> true_value = handles.main_isolate()->factory()->true_value(); | 227 Handle<Object> true_value = handles.main_isolate()->factory()->true_value(); |
193 for (int i = 0; i <= Register::kMaxRegisterIndex; i++) { | 228 for (int i = 0; i <= Register::kMaxRegisterIndex; i++) { |
194 BytecodeArrayBuilder builder(handles.main_isolate()); | 229 BytecodeArrayBuilder builder(handles.main_isolate()); |
195 builder.set_locals_count(i + 1); | 230 builder.set_locals_count(i + 1); |
| 231 builder.set_parameter_count(1); |
196 Register reg(i); | 232 Register reg(i); |
197 builder.LoadTrue() | 233 builder.LoadTrue() |
198 .StoreAccumulatorInRegister(reg) | 234 .StoreAccumulatorInRegister(reg) |
199 .LoadFalse() | 235 .LoadFalse() |
200 .LoadAccumulatorWithRegister(reg) | 236 .LoadAccumulatorWithRegister(reg) |
201 .Return(); | 237 .Return(); |
202 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 238 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
203 | 239 |
204 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 240 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
205 InterpreterCallable callable(tester.GetCallable()); | 241 auto callable = tester.GetCallable<>(); |
206 Handle<Object> return_val = callable().ToHandleChecked(); | 242 Handle<Object> return_val = callable().ToHandleChecked(); |
207 CHECK(return_val.is_identical_to(true_value)); | 243 CHECK(return_val.is_identical_to(true_value)); |
208 } | 244 } |
209 } | 245 } |
210 | 246 |
211 | 247 |
212 TEST(TestInterpreterAdd) { | 248 TEST(InterpreterAdd) { |
213 InitializedHandleScope handles; | 249 InitializedHandleScope handles; |
214 // TODO(rmcilroy): Do add tests for heap numbers and strings once we support | 250 // TODO(rmcilroy): Do add tests for heap numbers and strings once we support |
215 // them. | 251 // them. |
216 BytecodeArrayBuilder builder(handles.main_isolate()); | 252 BytecodeArrayBuilder builder(handles.main_isolate()); |
217 builder.set_locals_count(1); | 253 builder.set_locals_count(1); |
| 254 builder.set_parameter_count(1); |
218 Register reg(0); | 255 Register reg(0); |
219 builder.LoadLiteral(Smi::FromInt(1)) | 256 builder.LoadLiteral(Smi::FromInt(1)) |
220 .StoreAccumulatorInRegister(reg) | 257 .StoreAccumulatorInRegister(reg) |
221 .LoadLiteral(Smi::FromInt(2)) | 258 .LoadLiteral(Smi::FromInt(2)) |
222 .BinaryOperation(Token::Value::ADD, reg) | 259 .BinaryOperation(Token::Value::ADD, reg) |
223 .Return(); | 260 .Return(); |
224 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 261 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
225 | 262 |
226 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 263 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
227 InterpreterCallable callable(tester.GetCallable()); | 264 auto callable = tester.GetCallable<>(); |
228 Handle<Object> return_val = callable().ToHandleChecked(); | 265 Handle<Object> return_val = callable().ToHandleChecked(); |
229 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(3)); | 266 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(3)); |
230 } | 267 } |
231 | 268 |
232 | 269 |
233 TEST(TestInterpreterSub) { | 270 TEST(InterpreterSub) { |
234 InitializedHandleScope handles; | 271 InitializedHandleScope handles; |
235 // TODO(rmcilroy): Do add tests for heap numbers once we support them. | 272 // TODO(rmcilroy): Do add tests for heap numbers once we support them. |
236 BytecodeArrayBuilder builder(handles.main_isolate()); | 273 BytecodeArrayBuilder builder(handles.main_isolate()); |
237 builder.set_locals_count(1); | 274 builder.set_locals_count(1); |
| 275 builder.set_parameter_count(1); |
238 Register reg(0); | 276 Register reg(0); |
239 builder.LoadLiteral(Smi::FromInt(5)) | 277 builder.LoadLiteral(Smi::FromInt(5)) |
240 .StoreAccumulatorInRegister(reg) | 278 .StoreAccumulatorInRegister(reg) |
241 .LoadLiteral(Smi::FromInt(31)) | 279 .LoadLiteral(Smi::FromInt(31)) |
242 .BinaryOperation(Token::Value::SUB, reg) | 280 .BinaryOperation(Token::Value::SUB, reg) |
243 .Return(); | 281 .Return(); |
244 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 282 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
245 | 283 |
246 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 284 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
247 InterpreterCallable callable(tester.GetCallable()); | 285 auto callable = tester.GetCallable<>(); |
248 Handle<Object> return_val = callable().ToHandleChecked(); | 286 Handle<Object> return_val = callable().ToHandleChecked(); |
249 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(-26)); | 287 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(-26)); |
250 } | 288 } |
251 | 289 |
252 | 290 |
253 TEST(TestInterpreterMul) { | 291 TEST(InterpreterMul) { |
254 InitializedHandleScope handles; | 292 InitializedHandleScope handles; |
255 // TODO(rmcilroy): Do add tests for heap numbers once we support them. | 293 // TODO(rmcilroy): Do add tests for heap numbers once we support them. |
256 BytecodeArrayBuilder builder(handles.main_isolate()); | 294 BytecodeArrayBuilder builder(handles.main_isolate()); |
257 builder.set_locals_count(1); | 295 builder.set_locals_count(1); |
| 296 builder.set_parameter_count(1); |
258 Register reg(0); | 297 Register reg(0); |
259 builder.LoadLiteral(Smi::FromInt(111)) | 298 builder.LoadLiteral(Smi::FromInt(111)) |
260 .StoreAccumulatorInRegister(reg) | 299 .StoreAccumulatorInRegister(reg) |
261 .LoadLiteral(Smi::FromInt(6)) | 300 .LoadLiteral(Smi::FromInt(6)) |
262 .BinaryOperation(Token::Value::MUL, reg) | 301 .BinaryOperation(Token::Value::MUL, reg) |
263 .Return(); | 302 .Return(); |
264 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 303 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
265 | 304 |
266 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 305 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
267 InterpreterCallable callable(tester.GetCallable()); | 306 auto callable = tester.GetCallable<>(); |
268 Handle<Object> return_val = callable().ToHandleChecked(); | 307 Handle<Object> return_val = callable().ToHandleChecked(); |
269 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(666)); | 308 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(666)); |
270 } | 309 } |
271 | 310 |
272 | 311 |
273 TEST(TestInterpreterDiv) { | 312 TEST(InterpreterDiv) { |
274 InitializedHandleScope handles; | 313 InitializedHandleScope handles; |
275 // TODO(rmcilroy): Do add tests for heap numbers once we support them. | 314 // TODO(rmcilroy): Do add tests for heap numbers once we support them. |
276 BytecodeArrayBuilder builder(handles.main_isolate()); | 315 BytecodeArrayBuilder builder(handles.main_isolate()); |
277 builder.set_locals_count(1); | 316 builder.set_locals_count(1); |
| 317 builder.set_parameter_count(1); |
278 Register reg(0); | 318 Register reg(0); |
279 builder.LoadLiteral(Smi::FromInt(-20)) | 319 builder.LoadLiteral(Smi::FromInt(-20)) |
280 .StoreAccumulatorInRegister(reg) | 320 .StoreAccumulatorInRegister(reg) |
281 .LoadLiteral(Smi::FromInt(5)) | 321 .LoadLiteral(Smi::FromInt(5)) |
282 .BinaryOperation(Token::Value::DIV, reg) | 322 .BinaryOperation(Token::Value::DIV, reg) |
283 .Return(); | 323 .Return(); |
284 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 324 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
285 | 325 |
286 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 326 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
287 InterpreterCallable callable(tester.GetCallable()); | 327 auto callable = tester.GetCallable<>(); |
288 Handle<Object> return_val = callable().ToHandleChecked(); | 328 Handle<Object> return_val = callable().ToHandleChecked(); |
289 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(-4)); | 329 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(-4)); |
290 } | 330 } |
291 | 331 |
292 | 332 |
293 TEST(TestInterpreterMod) { | 333 TEST(InterpreterMod) { |
294 InitializedHandleScope handles; | 334 InitializedHandleScope handles; |
295 // TODO(rmcilroy): Do add tests for heap numbers once we support them. | 335 // TODO(rmcilroy): Do add tests for heap numbers once we support them. |
296 BytecodeArrayBuilder builder(handles.main_isolate()); | 336 BytecodeArrayBuilder builder(handles.main_isolate()); |
297 builder.set_locals_count(1); | 337 builder.set_locals_count(1); |
| 338 builder.set_parameter_count(1); |
298 Register reg(0); | 339 Register reg(0); |
299 builder.LoadLiteral(Smi::FromInt(121)) | 340 builder.LoadLiteral(Smi::FromInt(121)) |
300 .StoreAccumulatorInRegister(reg) | 341 .StoreAccumulatorInRegister(reg) |
301 .LoadLiteral(Smi::FromInt(100)) | 342 .LoadLiteral(Smi::FromInt(100)) |
302 .BinaryOperation(Token::Value::MOD, reg) | 343 .BinaryOperation(Token::Value::MOD, reg) |
303 .Return(); | 344 .Return(); |
304 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 345 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
305 | 346 |
306 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 347 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
307 InterpreterCallable callable(tester.GetCallable()); | 348 auto callable = tester.GetCallable<>(); |
308 Handle<Object> return_val = callable().ToHandleChecked(); | 349 Handle<Object> return_val = callable().ToHandleChecked(); |
309 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(21)); | 350 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(21)); |
310 } | 351 } |
| 352 |
| 353 |
| 354 TEST(InterpreterParameter1) { |
| 355 InitializedHandleScope handles; |
| 356 BytecodeArrayBuilder builder(handles.main_isolate()); |
| 357 builder.set_locals_count(1); |
| 358 builder.set_parameter_count(1); |
| 359 builder.LoadAccumulatorWithRegister(builder.Parameter(0)).Return(); |
| 360 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 361 |
| 362 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 363 auto callable = tester.GetCallable<Handle<Object>>(); |
| 364 |
| 365 // Check for heap objects. |
| 366 Handle<Object> true_value = handles.main_isolate()->factory()->true_value(); |
| 367 Handle<Object> return_val = callable(true_value).ToHandleChecked(); |
| 368 CHECK(return_val.is_identical_to(true_value)); |
| 369 |
| 370 // Check for Smis. |
| 371 return_val = callable(Handle<Smi>(Smi::FromInt(3), handles.main_isolate())) |
| 372 .ToHandleChecked(); |
| 373 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(3)); |
| 374 } |
| 375 |
| 376 |
| 377 TEST(InterpreterParameter8) { |
| 378 InitializedHandleScope handles; |
| 379 BytecodeArrayBuilder builder(handles.main_isolate()); |
| 380 builder.set_locals_count(1); |
| 381 builder.set_parameter_count(8); |
| 382 builder.LoadAccumulatorWithRegister(builder.Parameter(0)) |
| 383 .BinaryOperation(Token::Value::ADD, builder.Parameter(1)) |
| 384 .BinaryOperation(Token::Value::ADD, builder.Parameter(2)) |
| 385 .BinaryOperation(Token::Value::ADD, builder.Parameter(3)) |
| 386 .BinaryOperation(Token::Value::ADD, builder.Parameter(4)) |
| 387 .BinaryOperation(Token::Value::ADD, builder.Parameter(5)) |
| 388 .BinaryOperation(Token::Value::ADD, builder.Parameter(6)) |
| 389 .BinaryOperation(Token::Value::ADD, builder.Parameter(7)) |
| 390 .Return(); |
| 391 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 392 |
| 393 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 394 typedef Handle<Object> H; |
| 395 auto callable = tester.GetCallable<H, H, H, H, H, H, H, H>(); |
| 396 |
| 397 Handle<Smi> arg1 = Handle<Smi>(Smi::FromInt(1), handles.main_isolate()); |
| 398 Handle<Smi> arg2 = Handle<Smi>(Smi::FromInt(2), handles.main_isolate()); |
| 399 Handle<Smi> arg3 = Handle<Smi>(Smi::FromInt(3), handles.main_isolate()); |
| 400 Handle<Smi> arg4 = Handle<Smi>(Smi::FromInt(4), handles.main_isolate()); |
| 401 Handle<Smi> arg5 = Handle<Smi>(Smi::FromInt(5), handles.main_isolate()); |
| 402 Handle<Smi> arg6 = Handle<Smi>(Smi::FromInt(6), handles.main_isolate()); |
| 403 Handle<Smi> arg7 = Handle<Smi>(Smi::FromInt(7), handles.main_isolate()); |
| 404 Handle<Smi> arg8 = Handle<Smi>(Smi::FromInt(8), handles.main_isolate()); |
| 405 // Check for Smis. |
| 406 Handle<Object> return_val = |
| 407 callable(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) |
| 408 .ToHandleChecked(); |
| 409 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(36)); |
| 410 } |
OLD | NEW |