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

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

Issue 1607433005: [interpreter] Implement exception handler table building. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Added moar tests. Created 4 years, 11 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 | « src/objects.cc ('k') | tools/gyp/v8.gyp » ('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/compiler.h" 7 #include "src/compiler.h"
8 #include "src/interpreter/bytecode-array-iterator.h" 8 #include "src/interpreter/bytecode-array-iterator.h"
9 #include "src/interpreter/bytecode-generator.h" 9 #include "src/interpreter/bytecode-generator.h"
10 #include "src/interpreter/interpreter.h" 10 #include "src/interpreter/interpreter.h"
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 // Structure for containing expected bytecode snippets. 154 // Structure for containing expected bytecode snippets.
155 template<typename T, int C = 6> 155 template<typename T, int C = 6>
156 struct ExpectedSnippet { 156 struct ExpectedSnippet {
157 const char* code_snippet; 157 const char* code_snippet;
158 int frame_size; 158 int frame_size;
159 int parameter_count; 159 int parameter_count;
160 int bytecode_length; 160 int bytecode_length;
161 const uint8_t bytecode[2048]; 161 const uint8_t bytecode[2048];
162 int constant_count; 162 int constant_count;
163 T constants[C]; 163 T constants[C];
164 int handler_count;
165 struct {
166 int start;
167 int end;
168 int handler;
169 } handlers[C];
164 }; 170 };
165 171
166 172
167 static void CheckConstant(int expected, Object* actual) { 173 static void CheckConstant(int expected, Object* actual) {
168 CHECK_EQ(expected, Smi::cast(actual)->value()); 174 CHECK_EQ(expected, Smi::cast(actual)->value());
169 } 175 }
170 176
171 177
172 static void CheckConstant(double expected, Object* actual) { 178 static void CheckConstant(double expected, Object* actual) {
173 CHECK_EQ(expected, HeapNumber::cast(actual)->value()); 179 CHECK_EQ(expected, HeapNumber::cast(actual)->value());
(...skipping 24 matching lines...) Expand all
198 CHECK_EQ(expected.parameter_count, actual->parameter_count()); 204 CHECK_EQ(expected.parameter_count, actual->parameter_count());
199 CHECK_EQ(expected.bytecode_length, actual->length()); 205 CHECK_EQ(expected.bytecode_length, actual->length());
200 if (expected.constant_count == 0) { 206 if (expected.constant_count == 0) {
201 CHECK_EQ(CcTest::heap()->empty_fixed_array(), actual->constant_pool()); 207 CHECK_EQ(CcTest::heap()->empty_fixed_array(), actual->constant_pool());
202 } else { 208 } else {
203 CHECK_EQ(expected.constant_count, actual->constant_pool()->length()); 209 CHECK_EQ(expected.constant_count, actual->constant_pool()->length());
204 for (int i = 0; i < expected.constant_count; i++) { 210 for (int i = 0; i < expected.constant_count; i++) {
205 CheckConstant(expected.constants[i], actual->constant_pool()->get(i)); 211 CheckConstant(expected.constants[i], actual->constant_pool()->get(i));
206 } 212 }
207 } 213 }
214 if (expected.handler_count == 0) {
215 CHECK_EQ(CcTest::heap()->empty_fixed_array(), actual->handler_table());
216 } else {
217 static const int kHTSize = 4; // see HandlerTable::kRangeEntrySize
218 static const int kHTStart = 0; // see HandlerTable::kRangeStartIndex
219 static const int kHTEnd = 1; // see HandlerTable::kRangeEndIndex
220 static const int kHTHandler = 2; // see HandlerTable::kRangeHandlerIndex
221 HandlerTable* table = HandlerTable::cast(actual->handler_table());
222 CHECK_EQ(expected.handler_count * kHTSize, table->length());
223 for (int i = 0; i < expected.handler_count; i++) {
224 int start = Smi::cast(table->get(i * kHTSize + kHTStart))->value();
225 int end = Smi::cast(table->get(i * kHTSize + kHTEnd))->value();
226 int handler = Smi::cast(table->get(i * kHTSize + kHTHandler))->value();
227 CHECK_EQ(expected.handlers[i].start, start);
228 CHECK_EQ(expected.handlers[i].end, end);
229 CHECK_EQ(expected.handlers[i].handler, handler >> 1);
230 }
231 }
208 232
209 BytecodeArrayIterator iterator(actual); 233 BytecodeArrayIterator iterator(actual);
210 int i = 0; 234 int i = 0;
211 while (!iterator.done()) { 235 while (!iterator.done()) {
212 int bytecode_index = i++; 236 int bytecode_index = i++;
213 Bytecode bytecode = iterator.current_bytecode(); 237 Bytecode bytecode = iterator.current_bytecode();
214 if (Bytecodes::ToByte(bytecode) != expected.bytecode[bytecode_index]) { 238 if (Bytecodes::ToByte(bytecode) != expected.bytecode[bytecode_index]) {
215 std::ostringstream stream; 239 std::ostringstream stream;
216 stream << "Check failed: expected bytecode [" << bytecode_index 240 stream << "Check failed: expected bytecode [" << bytecode_index
217 << "] to be " << Bytecodes::ToString(static_cast<Bytecode>( 241 << "] to be " << Bytecodes::ToString(static_cast<Bytecode>(
(...skipping 3918 matching lines...) Expand 10 before | Expand all | Expand 10 after
4136 helper.MakeTopLevelBytecode(snippets[i].code_snippet); 4160 helper.MakeTopLevelBytecode(snippets[i].code_snippet);
4137 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 4161 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
4138 } 4162 }
4139 } 4163 }
4140 4164
4141 4165
4142 TEST(TryCatch) { 4166 TEST(TryCatch) {
4143 InitializedHandleScope handle_scope; 4167 InitializedHandleScope handle_scope;
4144 BytecodeGeneratorHelper helper; 4168 BytecodeGeneratorHelper helper;
4145 4169
4146 // TODO(rmcilroy): modify tests when we have real try catch support. 4170 int closure = Register::function_closure().index();
4147 ExpectedSnippet<int> snippets[] = { 4171
4172 ExpectedSnippet<const char*> snippets[] = {
4148 {"try { return 1; } catch(e) { return 2; }", 4173 {"try { return 1; } catch(e) { return 2; }",
4149 kPointerSize, 4174 5 * kPointerSize,
4150 1, 4175 1,
4151 3, 4176 23,
4152 { 4177 {
4153 B(LdaSmi8), U8(1), // 4178 B(LdaSmi8), U8(1), //
4154 B(Return), // 4179 B(Return), //
4180 B(Star), R(3), //
4181 B(LdaConstant), U8(0), //
4182 B(Star), R(2), //
4183 B(Ldar), R(closure), //
4184 B(Star), R(4), //
4185 B(CallRuntime), U16(Runtime::kPushCatchContext), R(2), U8(3), //
4186 B(LdaSmi8), U8(2), //
4187 B(Return), //
4188 // TODO(mstarzinger): Potential optimization, elide next bytes.
4189 B(LdaUndefined), //
4190 B(Return), //
4155 }, 4191 },
4156 0}, 4192 1,
4193 {"e"},
4194 1,
4195 {{0, 3, 3}}},
4196 {"var a; try { a = 1 } catch(e1) {}; try { a = 2 } catch(e2) { a = 3 }",
4197 6 * kPointerSize,
4198 1,
4199 48,
4200 {
4201 B(LdaSmi8), U8(1), //
4202 B(Star), R(0), //
4203 B(Jump), U8(17), //
4204 B(Star), R(4), //
4205 B(LdaConstant), U8(0), //
4206 B(Star), R(3), //
4207 B(Ldar), R(closure), //
4208 B(Star), R(5), //
4209 B(CallRuntime), U16(Runtime::kPushCatchContext), R(3), U8(3), //
4210 B(LdaSmi8), U8(2), //
4211 B(Star), R(0), //
4212 B(Jump), U8(21), //
4213 B(Star), R(4), //
4214 B(LdaConstant), U8(1), //
4215 B(Star), R(3), //
4216 B(Ldar), R(closure), //
4217 B(Star), R(5), //
4218 B(CallRuntime), U16(Runtime::kPushCatchContext), R(3), U8(3), //
4219 B(LdaSmi8), U8(3), //
4220 B(Star), R(0), //
4221 B(LdaUndefined), //
4222 B(Return), //
4223 },
4224 2,
4225 {"e1", "e2"},
4226 2,
4227 {{0, 4, 6}, {21, 25, 27}}},
4157 }; 4228 };
4158 4229
4159 for (size_t i = 0; i < arraysize(snippets); i++) { 4230 for (size_t i = 0; i < arraysize(snippets); i++) {
4160 Handle<BytecodeArray> bytecode_array = 4231 Handle<BytecodeArray> bytecode_array =
4161 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); 4232 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
4162 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 4233 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
4163 } 4234 }
4164 } 4235 }
4165 4236
4166 4237
4167 TEST(TryFinally) { 4238 TEST(TryFinally) {
4168 InitializedHandleScope handle_scope; 4239 InitializedHandleScope handle_scope;
4169 BytecodeGeneratorHelper helper; 4240 BytecodeGeneratorHelper helper;
4170 4241
4171 // TODO(rmcilroy): modify tests when we have real try finally support. 4242 int closure = Register::function_closure().index();
4172 ExpectedSnippet<int> snippets[] = { 4243
4244 ExpectedSnippet<const char*> snippets[] = {
4173 {"var a = 1; try { a = 2; } finally { a = 3; }", 4245 {"var a = 1; try { a = 2; } finally { a = 3; }",
4174 kPointerSize, 4246 2 * kPointerSize,
4175 1, 4247 1,
4176 14, 4248 14,
4177 { 4249 {
4178 B(LdaSmi8), U8(1), // 4250 B(LdaSmi8), U8(1), //
4179 B(Star), R(0), // 4251 B(Star), R(0), //
4180 B(LdaSmi8), U8(2), // 4252 B(LdaSmi8), U8(2), //
4181 B(Star), R(0), // 4253 B(Star), R(0), //
4182 B(LdaSmi8), U8(3), // 4254 B(LdaSmi8), U8(3), //
4183 B(Star), R(0), // 4255 B(Star), R(0), //
4184 B(LdaUndefined), // 4256 B(LdaUndefined), //
4185 B(Return), // 4257 B(Return), //
4186 }, 4258 },
4187 0}, 4259 0,
4260 {},
4261 1,
4262 {{4, 8, 8}}},
4188 {"var a = 1; try { a = 2; } catch(e) { a = 20 } finally { a = 3; }", 4263 {"var a = 1; try { a = 2; } catch(e) { a = 20 } finally { a = 3; }",
4189 2 * kPointerSize, 4264 7 * kPointerSize,
4190 1, 4265 1,
4191 14, 4266 35,
4192 { 4267 {
4193 B(LdaSmi8), U8(1), // 4268 B(LdaSmi8), U8(1), //
4194 B(Star), R(0), // 4269 B(Star), R(0), //
4195 B(LdaSmi8), U8(2), // 4270 B(LdaSmi8), U8(2), //
4196 B(Star), R(0), // 4271 B(Star), R(0), //
4197 B(LdaSmi8), U8(3), // 4272 B(Jump), U8(21), //
4198 B(Star), R(0), // 4273 B(Star), R(5), //
4199 B(LdaUndefined), // 4274 B(LdaConstant), U8(0), //
4200 B(Return), // 4275 B(Star), R(4), //
4276 B(Ldar), R(closure), //
4277 B(Star), R(6), //
4278 B(CallRuntime), U16(Runtime::kPushCatchContext), R(4), U8(3), //
4279 B(LdaSmi8), U8(20), //
4280 B(Star), R(0), //
4281 B(LdaSmi8), U8(3), //
4282 B(Star), R(0), //
4283 B(LdaUndefined), //
4284 B(Return), //
4201 }, 4285 },
4202 0}, 4286 1,
4287 {"e"},
4288 2,
4289 {{4, 29, 29}, {4, 8, 10}}},
4290 {"var a; try {"
4291 " try { a = 1 } catch(e) { a = 2 }"
4292 "} catch(e) { a = 20 } finally { a = 3; }",
4293 8 * kPointerSize,
4294 1,
4295 52,
4296 {
4297 B(LdaSmi8), U8(1), //
4298 B(Star), R(0), //
4299 B(Jump), U8(21), //
4300 B(Star), R(6), //
4301 B(LdaConstant), U8(0), //
4302 B(Star), R(5), //
4303 B(Ldar), R(closure), //
4304 B(Star), R(7), //
4305 B(CallRuntime), U16(Runtime::kPushCatchContext), R(5), U8(3), //
4306 B(LdaSmi8), U8(2), //
4307 B(Star), R(0), //
4308 B(Jump), U8(21), //
4309 B(Star), R(5), //
4310 B(LdaConstant), U8(0), //
4311 B(Star), R(4), //
4312 B(Ldar), R(closure), //
4313 B(Star), R(6), //
4314 B(CallRuntime), U16(Runtime::kPushCatchContext), R(4), U8(3), //
4315 B(LdaSmi8), U8(20), //
4316 B(Star), R(0), //
4317 B(LdaSmi8), U8(3), //
4318 B(Star), R(0), //
4319 B(LdaUndefined), //
4320 B(Return), //
4321 },
4322 1,
4323 {"e"},
4324 3,
4325 {{0, 46, 46}, {0, 25, 27}, {0, 4, 6}}},
4203 }; 4326 };
4204 4327
4205 for (size_t i = 0; i < arraysize(snippets); i++) { 4328 for (size_t i = 0; i < arraysize(snippets); i++) {
4206 Handle<BytecodeArray> bytecode_array = 4329 Handle<BytecodeArray> bytecode_array =
4207 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); 4330 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
4208 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 4331 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
4209 } 4332 }
4210 } 4333 }
4211 4334
4212 4335
4213 TEST(Throw) { 4336 TEST(Throw) {
4214 InitializedHandleScope handle_scope; 4337 InitializedHandleScope handle_scope;
4215 BytecodeGeneratorHelper helper; 4338 BytecodeGeneratorHelper helper;
4216 4339
4217 // TODO(rmcilroy): modify tests when we have real try catch support.
4218 ExpectedSnippet<const char*> snippets[] = { 4340 ExpectedSnippet<const char*> snippets[] = {
4219 {"throw 1;", 4341 {"throw 1;",
4220 0, 4342 0,
4221 1, 4343 1,
4222 3, 4344 3,
4223 { 4345 {
4224 B(LdaSmi8), U8(1), // 4346 B(LdaSmi8), U8(1), //
4225 B(Throw), // 4347 B(Throw), //
4226 }, 4348 },
4227 0}, 4349 0},
(...skipping 2534 matching lines...) Expand 10 before | Expand all | Expand 10 after
6762 std::string(function_epilogue); 6884 std::string(function_epilogue);
6763 Handle<BytecodeArray> bytecode_array = 6885 Handle<BytecodeArray> bytecode_array =
6764 helper.MakeBytecode(script.c_str(), "*", "f"); 6886 helper.MakeBytecode(script.c_str(), "*", "f");
6765 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 6887 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
6766 } 6888 }
6767 } 6889 }
6768 6890
6769 } // namespace interpreter 6891 } // namespace interpreter
6770 } // namespace internal 6892 } // namespace internal
6771 } // namespace v8 6893 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | tools/gyp/v8.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698