b0bf3b84a9298fe1134090e241f0779f6e5cb7d3
[platform/upstream/nodejs.git] / deps / v8 / src / full-codegen.cc
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/v8.h"
6
7 #include "src/ast.h"
8 #include "src/ast-numbering.h"
9 #include "src/code-factory.h"
10 #include "src/codegen.h"
11 #include "src/compiler.h"
12 #include "src/debug.h"
13 #include "src/full-codegen.h"
14 #include "src/liveedit.h"
15 #include "src/macro-assembler.h"
16 #include "src/prettyprinter.h"
17 #include "src/scopeinfo.h"
18 #include "src/scopes.h"
19 #include "src/snapshot.h"
20
21 namespace v8 {
22 namespace internal {
23
24 void BreakableStatementChecker::Check(Statement* stmt) {
25   Visit(stmt);
26 }
27
28
29 void BreakableStatementChecker::Check(Expression* expr) {
30   Visit(expr);
31 }
32
33
34 void BreakableStatementChecker::VisitVariableDeclaration(
35     VariableDeclaration* decl) {
36 }
37
38
39 void BreakableStatementChecker::VisitFunctionDeclaration(
40     FunctionDeclaration* decl) {
41 }
42
43
44 void BreakableStatementChecker::VisitModuleDeclaration(
45     ModuleDeclaration* decl) {
46 }
47
48
49 void BreakableStatementChecker::VisitImportDeclaration(
50     ImportDeclaration* decl) {
51 }
52
53
54 void BreakableStatementChecker::VisitExportDeclaration(
55     ExportDeclaration* decl) {
56 }
57
58
59 void BreakableStatementChecker::VisitModuleLiteral(ModuleLiteral* module) {
60 }
61
62
63 void BreakableStatementChecker::VisitModulePath(ModulePath* module) {
64 }
65
66
67 void BreakableStatementChecker::VisitModuleUrl(ModuleUrl* module) {
68 }
69
70
71 void BreakableStatementChecker::VisitModuleStatement(ModuleStatement* stmt) {
72 }
73
74
75 void BreakableStatementChecker::VisitBlock(Block* stmt) {
76 }
77
78
79 void BreakableStatementChecker::VisitExpressionStatement(
80     ExpressionStatement* stmt) {
81   // Check if expression is breakable.
82   Visit(stmt->expression());
83 }
84
85
86 void BreakableStatementChecker::VisitEmptyStatement(EmptyStatement* stmt) {
87 }
88
89
90 void BreakableStatementChecker::VisitIfStatement(IfStatement* stmt) {
91   // If the condition is breakable the if statement is breakable.
92   Visit(stmt->condition());
93 }
94
95
96 void BreakableStatementChecker::VisitContinueStatement(
97     ContinueStatement* stmt) {
98 }
99
100
101 void BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) {
102 }
103
104
105 void BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) {
106   // Return is breakable if the expression is.
107   Visit(stmt->expression());
108 }
109
110
111 void BreakableStatementChecker::VisitWithStatement(WithStatement* stmt) {
112   Visit(stmt->expression());
113 }
114
115
116 void BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) {
117   // Switch statements breakable if the tag expression is.
118   Visit(stmt->tag());
119 }
120
121
122 void BreakableStatementChecker::VisitDoWhileStatement(DoWhileStatement* stmt) {
123   // Mark do while as breakable to avoid adding a break slot in front of it.
124   is_breakable_ = true;
125 }
126
127
128 void BreakableStatementChecker::VisitWhileStatement(WhileStatement* stmt) {
129   // Mark while statements breakable if the condition expression is.
130   Visit(stmt->cond());
131 }
132
133
134 void BreakableStatementChecker::VisitForStatement(ForStatement* stmt) {
135   // We set positions for both init and condition, if they exist.
136   if (stmt->cond() != NULL || stmt->init() != NULL) is_breakable_ = true;
137 }
138
139
140 void BreakableStatementChecker::VisitForInStatement(ForInStatement* stmt) {
141   // For-in is breakable because we set the position for the enumerable.
142   is_breakable_ = true;
143 }
144
145
146 void BreakableStatementChecker::VisitForOfStatement(ForOfStatement* stmt) {
147   // For-of is breakable because we set the position for the next() call.
148   is_breakable_ = true;
149 }
150
151
152 void BreakableStatementChecker::VisitTryCatchStatement(
153     TryCatchStatement* stmt) {
154   // Mark try catch as breakable to avoid adding a break slot in front of it.
155   is_breakable_ = true;
156 }
157
158
159 void BreakableStatementChecker::VisitTryFinallyStatement(
160     TryFinallyStatement* stmt) {
161   // Mark try finally as breakable to avoid adding a break slot in front of it.
162   is_breakable_ = true;
163 }
164
165
166 void BreakableStatementChecker::VisitDebuggerStatement(
167     DebuggerStatement* stmt) {
168   // The debugger statement is breakable.
169   is_breakable_ = true;
170 }
171
172
173 void BreakableStatementChecker::VisitCaseClause(CaseClause* clause) {
174 }
175
176
177 void BreakableStatementChecker::VisitFunctionLiteral(FunctionLiteral* expr) {
178 }
179
180
181 void BreakableStatementChecker::VisitClassLiteral(ClassLiteral* expr) {
182   if (expr->extends() != NULL) {
183     Visit(expr->extends());
184   }
185 }
186
187
188 void BreakableStatementChecker::VisitNativeFunctionLiteral(
189     NativeFunctionLiteral* expr) {
190 }
191
192
193 void BreakableStatementChecker::VisitConditional(Conditional* expr) {
194 }
195
196
197 void BreakableStatementChecker::VisitVariableProxy(VariableProxy* expr) {
198 }
199
200
201 void BreakableStatementChecker::VisitLiteral(Literal* expr) {
202 }
203
204
205 void BreakableStatementChecker::VisitRegExpLiteral(RegExpLiteral* expr) {
206 }
207
208
209 void BreakableStatementChecker::VisitObjectLiteral(ObjectLiteral* expr) {
210 }
211
212
213 void BreakableStatementChecker::VisitArrayLiteral(ArrayLiteral* expr) {
214 }
215
216
217 void BreakableStatementChecker::VisitAssignment(Assignment* expr) {
218   // If assigning to a property (including a global property) the assignment is
219   // breakable.
220   VariableProxy* proxy = expr->target()->AsVariableProxy();
221   Property* prop = expr->target()->AsProperty();
222   if (prop != NULL || (proxy != NULL && proxy->var()->IsUnallocated())) {
223     is_breakable_ = true;
224     return;
225   }
226
227   // Otherwise the assignment is breakable if the assigned value is.
228   Visit(expr->value());
229 }
230
231
232 void BreakableStatementChecker::VisitYield(Yield* expr) {
233   // Yield is breakable if the expression is.
234   Visit(expr->expression());
235 }
236
237
238 void BreakableStatementChecker::VisitThrow(Throw* expr) {
239   // Throw is breakable if the expression is.
240   Visit(expr->exception());
241 }
242
243
244 void BreakableStatementChecker::VisitProperty(Property* expr) {
245   // Property load is breakable.
246   is_breakable_ = true;
247 }
248
249
250 void BreakableStatementChecker::VisitCall(Call* expr) {
251   // Function calls both through IC and call stub are breakable.
252   is_breakable_ = true;
253 }
254
255
256 void BreakableStatementChecker::VisitCallNew(CallNew* expr) {
257   // Function calls through new are breakable.
258   is_breakable_ = true;
259 }
260
261
262 void BreakableStatementChecker::VisitCallRuntime(CallRuntime* expr) {
263 }
264
265
266 void BreakableStatementChecker::VisitUnaryOperation(UnaryOperation* expr) {
267   Visit(expr->expression());
268 }
269
270
271 void BreakableStatementChecker::VisitCountOperation(CountOperation* expr) {
272   Visit(expr->expression());
273 }
274
275
276 void BreakableStatementChecker::VisitBinaryOperation(BinaryOperation* expr) {
277   Visit(expr->left());
278   if (expr->op() != Token::AND &&
279       expr->op() != Token::OR) {
280     Visit(expr->right());
281   }
282 }
283
284
285 void BreakableStatementChecker::VisitCompareOperation(CompareOperation* expr) {
286   Visit(expr->left());
287   Visit(expr->right());
288 }
289
290
291 void BreakableStatementChecker::VisitThisFunction(ThisFunction* expr) {
292 }
293
294
295 void BreakableStatementChecker::VisitSuperReference(SuperReference* expr) {}
296
297
298 #define __ ACCESS_MASM(masm())
299
300 bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
301   Isolate* isolate = info->isolate();
302
303   TimerEventScope<TimerEventCompileFullCode> timer(info->isolate());
304
305   // Ensure that the feedback vector is large enough.
306   info->EnsureFeedbackVector();
307
308   Handle<Script> script = info->script();
309   if (!script->IsUndefined() && !script->source()->IsUndefined()) {
310     int len = String::cast(script->source())->length();
311     isolate->counters()->total_full_codegen_source_size()->Increment(len);
312   }
313   CodeGenerator::MakeCodePrologue(info, "full");
314   const int kInitialBufferSize = 4 * KB;
315   MacroAssembler masm(info->isolate(), NULL, kInitialBufferSize);
316   if (info->will_serialize()) masm.enable_serializer();
317
318   LOG_CODE_EVENT(isolate,
319                  CodeStartLinePosInfoRecordEvent(masm.positions_recorder()));
320
321   FullCodeGenerator cgen(&masm, info);
322   cgen.Generate();
323   if (cgen.HasStackOverflow()) {
324     DCHECK(!isolate->has_pending_exception());
325     return false;
326   }
327   unsigned table_offset = cgen.EmitBackEdgeTable();
328
329   Code::Flags flags = Code::ComputeFlags(Code::FUNCTION);
330   Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
331   code->set_optimizable(info->IsOptimizable() &&
332                         !info->function()->dont_optimize() &&
333                         info->function()->scope()->AllowsLazyCompilation());
334   cgen.PopulateDeoptimizationData(code);
335   cgen.PopulateTypeFeedbackInfo(code);
336   code->set_has_deoptimization_support(info->HasDeoptimizationSupport());
337   code->set_has_reloc_info_for_serialization(info->will_serialize());
338   code->set_handler_table(*cgen.handler_table());
339   code->set_compiled_optimizable(info->IsOptimizable());
340   code->set_allow_osr_at_loop_nesting_level(0);
341   code->set_profiler_ticks(0);
342   code->set_back_edge_table_offset(table_offset);
343   CodeGenerator::PrintCode(code, info);
344   info->SetCode(code);
345   void* line_info = masm.positions_recorder()->DetachJITHandlerData();
346   LOG_CODE_EVENT(isolate, CodeEndLinePosInfoRecordEvent(*code, line_info));
347
348 #ifdef DEBUG
349   // Check that no context-specific object has been embedded.
350   code->VerifyEmbeddedObjects(Code::kNoContextSpecificPointers);
351 #endif  // DEBUG
352   return true;
353 }
354
355
356 unsigned FullCodeGenerator::EmitBackEdgeTable() {
357   // The back edge table consists of a length (in number of entries)
358   // field, and then a sequence of entries.  Each entry is a pair of AST id
359   // and code-relative pc offset.
360   masm()->Align(kPointerSize);
361   unsigned offset = masm()->pc_offset();
362   unsigned length = back_edges_.length();
363   __ dd(length);
364   for (unsigned i = 0; i < length; ++i) {
365     __ dd(back_edges_[i].id.ToInt());
366     __ dd(back_edges_[i].pc);
367     __ dd(back_edges_[i].loop_depth);
368   }
369   return offset;
370 }
371
372
373 void FullCodeGenerator::EnsureSlotContainsAllocationSite(
374     FeedbackVectorSlot slot) {
375   Handle<TypeFeedbackVector> vector = FeedbackVector();
376   if (!vector->Get(slot)->IsAllocationSite()) {
377     Handle<AllocationSite> allocation_site =
378         isolate()->factory()->NewAllocationSite();
379     vector->Set(slot, *allocation_site);
380   }
381 }
382
383
384 void FullCodeGenerator::EnsureSlotContainsAllocationSite(
385     FeedbackVectorICSlot slot) {
386   Handle<TypeFeedbackVector> vector = FeedbackVector();
387   if (!vector->Get(slot)->IsAllocationSite()) {
388     Handle<AllocationSite> allocation_site =
389         isolate()->factory()->NewAllocationSite();
390     vector->Set(slot, *allocation_site);
391   }
392 }
393
394
395 void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) {
396   // Fill in the deoptimization information.
397   DCHECK(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty());
398   if (!info_->HasDeoptimizationSupport()) return;
399   int length = bailout_entries_.length();
400   Handle<DeoptimizationOutputData> data =
401       DeoptimizationOutputData::New(isolate(), length, TENURED);
402   for (int i = 0; i < length; i++) {
403     data->SetAstId(i, bailout_entries_[i].id);
404     data->SetPcAndState(i, Smi::FromInt(bailout_entries_[i].pc_and_state));
405   }
406   code->set_deoptimization_data(*data);
407 }
408
409
410 void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) {
411   Handle<TypeFeedbackInfo> info = isolate()->factory()->NewTypeFeedbackInfo();
412   info->set_ic_total_count(ic_total_count_);
413   DCHECK(!isolate()->heap()->InNewSpace(*info));
414   code->set_type_feedback_info(*info);
415 }
416
417
418 bool FullCodeGenerator::MustCreateObjectLiteralWithRuntime(
419     ObjectLiteral* expr) const {
420   // FastCloneShallowObjectStub doesn't copy elements, and object literals don't
421   // support copy-on-write (COW) elements for now.
422   // TODO(mvstanton): make object literals support COW elements.
423   return expr->may_store_doubles() || expr->depth() > 1 ||
424          masm()->serializer_enabled() ||
425          expr->ComputeFlags() != ObjectLiteral::kFastElements ||
426          expr->has_elements() ||
427          expr->properties_count() >
428              FastCloneShallowObjectStub::kMaximumClonedProperties;
429 }
430
431
432 bool FullCodeGenerator::MustCreateArrayLiteralWithRuntime(
433     ArrayLiteral* expr) const {
434   return expr->depth() > 1 ||
435          expr->values()->length() > JSObject::kInitialMaxFastElementArray;
436 }
437
438
439 void FullCodeGenerator::Initialize() {
440   InitializeAstVisitor(info_->isolate(), info_->zone());
441   // The generation of debug code must match between the snapshot code and the
442   // code that is generated later.  This is assumed by the debugger when it is
443   // calculating PC offsets after generating a debug version of code.  Therefore
444   // we disable the production of debug code in the full compiler if we are
445   // either generating a snapshot or we booted from a snapshot.
446   generate_debug_code_ = FLAG_debug_code &&
447                          !masm_->serializer_enabled() &&
448                          !Snapshot::HaveASnapshotToStartFrom();
449   masm_->set_emit_debug_code(generate_debug_code_);
450   masm_->set_predictable_code_size(true);
451 }
452
453
454 void FullCodeGenerator::PrepareForBailout(Expression* node, State state) {
455   PrepareForBailoutForId(node->id(), state);
456 }
457
458
459 void FullCodeGenerator::CallLoadIC(ContextualMode contextual_mode,
460                                    TypeFeedbackId id) {
461   Handle<Code> ic = CodeFactory::LoadIC(isolate(), contextual_mode).code();
462   CallIC(ic, id);
463 }
464
465
466 void FullCodeGenerator::CallStoreIC(TypeFeedbackId id) {
467   Handle<Code> ic = CodeFactory::StoreIC(isolate(), language_mode()).code();
468   CallIC(ic, id);
469 }
470
471
472 void FullCodeGenerator::RecordJSReturnSite(Call* call) {
473   // We record the offset of the function return so we can rebuild the frame
474   // if the function was inlined, i.e., this is the return address in the
475   // inlined function's frame.
476   //
477   // The state is ignored.  We defensively set it to TOS_REG, which is the
478   // real state of the unoptimized code at the return site.
479   PrepareForBailoutForId(call->ReturnId(), TOS_REG);
480 #ifdef DEBUG
481   // In debug builds, mark the return so we can verify that this function
482   // was called.
483   DCHECK(!call->return_is_recorded_);
484   call->return_is_recorded_ = true;
485 #endif
486 }
487
488
489 void FullCodeGenerator::PrepareForBailoutForId(BailoutId id, State state) {
490   // There's no need to prepare this code for bailouts from already optimized
491   // code or code that can't be optimized.
492   if (!info_->HasDeoptimizationSupport()) return;
493   unsigned pc_and_state =
494       StateField::encode(state) | PcField::encode(masm_->pc_offset());
495   DCHECK(Smi::IsValid(pc_and_state));
496 #ifdef DEBUG
497   for (int i = 0; i < bailout_entries_.length(); ++i) {
498     DCHECK(bailout_entries_[i].id != id);
499   }
500 #endif
501   BailoutEntry entry = { id, pc_and_state };
502   bailout_entries_.Add(entry, zone());
503 }
504
505
506 void FullCodeGenerator::RecordBackEdge(BailoutId ast_id) {
507   // The pc offset does not need to be encoded and packed together with a state.
508   DCHECK(masm_->pc_offset() > 0);
509   DCHECK(loop_depth() > 0);
510   uint8_t depth = Min(loop_depth(), Code::kMaxLoopNestingMarker);
511   BackEdgeEntry entry =
512       { ast_id, static_cast<unsigned>(masm_->pc_offset()), depth };
513   back_edges_.Add(entry, zone());
514 }
515
516
517 bool FullCodeGenerator::ShouldInlineSmiCase(Token::Value op) {
518   // Inline smi case inside loops, but not division and modulo which
519   // are too complicated and take up too much space.
520   if (op == Token::DIV ||op == Token::MOD) return false;
521   if (FLAG_always_inline_smi_code) return true;
522   return loop_depth_ > 0;
523 }
524
525
526 void FullCodeGenerator::EffectContext::Plug(Register reg) const {
527 }
528
529
530 void FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const {
531   __ Move(result_register(), reg);
532 }
533
534
535 void FullCodeGenerator::StackValueContext::Plug(Register reg) const {
536   __ Push(reg);
537 }
538
539
540 void FullCodeGenerator::TestContext::Plug(Register reg) const {
541   // For simplicity we always test the accumulator register.
542   __ Move(result_register(), reg);
543   codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
544   codegen()->DoTest(this);
545 }
546
547
548 void FullCodeGenerator::EffectContext::PlugTOS() const {
549   __ Drop(1);
550 }
551
552
553 void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const {
554   __ Pop(result_register());
555 }
556
557
558 void FullCodeGenerator::StackValueContext::PlugTOS() const {
559 }
560
561
562 void FullCodeGenerator::TestContext::PlugTOS() const {
563   // For simplicity we always test the accumulator register.
564   __ Pop(result_register());
565   codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
566   codegen()->DoTest(this);
567 }
568
569
570 void FullCodeGenerator::EffectContext::PrepareTest(
571     Label* materialize_true,
572     Label* materialize_false,
573     Label** if_true,
574     Label** if_false,
575     Label** fall_through) const {
576   // In an effect context, the true and the false case branch to the
577   // same label.
578   *if_true = *if_false = *fall_through = materialize_true;
579 }
580
581
582 void FullCodeGenerator::AccumulatorValueContext::PrepareTest(
583     Label* materialize_true,
584     Label* materialize_false,
585     Label** if_true,
586     Label** if_false,
587     Label** fall_through) const {
588   *if_true = *fall_through = materialize_true;
589   *if_false = materialize_false;
590 }
591
592
593 void FullCodeGenerator::StackValueContext::PrepareTest(
594     Label* materialize_true,
595     Label* materialize_false,
596     Label** if_true,
597     Label** if_false,
598     Label** fall_through) const {
599   *if_true = *fall_through = materialize_true;
600   *if_false = materialize_false;
601 }
602
603
604 void FullCodeGenerator::TestContext::PrepareTest(
605     Label* materialize_true,
606     Label* materialize_false,
607     Label** if_true,
608     Label** if_false,
609     Label** fall_through) const {
610   *if_true = true_label_;
611   *if_false = false_label_;
612   *fall_through = fall_through_;
613 }
614
615
616 void FullCodeGenerator::DoTest(const TestContext* context) {
617   DoTest(context->condition(),
618          context->true_label(),
619          context->false_label(),
620          context->fall_through());
621 }
622
623
624 void FullCodeGenerator::AllocateModules(ZoneList<Declaration*>* declarations) {
625   DCHECK(scope_->is_script_scope());
626
627   for (int i = 0; i < declarations->length(); i++) {
628     ModuleDeclaration* declaration = declarations->at(i)->AsModuleDeclaration();
629     if (declaration != NULL) {
630       ModuleLiteral* module = declaration->module()->AsModuleLiteral();
631       if (module != NULL) {
632         Comment cmnt(masm_, "[ Link nested modules");
633         Scope* scope = module->body()->scope();
634         DCHECK(scope->module()->IsFrozen());
635
636         scope->module()->Allocate(scope->module_var()->index());
637
638         // Set up module context.
639         DCHECK(scope->module()->Index() >= 0);
640         __ Push(Smi::FromInt(scope->module()->Index()));
641         __ Push(scope->GetScopeInfo(isolate()));
642         __ CallRuntime(Runtime::kPushModuleContext, 2);
643         StoreToFrameField(StandardFrameConstants::kContextOffset,
644                           context_register());
645
646         AllocateModules(scope->declarations());
647
648         // Pop module context.
649         LoadContextField(context_register(), Context::PREVIOUS_INDEX);
650         // Update local stack frame context field.
651         StoreToFrameField(StandardFrameConstants::kContextOffset,
652                           context_register());
653       }
654     }
655   }
656 }
657
658
659 // Modules have their own local scope, represented by their own context.
660 // Module instance objects have an accessor for every export that forwards
661 // access to the respective slot from the module's context. (Exports that are
662 // modules themselves, however, are simple data properties.)
663 //
664 // All modules have a _hosting_ scope/context, which (currently) is the
665 // enclosing script scope. To deal with recursion, nested modules are hosted
666 // by the same scope as global ones.
667 //
668 // For every (global or nested) module literal, the hosting context has an
669 // internal slot that points directly to the respective module context. This
670 // enables quick access to (statically resolved) module members by 2-dimensional
671 // access through the hosting context. For example,
672 //
673 //   module A {
674 //     let x;
675 //     module B { let y; }
676 //   }
677 //   module C { let z; }
678 //
679 // allocates contexts as follows:
680 //
681 // [header| .A | .B | .C | A | C ]  (global)
682 //           |    |    |
683 //           |    |    +-- [header| z ]  (module)
684 //           |    |
685 //           |    +------- [header| y ]  (module)
686 //           |
687 //           +------------ [header| x | B ]  (module)
688 //
689 // Here, .A, .B, .C are the internal slots pointing to the hosted module
690 // contexts, whereas A, B, C hold the actual instance objects (note that every
691 // module context also points to the respective instance object through its
692 // extension slot in the header).
693 //
694 // To deal with arbitrary recursion and aliases between modules,
695 // they are created and initialized in several stages. Each stage applies to
696 // all modules in the hosting script scope, including nested ones.
697 //
698 // 1. Allocate: for each module _literal_, allocate the module contexts and
699 //    respective instance object and wire them up. This happens in the
700 //    PushModuleContext runtime function, as generated by AllocateModules
701 //    (invoked by VisitDeclarations in the hosting scope).
702 //
703 // 2. Bind: for each module _declaration_ (i.e. literals as well as aliases),
704 //    assign the respective instance object to respective local variables. This
705 //    happens in VisitModuleDeclaration, and uses the instance objects created
706 //    in the previous stage.
707 //    For each module _literal_, this phase also constructs a module descriptor
708 //    for the next stage. This happens in VisitModuleLiteral.
709 //
710 // 3. Populate: invoke the DeclareModules runtime function to populate each
711 //    _instance_ object with accessors for it exports. This is generated by
712 //    DeclareModules (invoked by VisitDeclarations in the hosting scope again),
713 //    and uses the descriptors generated in the previous stage.
714 //
715 // 4. Initialize: execute the module bodies (and other code) in sequence. This
716 //    happens by the separate statements generated for module bodies. To reenter
717 //    the module scopes properly, the parser inserted ModuleStatements.
718
719 void FullCodeGenerator::VisitDeclarations(
720     ZoneList<Declaration*>* declarations) {
721   Handle<FixedArray> saved_modules = modules_;
722   int saved_module_index = module_index_;
723   ZoneList<Handle<Object> >* saved_globals = globals_;
724   ZoneList<Handle<Object> > inner_globals(10, zone());
725   globals_ = &inner_globals;
726
727   if (scope_->num_modules() != 0) {
728     // This is a scope hosting modules. Allocate a descriptor array to pass
729     // to the runtime for initialization.
730     Comment cmnt(masm_, "[ Allocate modules");
731     DCHECK(scope_->is_script_scope());
732     modules_ =
733         isolate()->factory()->NewFixedArray(scope_->num_modules(), TENURED);
734     module_index_ = 0;
735
736     // Generate code for allocating all modules, including nested ones.
737     // The allocated contexts are stored in internal variables in this scope.
738     AllocateModules(declarations);
739   }
740
741   AstVisitor::VisitDeclarations(declarations);
742
743   if (scope_->num_modules() != 0) {
744     // TODO(ES6): This step, which creates module instance objects,
745     // can probably be delayed until an "import *" declaration
746     // reifies a module instance. Until imports are implemented,
747     // we skip it altogether.
748     //
749     // Initialize modules from descriptor array.
750     //  DCHECK(module_index_ == modules_->length());
751     //  DeclareModules(modules_);
752     modules_ = saved_modules;
753     module_index_ = saved_module_index;
754   }
755
756   if (!globals_->is_empty()) {
757     // Invoke the platform-dependent code generator to do the actual
758     // declaration of the global functions and variables.
759     Handle<FixedArray> array =
760        isolate()->factory()->NewFixedArray(globals_->length(), TENURED);
761     for (int i = 0; i < globals_->length(); ++i)
762       array->set(i, *globals_->at(i));
763     DeclareGlobals(array);
764   }
765
766   globals_ = saved_globals;
767 }
768
769
770 void FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) {
771   Block* block = module->body();
772   Scope* saved_scope = scope();
773   scope_ = block->scope();
774   ModuleDescriptor* descriptor = scope_->module();
775
776   Comment cmnt(masm_, "[ ModuleLiteral");
777   SetStatementPosition(block);
778
779   DCHECK(!modules_.is_null());
780   DCHECK(module_index_ < modules_->length());
781   int index = module_index_++;
782
783   // Set up module context.
784   DCHECK(descriptor->Index() >= 0);
785   __ Push(Smi::FromInt(descriptor->Index()));
786   __ Push(Smi::FromInt(0));
787   __ CallRuntime(Runtime::kPushModuleContext, 2);
788   StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
789
790   {
791     Comment cmnt(masm_, "[ Declarations");
792     VisitDeclarations(scope_->declarations());
793   }
794
795   // Populate the module description.
796   Handle<ModuleInfo> description =
797       ModuleInfo::Create(isolate(), descriptor, scope_);
798   modules_->set(index, *description);
799
800   scope_ = saved_scope;
801   // Pop module context.
802   LoadContextField(context_register(), Context::PREVIOUS_INDEX);
803   // Update local stack frame context field.
804   StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
805 }
806
807
808 // TODO(adamk): Delete ModulePath.
809 void FullCodeGenerator::VisitModulePath(ModulePath* module) {
810 }
811
812
813 // TODO(adamk): Delete ModuleUrl.
814 void FullCodeGenerator::VisitModuleUrl(ModuleUrl* module) {
815 }
816
817
818 int FullCodeGenerator::DeclareGlobalsFlags() {
819   DCHECK(DeclareGlobalsLanguageMode::is_valid(language_mode()));
820   return DeclareGlobalsEvalFlag::encode(is_eval()) |
821          DeclareGlobalsNativeFlag::encode(is_native()) |
822          DeclareGlobalsLanguageMode::encode(language_mode());
823 }
824
825
826 void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
827   CodeGenerator::RecordPositions(masm_, fun->start_position());
828 }
829
830
831 void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
832   CodeGenerator::RecordPositions(masm_, fun->end_position() - 1);
833 }
834
835
836 void FullCodeGenerator::SetStatementPosition(Statement* stmt) {
837   if (!info_->is_debug()) {
838     CodeGenerator::RecordPositions(masm_, stmt->position());
839   } else {
840     // Check if the statement will be breakable without adding a debug break
841     // slot.
842     BreakableStatementChecker checker(info_->isolate(), zone());
843     checker.Check(stmt);
844     // Record the statement position right here if the statement is not
845     // breakable. For breakable statements the actual recording of the
846     // position will be postponed to the breakable code (typically an IC).
847     bool position_recorded = CodeGenerator::RecordPositions(
848         masm_, stmt->position(), !checker.is_breakable());
849     // If the position recording did record a new position generate a debug
850     // break slot to make the statement breakable.
851     if (position_recorded) {
852       DebugCodegen::GenerateSlot(masm_);
853     }
854   }
855 }
856
857
858 void FullCodeGenerator::VisitSuperReference(SuperReference* super) {
859   __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0);
860 }
861
862
863 bool FullCodeGenerator::ValidateSuperCall(Call* expr) {
864   Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
865   if (new_target_var == nullptr) {
866     // TODO(dslomov): this is not exactly correct, the spec requires us
867     // to execute the constructor and only fail when an assigment to 'this'
868     // is attempted. Will implement once we have general new.target support,
869     // but also filed spec bug 3843 to make it an early error.
870     __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0);
871     RecordJSReturnSite(expr);
872     context()->Plug(result_register());
873     return false;
874   }
875   return true;
876 }
877
878
879 void FullCodeGenerator::SetExpressionPosition(Expression* expr) {
880   if (!info_->is_debug()) {
881     CodeGenerator::RecordPositions(masm_, expr->position());
882   } else {
883     // Check if the expression will be breakable without adding a debug break
884     // slot.
885     BreakableStatementChecker checker(info_->isolate(), zone());
886     checker.Check(expr);
887     // Record a statement position right here if the expression is not
888     // breakable. For breakable expressions the actual recording of the
889     // position will be postponed to the breakable code (typically an IC).
890     // NOTE this will record a statement position for something which might
891     // not be a statement. As stepping in the debugger will only stop at
892     // statement positions this is used for e.g. the condition expression of
893     // a do while loop.
894     bool position_recorded = CodeGenerator::RecordPositions(
895         masm_, expr->position(), !checker.is_breakable());
896     // If the position recording did record a new position generate a debug
897     // break slot to make the statement breakable.
898     if (position_recorded) {
899       DebugCodegen::GenerateSlot(masm_);
900     }
901   }
902 }
903
904
905 void FullCodeGenerator::SetSourcePosition(int pos) {
906   if (pos != RelocInfo::kNoPosition) {
907     masm_->positions_recorder()->RecordPosition(pos);
908   }
909 }
910
911
912 // Lookup table for code generators for  special runtime calls which are
913 // generated inline.
914 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize)          \
915     &FullCodeGenerator::Emit##Name,
916
917 const FullCodeGenerator::InlineFunctionGenerator
918   FullCodeGenerator::kInlineFunctionGenerators[] = {
919     INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
920   };
921 #undef INLINE_FUNCTION_GENERATOR_ADDRESS
922
923
924 FullCodeGenerator::InlineFunctionGenerator
925   FullCodeGenerator::FindInlineFunctionGenerator(Runtime::FunctionId id) {
926     int lookup_index =
927         static_cast<int>(id) - static_cast<int>(Runtime::kFirstInlineFunction);
928     DCHECK(lookup_index >= 0);
929     DCHECK(static_cast<size_t>(lookup_index) <
930            arraysize(kInlineFunctionGenerators));
931     return kInlineFunctionGenerators[lookup_index];
932 }
933
934
935 void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* expr) {
936   const Runtime::Function* function = expr->function();
937   DCHECK(function != NULL);
938   DCHECK(function->intrinsic_type == Runtime::INLINE);
939   InlineFunctionGenerator generator =
940       FindInlineFunctionGenerator(function->function_id);
941   ((*this).*(generator))(expr);
942 }
943
944
945 void FullCodeGenerator::EmitGeneratorNext(CallRuntime* expr) {
946   ZoneList<Expression*>* args = expr->arguments();
947   DCHECK(args->length() == 2);
948   EmitGeneratorResume(args->at(0), args->at(1), JSGeneratorObject::NEXT);
949 }
950
951
952 void FullCodeGenerator::EmitGeneratorThrow(CallRuntime* expr) {
953   ZoneList<Expression*>* args = expr->arguments();
954   DCHECK(args->length() == 2);
955   EmitGeneratorResume(args->at(0), args->at(1), JSGeneratorObject::THROW);
956 }
957
958
959 void FullCodeGenerator::EmitDebugBreakInOptimizedCode(CallRuntime* expr) {
960   context()->Plug(handle(Smi::FromInt(0), isolate()));
961 }
962
963
964 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
965   switch (expr->op()) {
966     case Token::COMMA:
967       return VisitComma(expr);
968     case Token::OR:
969     case Token::AND:
970       return VisitLogicalExpression(expr);
971     default:
972       return VisitArithmeticExpression(expr);
973   }
974 }
975
976
977 void FullCodeGenerator::VisitInDuplicateContext(Expression* expr) {
978   if (context()->IsEffect()) {
979     VisitForEffect(expr);
980   } else if (context()->IsAccumulatorValue()) {
981     VisitForAccumulatorValue(expr);
982   } else if (context()->IsStackValue()) {
983     VisitForStackValue(expr);
984   } else if (context()->IsTest()) {
985     const TestContext* test = TestContext::cast(context());
986     VisitForControl(expr, test->true_label(), test->false_label(),
987                     test->fall_through());
988   }
989 }
990
991
992 void FullCodeGenerator::VisitComma(BinaryOperation* expr) {
993   Comment cmnt(masm_, "[ Comma");
994   VisitForEffect(expr->left());
995   VisitInDuplicateContext(expr->right());
996 }
997
998
999 void FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) {
1000   bool is_logical_and = expr->op() == Token::AND;
1001   Comment cmnt(masm_, is_logical_and ? "[ Logical AND" :  "[ Logical OR");
1002   Expression* left = expr->left();
1003   Expression* right = expr->right();
1004   BailoutId right_id = expr->RightId();
1005   Label done;
1006
1007   if (context()->IsTest()) {
1008     Label eval_right;
1009     const TestContext* test = TestContext::cast(context());
1010     if (is_logical_and) {
1011       VisitForControl(left, &eval_right, test->false_label(), &eval_right);
1012     } else {
1013       VisitForControl(left, test->true_label(), &eval_right, &eval_right);
1014     }
1015     PrepareForBailoutForId(right_id, NO_REGISTERS);
1016     __ bind(&eval_right);
1017
1018   } else if (context()->IsAccumulatorValue()) {
1019     VisitForAccumulatorValue(left);
1020     // We want the value in the accumulator for the test, and on the stack in
1021     // case we need it.
1022     __ Push(result_register());
1023     Label discard, restore;
1024     if (is_logical_and) {
1025       DoTest(left, &discard, &restore, &restore);
1026     } else {
1027       DoTest(left, &restore, &discard, &restore);
1028     }
1029     __ bind(&restore);
1030     __ Pop(result_register());
1031     __ jmp(&done);
1032     __ bind(&discard);
1033     __ Drop(1);
1034     PrepareForBailoutForId(right_id, NO_REGISTERS);
1035
1036   } else if (context()->IsStackValue()) {
1037     VisitForAccumulatorValue(left);
1038     // We want the value in the accumulator for the test, and on the stack in
1039     // case we need it.
1040     __ Push(result_register());
1041     Label discard;
1042     if (is_logical_and) {
1043       DoTest(left, &discard, &done, &discard);
1044     } else {
1045       DoTest(left, &done, &discard, &discard);
1046     }
1047     __ bind(&discard);
1048     __ Drop(1);
1049     PrepareForBailoutForId(right_id, NO_REGISTERS);
1050
1051   } else {
1052     DCHECK(context()->IsEffect());
1053     Label eval_right;
1054     if (is_logical_and) {
1055       VisitForControl(left, &eval_right, &done, &eval_right);
1056     } else {
1057       VisitForControl(left, &done, &eval_right, &eval_right);
1058     }
1059     PrepareForBailoutForId(right_id, NO_REGISTERS);
1060     __ bind(&eval_right);
1061   }
1062
1063   VisitInDuplicateContext(right);
1064   __ bind(&done);
1065 }
1066
1067
1068 void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
1069   Token::Value op = expr->op();
1070   Comment cmnt(masm_, "[ ArithmeticExpression");
1071   Expression* left = expr->left();
1072   Expression* right = expr->right();
1073
1074   VisitForStackValue(left);
1075   VisitForAccumulatorValue(right);
1076
1077   SetSourcePosition(expr->position());
1078   if (ShouldInlineSmiCase(op)) {
1079     EmitInlineSmiBinaryOp(expr, op, left, right);
1080   } else {
1081     EmitBinaryOp(expr, op);
1082   }
1083 }
1084
1085
1086 void FullCodeGenerator::VisitBlock(Block* stmt) {
1087   Comment cmnt(masm_, "[ Block");
1088   NestedBlock nested_block(this, stmt);
1089   SetStatementPosition(stmt);
1090
1091   {
1092     EnterBlockScopeIfNeeded block_scope_state(
1093         this, stmt->scope(), stmt->EntryId(), stmt->DeclsId(), stmt->ExitId());
1094     VisitStatements(stmt->statements());
1095     __ bind(nested_block.break_label());
1096   }
1097 }
1098
1099
1100 void FullCodeGenerator::VisitModuleStatement(ModuleStatement* stmt) {
1101   Comment cmnt(masm_, "[ Module context");
1102
1103   DCHECK(stmt->body()->scope()->is_module_scope());
1104
1105   __ Push(Smi::FromInt(stmt->body()->scope()->module()->Index()));
1106   __ Push(Smi::FromInt(0));
1107   __ CallRuntime(Runtime::kPushModuleContext, 2);
1108   StoreToFrameField(
1109       StandardFrameConstants::kContextOffset, context_register());
1110
1111   Scope* saved_scope = scope_;
1112   scope_ = stmt->body()->scope();
1113   VisitStatements(stmt->body()->statements());
1114   scope_ = saved_scope;
1115   LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1116   // Update local stack frame context field.
1117   StoreToFrameField(StandardFrameConstants::kContextOffset,
1118                     context_register());
1119 }
1120
1121
1122 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
1123   Comment cmnt(masm_, "[ ExpressionStatement");
1124   SetStatementPosition(stmt);
1125   VisitForEffect(stmt->expression());
1126 }
1127
1128
1129 void FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
1130   Comment cmnt(masm_, "[ EmptyStatement");
1131   SetStatementPosition(stmt);
1132 }
1133
1134
1135 void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) {
1136   Comment cmnt(masm_, "[ IfStatement");
1137   SetStatementPosition(stmt);
1138   Label then_part, else_part, done;
1139
1140   if (stmt->HasElseStatement()) {
1141     VisitForControl(stmt->condition(), &then_part, &else_part, &then_part);
1142     PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS);
1143     __ bind(&then_part);
1144     Visit(stmt->then_statement());
1145     __ jmp(&done);
1146
1147     PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS);
1148     __ bind(&else_part);
1149     Visit(stmt->else_statement());
1150   } else {
1151     VisitForControl(stmt->condition(), &then_part, &done, &then_part);
1152     PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS);
1153     __ bind(&then_part);
1154     Visit(stmt->then_statement());
1155
1156     PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS);
1157   }
1158   __ bind(&done);
1159   PrepareForBailoutForId(stmt->IfId(), NO_REGISTERS);
1160 }
1161
1162
1163 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
1164   Comment cmnt(masm_,  "[ ContinueStatement");
1165   SetStatementPosition(stmt);
1166   NestedStatement* current = nesting_stack_;
1167   int stack_depth = 0;
1168   int context_length = 0;
1169   // When continuing, we clobber the unpredictable value in the accumulator
1170   // with one that's safe for GC.  If we hit an exit from the try block of
1171   // try...finally on our way out, we will unconditionally preserve the
1172   // accumulator on the stack.
1173   ClearAccumulator();
1174   while (!current->IsContinueTarget(stmt->target())) {
1175     current = current->Exit(&stack_depth, &context_length);
1176   }
1177   __ Drop(stack_depth);
1178   if (context_length > 0) {
1179     while (context_length > 0) {
1180       LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1181       --context_length;
1182     }
1183     StoreToFrameField(StandardFrameConstants::kContextOffset,
1184                       context_register());
1185   }
1186
1187   __ jmp(current->AsIteration()->continue_label());
1188 }
1189
1190
1191 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
1192   Comment cmnt(masm_,  "[ BreakStatement");
1193   SetStatementPosition(stmt);
1194   NestedStatement* current = nesting_stack_;
1195   int stack_depth = 0;
1196   int context_length = 0;
1197   // When breaking, we clobber the unpredictable value in the accumulator
1198   // with one that's safe for GC.  If we hit an exit from the try block of
1199   // try...finally on our way out, we will unconditionally preserve the
1200   // accumulator on the stack.
1201   ClearAccumulator();
1202   while (!current->IsBreakTarget(stmt->target())) {
1203     current = current->Exit(&stack_depth, &context_length);
1204   }
1205   __ Drop(stack_depth);
1206   if (context_length > 0) {
1207     while (context_length > 0) {
1208       LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1209       --context_length;
1210     }
1211     StoreToFrameField(StandardFrameConstants::kContextOffset,
1212                       context_register());
1213   }
1214
1215   __ jmp(current->AsBreakable()->break_label());
1216 }
1217
1218
1219 void FullCodeGenerator::EmitUnwindBeforeReturn() {
1220   NestedStatement* current = nesting_stack_;
1221   int stack_depth = 0;
1222   int context_length = 0;
1223   while (current != NULL) {
1224     current = current->Exit(&stack_depth, &context_length);
1225   }
1226   __ Drop(stack_depth);
1227 }
1228
1229
1230 void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property,
1231                                         BailoutId bailout_id) {
1232   VisitForStackValue(property->key());
1233   __ InvokeBuiltin(Builtins::TO_NAME, CALL_FUNCTION);
1234   PrepareForBailoutForId(bailout_id, NO_REGISTERS);
1235   __ Push(result_register());
1236 }
1237
1238
1239 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
1240   Comment cmnt(masm_, "[ ReturnStatement");
1241   SetStatementPosition(stmt);
1242   Expression* expr = stmt->expression();
1243   VisitForAccumulatorValue(expr);
1244   EmitUnwindBeforeReturn();
1245   EmitReturnSequence();
1246 }
1247
1248
1249 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) {
1250   Comment cmnt(masm_, "[ WithStatement");
1251   SetStatementPosition(stmt);
1252
1253   VisitForStackValue(stmt->expression());
1254   PushFunctionArgumentForContextAllocation();
1255   __ CallRuntime(Runtime::kPushWithContext, 2);
1256   StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1257   PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
1258
1259   Scope* saved_scope = scope();
1260   scope_ = stmt->scope();
1261   { WithOrCatch body(this);
1262     Visit(stmt->statement());
1263   }
1264   scope_ = saved_scope;
1265
1266   // Pop context.
1267   LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1268   // Update local stack frame context field.
1269   StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1270 }
1271
1272
1273 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
1274   Comment cmnt(masm_, "[ DoWhileStatement");
1275   SetStatementPosition(stmt);
1276   Label body, book_keeping;
1277
1278   Iteration loop_statement(this, stmt);
1279   increment_loop_depth();
1280
1281   __ bind(&body);
1282   Visit(stmt->body());
1283
1284   // Record the position of the do while condition and make sure it is
1285   // possible to break on the condition.
1286   __ bind(loop_statement.continue_label());
1287   PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
1288   SetExpressionPosition(stmt->cond());
1289   VisitForControl(stmt->cond(),
1290                   &book_keeping,
1291                   loop_statement.break_label(),
1292                   &book_keeping);
1293
1294   // Check stack before looping.
1295   PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
1296   __ bind(&book_keeping);
1297   EmitBackEdgeBookkeeping(stmt, &body);
1298   __ jmp(&body);
1299
1300   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1301   __ bind(loop_statement.break_label());
1302   decrement_loop_depth();
1303 }
1304
1305
1306 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
1307   Comment cmnt(masm_, "[ WhileStatement");
1308   Label loop, body;
1309
1310   Iteration loop_statement(this, stmt);
1311   increment_loop_depth();
1312
1313   __ bind(&loop);
1314
1315   SetExpressionPosition(stmt->cond());
1316   VisitForControl(stmt->cond(),
1317                   &body,
1318                   loop_statement.break_label(),
1319                   &body);
1320
1321   PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1322   __ bind(&body);
1323   Visit(stmt->body());
1324
1325   __ bind(loop_statement.continue_label());
1326
1327   // Check stack before looping.
1328   EmitBackEdgeBookkeeping(stmt, &loop);
1329   __ jmp(&loop);
1330
1331   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1332   __ bind(loop_statement.break_label());
1333   decrement_loop_depth();
1334 }
1335
1336
1337 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
1338   Comment cmnt(masm_, "[ ForStatement");
1339   Label test, body;
1340
1341   Iteration loop_statement(this, stmt);
1342
1343   // Set statement position for a break slot before entering the for-body.
1344   SetStatementPosition(stmt);
1345
1346   if (stmt->init() != NULL) {
1347     SetStatementPosition(stmt->init());
1348     Visit(stmt->init());
1349   }
1350
1351   increment_loop_depth();
1352   // Emit the test at the bottom of the loop (even if empty).
1353   __ jmp(&test);
1354
1355   PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1356   __ bind(&body);
1357   Visit(stmt->body());
1358
1359   PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
1360   __ bind(loop_statement.continue_label());
1361   if (stmt->next() != NULL) {
1362     SetStatementPosition(stmt->next());
1363     Visit(stmt->next());
1364   }
1365
1366   // Emit the statement position here as this is where the for
1367   // statement code starts.
1368   SetStatementPosition(stmt);
1369
1370   // Check stack before looping.
1371   EmitBackEdgeBookkeeping(stmt, &body);
1372
1373   __ bind(&test);
1374   if (stmt->cond() != NULL) {
1375     SetExpressionPosition(stmt->cond());
1376     VisitForControl(stmt->cond(),
1377                     &body,
1378                     loop_statement.break_label(),
1379                     loop_statement.break_label());
1380   } else {
1381     __ jmp(&body);
1382   }
1383
1384   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1385   __ bind(loop_statement.break_label());
1386   decrement_loop_depth();
1387 }
1388
1389
1390 void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
1391   Comment cmnt(masm_, "[ ForOfStatement");
1392   SetStatementPosition(stmt);
1393
1394   Iteration loop_statement(this, stmt);
1395   increment_loop_depth();
1396
1397   // var iterator = iterable[Symbol.iterator]();
1398   VisitForEffect(stmt->assign_iterator());
1399
1400   // Loop entry.
1401   __ bind(loop_statement.continue_label());
1402
1403   // result = iterator.next()
1404   SetExpressionPosition(stmt->next_result());
1405   VisitForEffect(stmt->next_result());
1406
1407   // if (result.done) break;
1408   Label result_not_done;
1409   VisitForControl(stmt->result_done(), loop_statement.break_label(),
1410                   &result_not_done, &result_not_done);
1411   __ bind(&result_not_done);
1412
1413   // each = result.value
1414   VisitForEffect(stmt->assign_each());
1415
1416   // Generate code for the body of the loop.
1417   Visit(stmt->body());
1418
1419   // Check stack before looping.
1420   PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
1421   EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label());
1422   __ jmp(loop_statement.continue_label());
1423
1424   // Exit and decrement the loop depth.
1425   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1426   __ bind(loop_statement.break_label());
1427   decrement_loop_depth();
1428 }
1429
1430
1431 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
1432   Comment cmnt(masm_, "[ TryCatchStatement");
1433   SetStatementPosition(stmt);
1434   // The try block adds a handler to the exception handler chain before
1435   // entering, and removes it again when exiting normally.  If an exception
1436   // is thrown during execution of the try block, the handler is consumed
1437   // and control is passed to the catch block with the exception in the
1438   // result register.
1439
1440   Label try_entry, handler_entry, exit;
1441   __ jmp(&try_entry);
1442   __ bind(&handler_entry);
1443   handler_table()->set(stmt->index(), Smi::FromInt(handler_entry.pos()));
1444   // Exception handler code, the exception is in the result register.
1445   // Extend the context before executing the catch block.
1446   { Comment cmnt(masm_, "[ Extend catch context");
1447     __ Push(stmt->variable()->name());
1448     __ Push(result_register());
1449     PushFunctionArgumentForContextAllocation();
1450     __ CallRuntime(Runtime::kPushCatchContext, 3);
1451     StoreToFrameField(StandardFrameConstants::kContextOffset,
1452                       context_register());
1453   }
1454
1455   Scope* saved_scope = scope();
1456   scope_ = stmt->scope();
1457   DCHECK(scope_->declarations()->is_empty());
1458   { WithOrCatch catch_body(this);
1459     Visit(stmt->catch_block());
1460   }
1461   // Restore the context.
1462   LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1463   StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1464   scope_ = saved_scope;
1465   __ jmp(&exit);
1466
1467   // Try block code. Sets up the exception handler chain.
1468   __ bind(&try_entry);
1469   __ PushTryHandler(StackHandler::CATCH, stmt->index());
1470   { TryCatch try_body(this);
1471     Visit(stmt->try_block());
1472   }
1473   __ PopTryHandler();
1474   __ bind(&exit);
1475 }
1476
1477
1478 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
1479   Comment cmnt(masm_, "[ TryFinallyStatement");
1480   SetStatementPosition(stmt);
1481   // Try finally is compiled by setting up a try-handler on the stack while
1482   // executing the try body, and removing it again afterwards.
1483   //
1484   // The try-finally construct can enter the finally block in three ways:
1485   // 1. By exiting the try-block normally. This removes the try-handler and
1486   //    calls the finally block code before continuing.
1487   // 2. By exiting the try-block with a function-local control flow transfer
1488   //    (break/continue/return). The site of the, e.g., break removes the
1489   //    try handler and calls the finally block code before continuing
1490   //    its outward control transfer.
1491   // 3. By exiting the try-block with a thrown exception.
1492   //    This can happen in nested function calls. It traverses the try-handler
1493   //    chain and consumes the try-handler entry before jumping to the
1494   //    handler code. The handler code then calls the finally-block before
1495   //    rethrowing the exception.
1496   //
1497   // The finally block must assume a return address on top of the stack
1498   // (or in the link register on ARM chips) and a value (return value or
1499   // exception) in the result register (rax/eax/r0), both of which must
1500   // be preserved. The return address isn't GC-safe, so it should be
1501   // cooked before GC.
1502   Label try_entry, handler_entry, finally_entry;
1503
1504   // Jump to try-handler setup and try-block code.
1505   __ jmp(&try_entry);
1506   __ bind(&handler_entry);
1507   handler_table()->set(stmt->index(), Smi::FromInt(handler_entry.pos()));
1508   // Exception handler code.  This code is only executed when an exception
1509   // is thrown.  The exception is in the result register, and must be
1510   // preserved by the finally block.  Call the finally block and then
1511   // rethrow the exception if it returns.
1512   __ Call(&finally_entry);
1513   __ Push(result_register());
1514   __ CallRuntime(Runtime::kReThrow, 1);
1515
1516   // Finally block implementation.
1517   __ bind(&finally_entry);
1518   EnterFinallyBlock();
1519   { Finally finally_body(this);
1520     Visit(stmt->finally_block());
1521   }
1522   ExitFinallyBlock();  // Return to the calling code.
1523
1524   // Set up try handler.
1525   __ bind(&try_entry);
1526   __ PushTryHandler(StackHandler::FINALLY, stmt->index());
1527   { TryFinally try_body(this, &finally_entry);
1528     Visit(stmt->try_block());
1529   }
1530   __ PopTryHandler();
1531   // Execute the finally block on the way out.  Clobber the unpredictable
1532   // value in the result register with one that's safe for GC because the
1533   // finally block will unconditionally preserve the result register on the
1534   // stack.
1535   ClearAccumulator();
1536   __ Call(&finally_entry);
1537 }
1538
1539
1540 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
1541   Comment cmnt(masm_, "[ DebuggerStatement");
1542   SetStatementPosition(stmt);
1543
1544   __ DebugBreak();
1545   // Ignore the return value.
1546
1547   PrepareForBailoutForId(stmt->DebugBreakId(), NO_REGISTERS);
1548 }
1549
1550
1551 void FullCodeGenerator::VisitCaseClause(CaseClause* clause) {
1552   UNREACHABLE();
1553 }
1554
1555
1556 void FullCodeGenerator::VisitConditional(Conditional* expr) {
1557   Comment cmnt(masm_, "[ Conditional");
1558   Label true_case, false_case, done;
1559   VisitForControl(expr->condition(), &true_case, &false_case, &true_case);
1560
1561   PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS);
1562   __ bind(&true_case);
1563   SetExpressionPosition(expr->then_expression());
1564   if (context()->IsTest()) {
1565     const TestContext* for_test = TestContext::cast(context());
1566     VisitForControl(expr->then_expression(),
1567                     for_test->true_label(),
1568                     for_test->false_label(),
1569                     NULL);
1570   } else {
1571     VisitInDuplicateContext(expr->then_expression());
1572     __ jmp(&done);
1573   }
1574
1575   PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS);
1576   __ bind(&false_case);
1577   SetExpressionPosition(expr->else_expression());
1578   VisitInDuplicateContext(expr->else_expression());
1579   // If control flow falls through Visit, merge it with true case here.
1580   if (!context()->IsTest()) {
1581     __ bind(&done);
1582   }
1583 }
1584
1585
1586 void FullCodeGenerator::VisitLiteral(Literal* expr) {
1587   Comment cmnt(masm_, "[ Literal");
1588   context()->Plug(expr->value());
1589 }
1590
1591
1592 void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
1593   Comment cmnt(masm_, "[ FunctionLiteral");
1594
1595   // Build the function boilerplate and instantiate it.
1596   Handle<SharedFunctionInfo> function_info =
1597       Compiler::BuildFunctionInfo(expr, script(), info_);
1598   if (function_info.is_null()) {
1599     SetStackOverflow();
1600     return;
1601   }
1602   EmitNewClosure(function_info, expr->pretenure());
1603 }
1604
1605
1606 void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) {
1607   Comment cmnt(masm_, "[ ClassLiteral");
1608
1609   {
1610     EnterBlockScopeIfNeeded block_scope_state(
1611         this, lit->scope(), lit->EntryId(), lit->DeclsId(), lit->ExitId());
1612
1613     if (lit->raw_name() != NULL) {
1614       __ Push(lit->name());
1615     } else {
1616       __ Push(isolate()->factory()->undefined_value());
1617     }
1618
1619     if (lit->extends() != NULL) {
1620       VisitForStackValue(lit->extends());
1621     } else {
1622       __ Push(isolate()->factory()->the_hole_value());
1623     }
1624
1625     VisitForStackValue(lit->constructor());
1626
1627     __ Push(script());
1628     __ Push(Smi::FromInt(lit->start_position()));
1629     __ Push(Smi::FromInt(lit->end_position()));
1630
1631     __ CallRuntime(Runtime::kDefineClass, 6);
1632     EmitClassDefineProperties(lit);
1633
1634     if (lit->scope() != NULL) {
1635       DCHECK_NOT_NULL(lit->class_variable_proxy());
1636       EmitVariableAssignment(lit->class_variable_proxy()->var(),
1637                              Token::INIT_CONST);
1638     }
1639   }
1640
1641   context()->Plug(result_register());
1642 }
1643
1644
1645 void FullCodeGenerator::VisitNativeFunctionLiteral(
1646     NativeFunctionLiteral* expr) {
1647   Comment cmnt(masm_, "[ NativeFunctionLiteral");
1648
1649   // Compute the function template for the native function.
1650   Handle<String> name = expr->name();
1651   v8::Handle<v8::FunctionTemplate> fun_template =
1652       expr->extension()->GetNativeFunctionTemplate(
1653           reinterpret_cast<v8::Isolate*>(isolate()), v8::Utils::ToLocal(name));
1654   DCHECK(!fun_template.IsEmpty());
1655
1656   // Instantiate the function and create a shared function info from it.
1657   Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction());
1658   const int literals = fun->NumberOfLiterals();
1659   Handle<Code> code = Handle<Code>(fun->shared()->code());
1660   Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
1661   Handle<SharedFunctionInfo> shared =
1662       isolate()->factory()->NewSharedFunctionInfo(
1663           name, literals, FunctionKind::kNormalFunction, code,
1664           Handle<ScopeInfo>(fun->shared()->scope_info()),
1665           Handle<TypeFeedbackVector>(fun->shared()->feedback_vector()));
1666   shared->set_construct_stub(*construct_stub);
1667
1668   // Copy the function data to the shared function info.
1669   shared->set_function_data(fun->shared()->function_data());
1670   int parameters = fun->shared()->internal_formal_parameter_count();
1671   shared->set_internal_formal_parameter_count(parameters);
1672
1673   EmitNewClosure(shared, false);
1674 }
1675
1676
1677 void FullCodeGenerator::VisitThrow(Throw* expr) {
1678   Comment cmnt(masm_, "[ Throw");
1679   VisitForStackValue(expr->exception());
1680   __ CallRuntime(Runtime::kThrow, 1);
1681   // Never returns here.
1682 }
1683
1684
1685 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryCatch::Exit(
1686     int* stack_depth,
1687     int* context_length) {
1688   // The macros used here must preserve the result register.
1689   __ Drop(*stack_depth);
1690   __ PopTryHandler();
1691   *stack_depth = 0;
1692   return previous_;
1693 }
1694
1695
1696 bool FullCodeGenerator::TryLiteralCompare(CompareOperation* expr) {
1697   Expression* sub_expr;
1698   Handle<String> check;
1699   if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) {
1700     EmitLiteralCompareTypeof(expr, sub_expr, check);
1701     return true;
1702   }
1703
1704   if (expr->IsLiteralCompareUndefined(&sub_expr, isolate())) {
1705     EmitLiteralCompareNil(expr, sub_expr, kUndefinedValue);
1706     return true;
1707   }
1708
1709   if (expr->IsLiteralCompareNull(&sub_expr)) {
1710     EmitLiteralCompareNil(expr, sub_expr, kNullValue);
1711     return true;
1712   }
1713
1714   return false;
1715 }
1716
1717
1718 void BackEdgeTable::Patch(Isolate* isolate, Code* unoptimized) {
1719   DisallowHeapAllocation no_gc;
1720   Code* patch = isolate->builtins()->builtin(Builtins::kOnStackReplacement);
1721
1722   // Increment loop nesting level by one and iterate over the back edge table
1723   // to find the matching loops to patch the interrupt
1724   // call to an unconditional call to the replacement code.
1725   int loop_nesting_level = unoptimized->allow_osr_at_loop_nesting_level() + 1;
1726   if (loop_nesting_level > Code::kMaxLoopNestingMarker) return;
1727
1728   BackEdgeTable back_edges(unoptimized, &no_gc);
1729   for (uint32_t i = 0; i < back_edges.length(); i++) {
1730     if (static_cast<int>(back_edges.loop_depth(i)) == loop_nesting_level) {
1731       DCHECK_EQ(INTERRUPT, GetBackEdgeState(isolate,
1732                                             unoptimized,
1733                                             back_edges.pc(i)));
1734       PatchAt(unoptimized, back_edges.pc(i), ON_STACK_REPLACEMENT, patch);
1735     }
1736   }
1737
1738   unoptimized->set_allow_osr_at_loop_nesting_level(loop_nesting_level);
1739   DCHECK(Verify(isolate, unoptimized));
1740 }
1741
1742
1743 void BackEdgeTable::Revert(Isolate* isolate, Code* unoptimized) {
1744   DisallowHeapAllocation no_gc;
1745   Code* patch = isolate->builtins()->builtin(Builtins::kInterruptCheck);
1746
1747   // Iterate over the back edge table and revert the patched interrupt calls.
1748   int loop_nesting_level = unoptimized->allow_osr_at_loop_nesting_level();
1749
1750   BackEdgeTable back_edges(unoptimized, &no_gc);
1751   for (uint32_t i = 0; i < back_edges.length(); i++) {
1752     if (static_cast<int>(back_edges.loop_depth(i)) <= loop_nesting_level) {
1753       DCHECK_NE(INTERRUPT, GetBackEdgeState(isolate,
1754                                             unoptimized,
1755                                             back_edges.pc(i)));
1756       PatchAt(unoptimized, back_edges.pc(i), INTERRUPT, patch);
1757     }
1758   }
1759
1760   unoptimized->set_allow_osr_at_loop_nesting_level(0);
1761   // Assert that none of the back edges are patched anymore.
1762   DCHECK(Verify(isolate, unoptimized));
1763 }
1764
1765
1766 void BackEdgeTable::AddStackCheck(Handle<Code> code, uint32_t pc_offset) {
1767   DisallowHeapAllocation no_gc;
1768   Isolate* isolate = code->GetIsolate();
1769   Address pc = code->instruction_start() + pc_offset;
1770   Code* patch = isolate->builtins()->builtin(Builtins::kOsrAfterStackCheck);
1771   PatchAt(*code, pc, OSR_AFTER_STACK_CHECK, patch);
1772 }
1773
1774
1775 void BackEdgeTable::RemoveStackCheck(Handle<Code> code, uint32_t pc_offset) {
1776   DisallowHeapAllocation no_gc;
1777   Isolate* isolate = code->GetIsolate();
1778   Address pc = code->instruction_start() + pc_offset;
1779
1780   if (OSR_AFTER_STACK_CHECK == GetBackEdgeState(isolate, *code, pc)) {
1781     Code* patch = isolate->builtins()->builtin(Builtins::kOnStackReplacement);
1782     PatchAt(*code, pc, ON_STACK_REPLACEMENT, patch);
1783   }
1784 }
1785
1786
1787 #ifdef DEBUG
1788 bool BackEdgeTable::Verify(Isolate* isolate, Code* unoptimized) {
1789   DisallowHeapAllocation no_gc;
1790   int loop_nesting_level = unoptimized->allow_osr_at_loop_nesting_level();
1791   BackEdgeTable back_edges(unoptimized, &no_gc);
1792   for (uint32_t i = 0; i < back_edges.length(); i++) {
1793     uint32_t loop_depth = back_edges.loop_depth(i);
1794     CHECK_LE(static_cast<int>(loop_depth), Code::kMaxLoopNestingMarker);
1795     // Assert that all back edges for shallower loops (and only those)
1796     // have already been patched.
1797     CHECK_EQ((static_cast<int>(loop_depth) <= loop_nesting_level),
1798              GetBackEdgeState(isolate,
1799                               unoptimized,
1800                               back_edges.pc(i)) != INTERRUPT);
1801   }
1802   return true;
1803 }
1804 #endif  // DEBUG
1805
1806
1807 FullCodeGenerator::EnterBlockScopeIfNeeded::EnterBlockScopeIfNeeded(
1808     FullCodeGenerator* codegen, Scope* scope, BailoutId entry_id,
1809     BailoutId declarations_id, BailoutId exit_id)
1810     : codegen_(codegen), scope_(scope), exit_id_(exit_id) {
1811   saved_scope_ = codegen_->scope();
1812
1813   if (scope == NULL) {
1814     codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS);
1815   } else {
1816     codegen_->scope_ = scope;
1817     {
1818       Comment cmnt(masm(), "[ Extend block context");
1819       __ Push(scope->GetScopeInfo(codegen->isolate()));
1820       codegen_->PushFunctionArgumentForContextAllocation();
1821       __ CallRuntime(Runtime::kPushBlockContext, 2);
1822
1823       // Replace the context stored in the frame.
1824       codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset,
1825                                   codegen_->context_register());
1826       codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS);
1827     }
1828     {
1829       Comment cmnt(masm(), "[ Declarations");
1830       codegen_->VisitDeclarations(scope->declarations());
1831       codegen_->PrepareForBailoutForId(declarations_id, NO_REGISTERS);
1832     }
1833   }
1834 }
1835
1836
1837 FullCodeGenerator::EnterBlockScopeIfNeeded::~EnterBlockScopeIfNeeded() {
1838   if (scope_ != NULL) {
1839     codegen_->LoadContextField(codegen_->context_register(),
1840                                Context::PREVIOUS_INDEX);
1841     // Update local stack frame context field.
1842     codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset,
1843                                 codegen_->context_register());
1844   }
1845   codegen_->PrepareForBailoutForId(exit_id_, NO_REGISTERS);
1846   codegen_->scope_ = saved_scope_;
1847 }
1848
1849
1850 #undef __
1851
1852
1853 } }  // namespace v8::internal