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 |