| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 } | 183 } |
| 184 | 184 |
| 185 | 185 |
| 186 void BreakableStatementChecker::VisitArrayLiteral(ArrayLiteral* expr) { | 186 void BreakableStatementChecker::VisitArrayLiteral(ArrayLiteral* expr) { |
| 187 } | 187 } |
| 188 | 188 |
| 189 | 189 |
| 190 void BreakableStatementChecker::VisitAssignment(Assignment* expr) { | 190 void BreakableStatementChecker::VisitAssignment(Assignment* expr) { |
| 191 // If assigning to a property (including a global property) the assignment is | 191 // If assigning to a property (including a global property) the assignment is |
| 192 // breakable. | 192 // breakable. |
| 193 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 193 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
| 194 Property* prop = expr->target()->AsProperty(); | 194 Property* prop = expr->target()->AsProperty(); |
| 195 if (prop != NULL || (var != NULL && var->is_global())) { | 195 if (prop != NULL || (proxy != NULL && proxy->var()->IsUnallocated())) { |
| 196 is_breakable_ = true; | 196 is_breakable_ = true; |
| 197 return; | 197 return; |
| 198 } | 198 } |
| 199 | 199 |
| 200 // Otherwise the assignment is breakable if the assigned value is. | 200 // Otherwise the assignment is breakable if the assigned value is. |
| 201 Visit(expr->value()); | 201 Visit(expr->value()); |
| 202 } | 202 } |
| 203 | 203 |
| 204 | 204 |
| 205 void BreakableStatementChecker::VisitThrow(Throw* expr) { | 205 void BreakableStatementChecker::VisitThrow(Throw* expr) { |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 | 388 |
| 389 | 389 |
| 390 void FullCodeGenerator::RecordStackCheck(int ast_id) { | 390 void FullCodeGenerator::RecordStackCheck(int ast_id) { |
| 391 // The pc offset does not need to be encoded and packed together with a | 391 // The pc offset does not need to be encoded and packed together with a |
| 392 // state. | 392 // state. |
| 393 BailoutEntry entry = { ast_id, masm_->pc_offset() }; | 393 BailoutEntry entry = { ast_id, masm_->pc_offset() }; |
| 394 stack_checks_.Add(entry); | 394 stack_checks_.Add(entry); |
| 395 } | 395 } |
| 396 | 396 |
| 397 | 397 |
| 398 int FullCodeGenerator::SlotOffset(Slot* slot) { | |
| 399 ASSERT(slot != NULL); | |
| 400 // Offset is negative because higher indexes are at lower addresses. | |
| 401 int offset = -slot->index() * kPointerSize; | |
| 402 // Adjust by a (parameter or local) base offset. | |
| 403 switch (slot->type()) { | |
| 404 case Slot::PARAMETER: | |
| 405 offset += (info_->scope()->num_parameters() + 1) * kPointerSize; | |
| 406 break; | |
| 407 case Slot::LOCAL: | |
| 408 offset += JavaScriptFrameConstants::kLocal0Offset; | |
| 409 break; | |
| 410 case Slot::CONTEXT: | |
| 411 case Slot::LOOKUP: | |
| 412 UNREACHABLE(); | |
| 413 } | |
| 414 return offset; | |
| 415 } | |
| 416 | |
| 417 | |
| 418 bool FullCodeGenerator::ShouldInlineSmiCase(Token::Value op) { | 398 bool FullCodeGenerator::ShouldInlineSmiCase(Token::Value op) { |
| 419 // Inline smi case inside loops, but not division and modulo which | 399 // Inline smi case inside loops, but not division and modulo which |
| 420 // are too complicated and take up too much space. | 400 // are too complicated and take up too much space. |
| 421 if (op == Token::DIV ||op == Token::MOD) return false; | 401 if (op == Token::DIV ||op == Token::MOD) return false; |
| 422 if (FLAG_always_inline_smi_code) return true; | 402 if (FLAG_always_inline_smi_code) return true; |
| 423 return loop_depth_ > 0; | 403 return loop_depth_ > 0; |
| 424 } | 404 } |
| 425 | 405 |
| 426 | 406 |
| 427 void FullCodeGenerator::EffectContext::Plug(Register reg) const { | 407 void FullCodeGenerator::EffectContext::Plug(Register reg) const { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 DoTest(context->condition(), | 502 DoTest(context->condition(), |
| 523 context->true_label(), | 503 context->true_label(), |
| 524 context->false_label(), | 504 context->false_label(), |
| 525 context->fall_through()); | 505 context->fall_through()); |
| 526 } | 506 } |
| 527 | 507 |
| 528 | 508 |
| 529 void FullCodeGenerator::VisitDeclarations( | 509 void FullCodeGenerator::VisitDeclarations( |
| 530 ZoneList<Declaration*>* declarations) { | 510 ZoneList<Declaration*>* declarations) { |
| 531 int length = declarations->length(); | 511 int length = declarations->length(); |
| 532 int globals = 0; | 512 int global_count = 0; |
| 533 for (int i = 0; i < length; i++) { | 513 for (int i = 0; i < length; i++) { |
| 534 Declaration* decl = declarations->at(i); | 514 Declaration* decl = declarations->at(i); |
| 535 Variable* var = decl->proxy()->var(); | 515 EmitDeclaration(decl->proxy(), decl->mode(), decl->fun(), &global_count); |
| 536 Slot* slot = var->AsSlot(); | |
| 537 | |
| 538 // If it was not possible to allocate the variable at compile | |
| 539 // time, we need to "declare" it at runtime to make sure it | |
| 540 // actually exists in the local context. | |
| 541 if ((slot != NULL && slot->type() == Slot::LOOKUP) || !var->is_global()) { | |
| 542 VisitDeclaration(decl); | |
| 543 } else { | |
| 544 // Count global variables and functions for later processing | |
| 545 globals++; | |
| 546 } | |
| 547 } | 516 } |
| 548 | 517 |
| 549 // Compute array of global variable and function declarations. | 518 // Batch declare global functions and variables. |
| 550 // Do nothing in case of no declared global functions or variables. | 519 if (global_count > 0) { |
| 551 if (globals > 0) { | |
| 552 Handle<FixedArray> array = | 520 Handle<FixedArray> array = |
| 553 isolate()->factory()->NewFixedArray(2 * globals, TENURED); | 521 isolate()->factory()->NewFixedArray(2 * global_count, TENURED); |
| 554 for (int j = 0, i = 0; i < length; i++) { | 522 for (int j = 0, i = 0; i < length; i++) { |
| 555 Declaration* decl = declarations->at(i); | 523 Declaration* decl = declarations->at(i); |
| 556 Variable* var = decl->proxy()->var(); | 524 Variable* var = decl->proxy()->var(); |
| 557 Slot* slot = var->AsSlot(); | |
| 558 | 525 |
| 559 if ((slot == NULL || slot->type() != Slot::LOOKUP) && var->is_global()) { | 526 if (var->IsUnallocated()) { |
| 560 array->set(j++, *(var->name())); | 527 array->set(j++, *(var->name())); |
| 561 if (decl->fun() == NULL) { | 528 if (decl->fun() == NULL) { |
| 562 if (var->mode() == Variable::CONST) { | 529 if (var->mode() == Variable::CONST) { |
| 563 // In case this is const property use the hole. | 530 // In case this is const property use the hole. |
| 564 array->set_the_hole(j++); | 531 array->set_the_hole(j++); |
| 565 } else { | 532 } else { |
| 566 array->set_undefined(j++); | 533 array->set_undefined(j++); |
| 567 } | 534 } |
| 568 } else { | 535 } else { |
| 569 Handle<SharedFunctionInfo> function = | 536 Handle<SharedFunctionInfo> function = |
| 570 Compiler::BuildFunctionInfo(decl->fun(), script()); | 537 Compiler::BuildFunctionInfo(decl->fun(), script()); |
| 571 // Check for stack-overflow exception. | 538 // Check for stack-overflow exception. |
| 572 if (function.is_null()) { | 539 if (function.is_null()) { |
| 573 SetStackOverflow(); | 540 SetStackOverflow(); |
| 574 return; | 541 return; |
| 575 } | 542 } |
| 576 array->set(j++, *function); | 543 array->set(j++, *function); |
| 577 } | 544 } |
| 578 } | 545 } |
| 579 } | 546 } |
| 580 // Invoke the platform-dependent code generator to do the actual | 547 // Invoke the platform-dependent code generator to do the actual |
| 581 // declaration the global variables and functions. | 548 // declaration the global functions and variables. |
| 582 DeclareGlobals(array); | 549 DeclareGlobals(array); |
| 583 } | 550 } |
| 584 } | 551 } |
| 585 | 552 |
| 586 | 553 |
| 587 int FullCodeGenerator::DeclareGlobalsFlags() { | 554 int FullCodeGenerator::DeclareGlobalsFlags() { |
| 588 int flags = 0; | 555 int flags = 0; |
| 589 if (is_eval()) flags |= kDeclareGlobalsEvalFlag; | 556 if (is_eval()) flags |= kDeclareGlobalsEvalFlag; |
| 590 if (is_strict_mode()) flags |= kDeclareGlobalsStrictModeFlag; | 557 if (is_strict_mode()) flags |= kDeclareGlobalsStrictModeFlag; |
| 591 if (is_native()) flags |= kDeclareGlobalsNativeFlag; | 558 if (is_native()) flags |= kDeclareGlobalsNativeFlag; |
| (...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1392 } | 1359 } |
| 1393 | 1360 |
| 1394 return false; | 1361 return false; |
| 1395 } | 1362 } |
| 1396 | 1363 |
| 1397 | 1364 |
| 1398 #undef __ | 1365 #undef __ |
| 1399 | 1366 |
| 1400 | 1367 |
| 1401 } } // namespace v8::internal | 1368 } } // namespace v8::internal |
| OLD | NEW |