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

Side by Side Diff: src/fast-codegen.cc

Issue 466033: Fast codegen: Working break and continue. (Closed)
Patch Set: Fixed bug in ARM PopTryHandler, merge with head. Created 11 years 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
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 18 matching lines...) Expand all
29 29
30 #include "codegen-inl.h" 30 #include "codegen-inl.h"
31 #include "compiler.h" 31 #include "compiler.h"
32 #include "fast-codegen.h" 32 #include "fast-codegen.h"
33 #include "stub-cache.h" 33 #include "stub-cache.h"
34 #include "debug.h" 34 #include "debug.h"
35 35
36 namespace v8 { 36 namespace v8 {
37 namespace internal { 37 namespace internal {
38 38
39 #define __ ACCESS_MASM(masm_) 39 #define __ ACCESS_MASM(masm())
40 40
41 Handle<Code> FastCodeGenerator::MakeCode(FunctionLiteral* fun, 41 Handle<Code> FastCodeGenerator::MakeCode(FunctionLiteral* fun,
42 Handle<Script> script, 42 Handle<Script> script,
43 bool is_eval) { 43 bool is_eval) {
44 CodeGenerator::MakeCodePrologue(fun); 44 CodeGenerator::MakeCodePrologue(fun);
45 const int kInitialBufferSize = 4 * KB; 45 const int kInitialBufferSize = 4 * KB;
46 MacroAssembler masm(NULL, kInitialBufferSize); 46 MacroAssembler masm(NULL, kInitialBufferSize);
47 FastCodeGenerator cgen(&masm, script, is_eval); 47 FastCodeGenerator cgen(&masm, script, is_eval);
48 cgen.Generate(fun); 48 cgen.Generate(fun);
49 if (cgen.HasStackOverflow()) { 49 if (cgen.HasStackOverflow()) {
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 225
226 __ bind(&eval_right); 226 __ bind(&eval_right);
227 Visit(expr->right()); 227 Visit(expr->right());
228 228
229 __ bind(&done); 229 __ bind(&done);
230 } 230 }
231 231
232 232
233 void FastCodeGenerator::VisitBlock(Block* stmt) { 233 void FastCodeGenerator::VisitBlock(Block* stmt) {
234 Comment cmnt(masm_, "[ Block"); 234 Comment cmnt(masm_, "[ Block");
235 Label end_of_block;
236 Breakable nested_statement(this, stmt, &end_of_block);
Kevin Millikin (Chromium) 2009/12/10 13:09:26 If the label is part of the state of the Breakable
235 SetStatementPosition(stmt); 237 SetStatementPosition(stmt);
236 VisitStatements(stmt->statements()); 238 VisitStatements(stmt->statements());
239 __ bind(&end_of_block);
Kevin Millikin (Chromium) 2009/12/10 13:09:26 And __ bind(nested_statement.break_target());
237 } 240 }
238 241
239 242
240 void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { 243 void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
241 Comment cmnt(masm_, "[ ExpressionStatement"); 244 Comment cmnt(masm_, "[ ExpressionStatement");
242 SetStatementPosition(stmt); 245 SetStatementPosition(stmt);
243 Visit(stmt->expression()); 246 Visit(stmt->expression());
244 } 247 }
245 248
246 249
(...skipping 24 matching lines...) Expand all
271 __ jmp(&done); 274 __ jmp(&done);
272 275
273 __ bind(&else_part); 276 __ bind(&else_part);
274 Visit(stmt->else_statement()); 277 Visit(stmt->else_statement());
275 278
276 __ bind(&done); 279 __ bind(&done);
277 } 280 }
278 281
279 282
280 void FastCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 283 void FastCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
281 UNREACHABLE(); 284 NestedStatement* current = nesting_stack_;
Kevin Millikin (Chromium) 2009/12/10 13:09:26 Might be nice to have a codegen comment "[ Continu
Lasse Reichstein 2009/12/10 13:55:32 Fixed
285 int stack_depth = 0;
286 while (!current->IsContinueTarget(stmt->target())) {
287 stack_depth = current->Exit(stack_depth);
288 current = current->outer();
289 }
290 __ Drop(stack_depth);
291
292 Iteration* loop = current->AsIteration();
293 __ jmp(loop->continue_target());
282 } 294 }
283 295
284 296
285 void FastCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 297 void FastCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
286 UNREACHABLE(); 298 NestedStatement* current = nesting_stack_;
299 int stack_depth = 0;
300 while (!current->IsBreakTarget(stmt->target())) {
301 stack_depth = current->Exit(stack_depth);
302 current = current->outer();
303 }
304 __ Drop(stack_depth);
305
306 Breakable* target = current->AsBreakable();
307 __ jmp(target->break_target());
287 } 308 }
288 309
289 310
311 void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
312 Comment cmnt(masm_, "[ ReturnStatement");
313 Expression* expr = stmt->expression();
314 // Complete the statement based on the type of the subexpression.
315 if (expr->AsLiteral() != NULL) {
316 __ Move(result_register(), expr->AsLiteral()->handle());
317 } else {
318 ASSERT_EQ(Expression::kValue, expr->context());
319 Visit(expr);
320 __ pop(result_register());
321 }
322
323 // Exit all nested statements.
324 NestedStatement* current = nesting_stack_;
325 int stack_depth = 0;
326 while (current != NULL) {
327 stack_depth = current->Exit(stack_depth);
328 current = current->outer();
329 }
330 __ Drop(stack_depth);
331
332 EmitReturnSequence(stmt->statement_pos());
333 }
334
335
336
337
290 void FastCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) { 338 void FastCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) {
291 UNREACHABLE(); 339 UNREACHABLE();
292 } 340 }
293 341
294 342
295 void FastCodeGenerator::VisitWithExitStatement(WithExitStatement* stmt) { 343 void FastCodeGenerator::VisitWithExitStatement(WithExitStatement* stmt) {
296 UNREACHABLE(); 344 UNREACHABLE();
297 } 345 }
298 346
299 347
300 void FastCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 348 void FastCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
301 UNREACHABLE(); 349 UNREACHABLE();
302 } 350 }
303 351
304 352
305 void FastCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 353 void FastCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
306 Comment cmnt(masm_, "[ DoWhileStatement"); 354 Comment cmnt(masm_, "[ DoWhileStatement");
355 Label body, test, exit, stack_limit_hit, stack_check_success;
Kevin Millikin (Chromium) 2009/12/10 13:09:26 exit and test could be fields of the Iteration.
356
307 increment_loop_depth(); 357 increment_loop_depth();
Kevin Millikin (Chromium) 2009/12/10 13:28:28 Another comment: it seems nicer to properly nest t
Lasse Reichstein 2009/12/10 13:55:32 Fixed
308 Label body, exit, stack_limit_hit, stack_check_success;
309 358
310 __ bind(&body); 359 __ bind(&body);
360 Iteration loop_statement(this, stmt, &exit, &test);
311 Visit(stmt->body()); 361 Visit(stmt->body());
312 362
313 // Check stack before looping. 363 // Check stack before looping.
314 __ StackLimitCheck(&stack_limit_hit); 364 __ StackLimitCheck(&stack_limit_hit);
315 __ bind(&stack_check_success); 365 __ bind(&stack_check_success);
316 366
317 // We are not in an expression context because we have been compiling 367 // We are not in an expression context because we have been compiling
318 // statements. Set up a test expression context for the condition. 368 // statements. Set up a test expression context for the condition.
369 __ bind(&test);
Kevin Millikin (Chromium) 2009/12/10 13:09:26 __ bind(loop_statement.continue_target());
319 ASSERT_EQ(NULL, true_label_); 370 ASSERT_EQ(NULL, true_label_);
320 ASSERT_EQ(NULL, false_label_); 371 ASSERT_EQ(NULL, false_label_);
321 true_label_ = &body; 372 true_label_ = &body;
322 false_label_ = &exit; 373 false_label_ = &exit;
323 ASSERT(stmt->cond()->context() == Expression::kTest); 374 ASSERT(stmt->cond()->context() == Expression::kTest);
324 Visit(stmt->cond()); 375 Visit(stmt->cond());
325 true_label_ = NULL; 376 true_label_ = NULL;
326 false_label_ = NULL; 377 false_label_ = NULL;
327 378
328 __ bind(&stack_limit_hit); 379 __ bind(&stack_limit_hit);
329 StackCheckStub stack_stub; 380 StackCheckStub stack_stub;
330 __ CallStub(&stack_stub); 381 __ CallStub(&stack_stub);
331 __ jmp(&stack_check_success); 382 __ jmp(&stack_check_success);
332 383
333 __ bind(&exit); 384 __ bind(&exit);
Kevin Millikin (Chromium) 2009/12/10 13:09:26 __ bind(loop_statement.break_target());
334 385
335 decrement_loop_depth(); 386 decrement_loop_depth();
336 } 387 }
337 388
338 389
339 void FastCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 390 void FastCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
340 Comment cmnt(masm_, "[ WhileStatement"); 391 Comment cmnt(masm_, "[ WhileStatement");
392 Label test, body, exit, stack_limit_hit, stack_check_success;
393
341 increment_loop_depth(); 394 increment_loop_depth();
342 Label test, body, exit, stack_limit_hit, stack_check_success;
343 395
344 // Emit the test at the bottom of the loop. 396 // Emit the test at the bottom of the loop.
345 __ jmp(&test); 397 __ jmp(&test);
346 398
347 __ bind(&body); 399 __ bind(&body);
400 Iteration loop_stamt(this, stmt, &exit, &test);
Kevin Millikin (Chromium) 2009/12/10 13:09:26 loop_statement? loop_stmt?
Lasse Reichstein 2009/12/10 13:55:32 Odd typo. Fixed.
348 Visit(stmt->body()); 401 Visit(stmt->body());
349 402
350 __ bind(&test); 403 __ bind(&test);
351 // Check stack before looping. 404 // Check stack before looping.
352 __ StackLimitCheck(&stack_limit_hit); 405 __ StackLimitCheck(&stack_limit_hit);
353 __ bind(&stack_check_success); 406 __ bind(&stack_check_success);
354 407
355 // We are not in an expression context because we have been compiling 408 // We are not in an expression context because we have been compiling
356 // statements. Set up a test expression context for the condition. 409 // statements. Set up a test expression context for the condition.
357 ASSERT_EQ(NULL, true_label_); 410 ASSERT_EQ(NULL, true_label_);
358 ASSERT_EQ(NULL, false_label_); 411 ASSERT_EQ(NULL, false_label_);
359 true_label_ = &body; 412 true_label_ = &body;
360 false_label_ = &exit; 413 false_label_ = &exit;
361 ASSERT(stmt->cond()->context() == Expression::kTest); 414 ASSERT(stmt->cond()->context() == Expression::kTest);
362 Visit(stmt->cond()); 415 Visit(stmt->cond());
363 true_label_ = NULL; 416 true_label_ = NULL;
364 false_label_ = NULL; 417 false_label_ = NULL;
365 418
366 __ bind(&stack_limit_hit); 419 __ bind(&stack_limit_hit);
367 StackCheckStub stack_stub; 420 StackCheckStub stack_stub;
368 __ CallStub(&stack_stub); 421 __ CallStub(&stack_stub);
369 __ jmp(&stack_check_success); 422 __ jmp(&stack_check_success);
370 423
371 __ bind(&exit); 424 __ bind(&exit);
372
373 decrement_loop_depth(); 425 decrement_loop_depth();
374 } 426 }
375 427
376 428
377 void FastCodeGenerator::VisitForStatement(ForStatement* stmt) { 429 void FastCodeGenerator::VisitForStatement(ForStatement* stmt) {
378 Comment cmnt(masm_, "[ ForStatement"); 430 Comment cmnt(masm_, "[ ForStatement");
379 Label test, body, exit, stack_limit_hit, stack_check_success; 431 Label test, body, next, exit, stack_limit_hit, stack_check_success;
380 if (stmt->init() != NULL) Visit(stmt->init()); 432 if (stmt->init() != NULL) Visit(stmt->init());
381 433
382 increment_loop_depth(); 434 increment_loop_depth();
435
383 // Emit the test at the bottom of the loop (even if empty). 436 // Emit the test at the bottom of the loop (even if empty).
384 __ jmp(&test); 437 __ jmp(&test);
438
385 __ bind(&body); 439 __ bind(&body);
440 Iteration loop_stamt(this, stmt, &exit, &next);
Kevin Millikin (Chromium) 2009/12/10 13:09:26 loop_statement?
386 Visit(stmt->body()); 441 Visit(stmt->body());
387 442
388 // Check stack before looping. 443 // Check stack before looping.
389 __ StackLimitCheck(&stack_limit_hit); 444 __ StackLimitCheck(&stack_limit_hit);
390 __ bind(&stack_check_success); 445 __ bind(&stack_check_success);
391 446
447 __ bind(&next);
448
392 if (stmt->next() != NULL) Visit(stmt->next()); 449 if (stmt->next() != NULL) Visit(stmt->next());
393 450
394 __ bind(&test); 451 __ bind(&test);
395 452
396 if (stmt->cond() == NULL) { 453 if (stmt->cond() == NULL) {
397 // For an empty test jump to the top of the loop. 454 // For an empty test jump to the top of the loop.
398 __ jmp(&body); 455 __ jmp(&body);
399 } else { 456 } else {
400 // We are not in an expression context because we have been compiling 457 // We are not in an expression context because we have been compiling
401 // statements. Set up a test expression context for the condition. 458 // statements. Set up a test expression context for the condition.
402 ASSERT_EQ(NULL, true_label_); 459 ASSERT_EQ(NULL, true_label_);
403 ASSERT_EQ(NULL, false_label_); 460 ASSERT_EQ(NULL, false_label_);
404 461
405 true_label_ = &body; 462 true_label_ = &body;
406 false_label_ = &exit; 463 false_label_ = &exit;
407 ASSERT(stmt->cond()->context() == Expression::kTest); 464 ASSERT(stmt->cond()->context() == Expression::kTest);
408 Visit(stmt->cond()); 465 Visit(stmt->cond());
409 true_label_ = NULL; 466 true_label_ = NULL;
410 false_label_ = NULL; 467 false_label_ = NULL;
411 } 468 }
412 469
413 __ bind(&stack_limit_hit); 470 __ bind(&stack_limit_hit);
414 StackCheckStub stack_stub; 471 StackCheckStub stack_stub;
415 __ CallStub(&stack_stub); 472 __ CallStub(&stack_stub);
416 __ jmp(&stack_check_success); 473 __ jmp(&stack_check_success);
417 474
418 __ bind(&exit); 475 __ bind(&exit);
476
419 decrement_loop_depth(); 477 decrement_loop_depth();
420 } 478 }
421 479
422 480
423 void FastCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 481 void FastCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
424 UNREACHABLE(); 482 UNREACHABLE();
425 } 483 }
426 484
427 485
428 void FastCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 486 void FastCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { 605 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
548 UNREACHABLE(); 606 UNREACHABLE();
549 } 607 }
550 608
551 609
552 void FastCodeGenerator::VisitThrow(Throw* expr) { 610 void FastCodeGenerator::VisitThrow(Throw* expr) {
553 UNREACHABLE(); 611 UNREACHABLE();
554 } 612 }
555 613
556 614
615 int FastCodeGenerator::TryFinally::Exit(int stack_depth) {
616 __ Drop(stack_depth);
Kevin Millikin (Chromium) 2009/12/10 13:09:26 Good. I much prefer adjusting the stack pointer t
617 __ PopTryHandler();
618 __ Call(finally_entry_);
619 return 0;
620 }
621
622
623 int FastCodeGenerator::TryCatch::Exit(int stack_depth) {
624 __ Drop(stack_depth);
625 __ PopTryHandler();
626 return 0;
627 }
628
629
557 #undef __ 630 #undef __
558 631
559 632
560 } } // namespace v8::internal 633 } } // namespace v8::internal
OLDNEW
« src/fast-codegen.h ('K') | « src/fast-codegen.h ('k') | src/ia32/fast-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698