54 void BreakableStatementChecker::VisitVariableDeclaration(
58 void BreakableStatementChecker::VisitFunctionDeclaration(
59 FunctionDeclaration* decl) {
62 void BreakableStatementChecker::VisitModuleDeclaration(
63 ModuleDeclaration* decl) {
66 void BreakableStatementChecker::VisitImportDeclaration(
67 ImportDeclaration* decl) {
70 void BreakableStatementChecker::VisitExportDeclaration(
71 ExportDeclaration* decl) {
75 void BreakableStatementChecker::VisitModuleLiteral(ModuleLiteral* module) {
78 void BreakableStatementChecker::VisitModuleVariable(ModuleVariable* module) {
81 void BreakableStatementChecker::VisitModulePath(ModulePath* module) {
84 void BreakableStatementChecker::VisitModuleUrl(ModuleUrl* module) {
88 void BreakableStatementChecker::VisitBlock(
Block* stmt) {
92 void BreakableStatementChecker::VisitExpressionStatement(
93 ExpressionStatement* stmt) {
95 Visit(stmt->expression());
99 void BreakableStatementChecker::VisitEmptyStatement(EmptyStatement* stmt) {
103 void BreakableStatementChecker::VisitIfStatement(IfStatement* stmt) {
105 Visit(stmt->condition());
109 void BreakableStatementChecker::VisitContinueStatement(
110 ContinueStatement* stmt) {
114 void BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) {
118 void BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) {
120 Visit(stmt->expression());
124 void BreakableStatementChecker::VisitWithStatement(WithStatement* stmt) {
125 Visit(stmt->expression());
129 void BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) {
135 void BreakableStatementChecker::VisitDoWhileStatement(DoWhileStatement* stmt) {
137 is_breakable_ =
true;
141 void BreakableStatementChecker::VisitWhileStatement(WhileStatement* stmt) {
147 void BreakableStatementChecker::VisitForStatement(ForStatement* stmt) {
149 if (stmt->cond() !=
NULL) {
155 void BreakableStatementChecker::VisitForInStatement(ForInStatement* stmt) {
157 Visit(stmt->enumerable());
161 void BreakableStatementChecker::VisitTryCatchStatement(
162 TryCatchStatement* stmt) {
164 is_breakable_ =
true;
168 void BreakableStatementChecker::VisitTryFinallyStatement(
169 TryFinallyStatement* stmt) {
171 is_breakable_ =
true;
175 void BreakableStatementChecker::VisitDebuggerStatement(
176 DebuggerStatement* stmt) {
178 is_breakable_ =
true;
182 void BreakableStatementChecker::VisitFunctionLiteral(FunctionLiteral* expr) {
186 void BreakableStatementChecker::VisitSharedFunctionInfoLiteral(
187 SharedFunctionInfoLiteral* expr) {
191 void BreakableStatementChecker::VisitConditional(Conditional* expr) {
195 void BreakableStatementChecker::VisitVariableProxy(VariableProxy* expr) {
199 void BreakableStatementChecker::VisitLiteral(Literal* expr) {
203 void BreakableStatementChecker::VisitRegExpLiteral(RegExpLiteral* expr) {
207 void BreakableStatementChecker::VisitObjectLiteral(ObjectLiteral* expr) {
211 void BreakableStatementChecker::VisitArrayLiteral(ArrayLiteral* expr) {
215 void BreakableStatementChecker::VisitAssignment(Assignment* expr) {
218 VariableProxy* proxy = expr->target()->AsVariableProxy();
219 Property* prop = expr->target()->AsProperty();
220 if (prop !=
NULL || (proxy !=
NULL && proxy->var()->IsUnallocated())) {
221 is_breakable_ =
true;
226 Visit(expr->value());
230 void BreakableStatementChecker::VisitThrow(Throw* expr) {
232 Visit(expr->exception());
236 void BreakableStatementChecker::VisitProperty(Property* expr) {
238 is_breakable_ =
true;
242 void BreakableStatementChecker::VisitCall(Call* expr) {
244 is_breakable_ =
true;
248 void BreakableStatementChecker::VisitCallNew(CallNew* expr) {
250 is_breakable_ =
true;
254 void BreakableStatementChecker::VisitCallRuntime(CallRuntime* expr) {
258 void BreakableStatementChecker::VisitUnaryOperation(UnaryOperation* expr) {
259 Visit(expr->expression());
263 void BreakableStatementChecker::VisitCountOperation(CountOperation* expr) {
264 Visit(expr->expression());
268 void BreakableStatementChecker::VisitBinaryOperation(BinaryOperation* expr) {
272 Visit(expr->right());
277 void BreakableStatementChecker::VisitCompareOperation(CompareOperation* expr) {
279 Visit(expr->right());
283 void BreakableStatementChecker::VisitThisFunction(ThisFunction* expr) {
287 #define __ ACCESS_MASM(masm())
290 Isolate* isolate = info->isolate();
292 if (!script->IsUndefined() && !script->source()->IsUndefined()) {
294 isolate->
counters()->total_full_codegen_source_size()->Increment(len);
296 if (FLAG_trace_codegen) {
297 PrintF(
"Full Compiler - ");
300 const int kInitialBufferSize = 4 *
KB;
302 #ifdef ENABLE_GDB_JIT_INTERFACE
308 if (cgen.HasStackOverflow()) {
312 unsigned table_offset = cgen.EmitStackCheckTable();
316 code->set_optimizable(info->IsOptimizable() &&
318 info->function()->scope()->AllowsLazyRecompilation());
319 cgen.PopulateDeoptimizationData(code);
320 cgen.PopulateTypeFeedbackInfo(code);
321 cgen.PopulateTypeFeedbackCells(code);
322 code->set_has_deoptimization_support(info->HasDeoptimizationSupport());
323 code->set_handler_table(*cgen.handler_table());
324 #ifdef ENABLE_DEBUGGER_SUPPORT
325 code->set_has_debug_break_slots(
326 info->isolate()->debugger()->IsDebuggerActive());
327 code->set_compiled_optimizable(info->IsOptimizable());
328 #endif // ENABLE_DEBUGGER_SUPPORT
329 code->set_allow_osr_at_loop_nesting_level(0);
330 code->set_profiler_ticks(0);
331 code->set_stack_check_table_offset(table_offset);
334 #ifdef ENABLE_GDB_JIT_INTERFACE
335 if (FLAG_gdbjit && !code.
is_null()) {
336 GDBJITLineInfo* lineinfo =
339 GDBJIT(RegisterDetailedLineInfo(*code, lineinfo));
346 unsigned FullCodeGenerator::EmitStackCheckTable() {
352 unsigned length = stack_checks_.length();
354 for (
unsigned i = 0; i < length; ++i) {
355 __ dd(stack_checks_[i].
id);
356 __ dd(stack_checks_[i].pc_and_state);
362 void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) {
364 ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty());
365 if (!info_->HasDeoptimizationSupport())
return;
366 int length = bailout_entries_.length();
367 Handle<DeoptimizationOutputData> data = isolate()->factory()->
368 NewDeoptimizationOutputData(length,
TENURED);
369 for (
int i = 0; i < length; i++) {
370 data->SetAstId(i,
Smi::FromInt(bailout_entries_[i].
id));
371 data->SetPcAndState(i,
Smi::FromInt(bailout_entries_[i].pc_and_state));
373 code->set_deoptimization_data(*data);
377 void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) {
378 Handle<TypeFeedbackInfo> info = isolate()->factory()->NewTypeFeedbackInfo();
379 info->set_ic_total_count(ic_total_count_);
380 ASSERT(!isolate()->heap()->InNewSpace(*info));
381 code->set_type_feedback_info(*info);
385 void FullCodeGenerator::PopulateTypeFeedbackCells(Handle<Code> code) {
386 if (type_feedback_cells_.is_empty())
return;
387 int length = type_feedback_cells_.length();
390 isolate()->factory()->NewFixedArray(array_size,
TENURED));
391 for (
int i = 0; i < length; i++) {
392 cache->SetAstId(i,
Smi::FromInt(type_feedback_cells_[i].ast_id));
393 cache->SetCell(i, *type_feedback_cells_[i].cell);
401 void FullCodeGenerator::PrepareForBailout(Expression* node, State state) {
402 PrepareForBailoutForId(node->id(), state);
406 void FullCodeGenerator::RecordJSReturnSite(Call* call) {
413 PrepareForBailoutForId(call->ReturnId(),
TOS_REG);
417 ASSERT(!call->return_is_recorded_);
418 call->return_is_recorded_ =
true;
423 void FullCodeGenerator::PrepareForBailoutForId(
unsigned id, State state) {
426 if (!info_->HasDeoptimizationSupport())
return;
427 unsigned pc_and_state =
430 BailoutEntry entry = { id, pc_and_state };
434 for (
int i = 0; i < bailout_entries_.length(); i++) {
435 if (bailout_entries_.
at(i).id == entry.id) {
437 PrintF(
"%s", printer.PrintProgram(info_->function()));
443 bailout_entries_.
Add(entry,
zone());
447 void FullCodeGenerator::RecordTypeFeedbackCell(
448 unsigned id, Handle<JSGlobalPropertyCell> cell) {
449 TypeFeedbackCellEntry entry = { id, cell };
450 type_feedback_cells_.
Add(entry,
zone());
454 void FullCodeGenerator::RecordStackCheck(
unsigned ast_id) {
458 BailoutEntry entry = { ast_id,
static_cast<unsigned>(masm_->
pc_offset()) };
459 stack_checks_.
Add(entry,
zone());
463 bool FullCodeGenerator::ShouldInlineSmiCase(
Token::Value op) {
466 if (op ==
Token::DIV ||op == Token::MOD)
return false;
467 if (FLAG_always_inline_smi_code)
return true;
468 return loop_depth_ > 0;
472 void FullCodeGenerator::EffectContext::Plug(Register reg)
const {
476 void FullCodeGenerator::AccumulatorValueContext::Plug(Register reg)
const {
477 __ Move(result_register(), reg);
481 void FullCodeGenerator::StackValueContext::Plug(Register reg)
const {
486 void FullCodeGenerator::TestContext::Plug(Register reg)
const {
488 __ Move(result_register(), reg);
489 codegen()->PrepareForBailoutBeforeSplit(condition(),
false,
NULL,
NULL);
490 codegen()->DoTest(
this);
494 void FullCodeGenerator::EffectContext::PlugTOS()
const {
499 void FullCodeGenerator::AccumulatorValueContext::PlugTOS()
const {
500 __ pop(result_register());
504 void FullCodeGenerator::StackValueContext::PlugTOS()
const {
508 void FullCodeGenerator::TestContext::PlugTOS()
const {
510 __ pop(result_register());
511 codegen()->PrepareForBailoutBeforeSplit(condition(),
false,
NULL,
NULL);
512 codegen()->DoTest(
this);
516 void FullCodeGenerator::EffectContext::PrepareTest(
517 Label* materialize_true,
518 Label* materialize_false,
521 Label** fall_through)
const {
524 *if_true = *if_false = *fall_through = materialize_true;
528 void FullCodeGenerator::AccumulatorValueContext::PrepareTest(
529 Label* materialize_true,
530 Label* materialize_false,
533 Label** fall_through)
const {
534 *if_true = *fall_through = materialize_true;
535 *if_false = materialize_false;
539 void FullCodeGenerator::StackValueContext::PrepareTest(
540 Label* materialize_true,
541 Label* materialize_false,
544 Label** fall_through)
const {
545 *if_true = *fall_through = materialize_true;
546 *if_false = materialize_false;
550 void FullCodeGenerator::TestContext::PrepareTest(
551 Label* materialize_true,
552 Label* materialize_false,
555 Label** fall_through)
const {
556 *if_true = true_label_;
557 *if_false = false_label_;
558 *fall_through = fall_through_;
562 void FullCodeGenerator::DoTest(
const TestContext* context) {
563 DoTest(context->condition(),
564 context->true_label(),
565 context->false_label(),
566 context->fall_through());
570 void FullCodeGenerator::VisitDeclarations(
571 ZoneList<Declaration*>* declarations) {
572 ZoneList<Handle<Object> >* saved_globals = globals_;
573 ZoneList<Handle<Object> > inner_globals(10,
zone());
574 globals_ = &inner_globals;
576 AstVisitor::VisitDeclarations(declarations);
577 if (!globals_->is_empty()) {
580 Handle<FixedArray> array =
581 isolate()->factory()->NewFixedArray(globals_->length(),
TENURED);
582 for (
int i = 0; i < globals_->length(); ++i)
583 array->set(i, *globals_->
at(i));
584 DeclareGlobals(array);
587 globals_ = saved_globals;
591 void FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) {
592 Handle<JSModule> instance = module->interface()->Instance();
593 ASSERT(!instance.is_null());
596 Block* block = module->body();
597 Scope* saved_scope = scope();
598 scope_ = block->scope();
602 Comment cmnt(masm_,
"[ ModuleLiteral");
603 SetStatementPosition(block);
605 if (scope_info->HasContext()) {
609 __ CallRuntime(Runtime::kPushModuleContext, 2);
615 Comment cmnt(masm_,
"[ Declarations");
619 scope_ = saved_scope;
620 if (scope_info->HasContext()) {
631 for (Interface::Iterator it = module->interface()->iterator();
632 !it.done(); it.Advance()) {
633 if (it.interface()->IsModule()) {
634 Handle<Object> value = it.interface()->Instance();
640 Handle<Object> value(isolate()->heap()->undefined_value());
644 USE(instance->PreventExtensions());
648 void FullCodeGenerator::VisitModuleVariable(ModuleVariable* module) {
654 void FullCodeGenerator::VisitModulePath(ModulePath* module) {
660 void FullCodeGenerator::VisitModuleUrl(ModuleUrl* decl) {
665 int FullCodeGenerator::DeclareGlobalsFlags() {
673 void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
678 void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
683 void FullCodeGenerator::SetStatementPosition(Statement* stmt) {
684 #ifdef ENABLE_DEBUGGER_SUPPORT
685 if (!isolate()->debugger()->IsDebuggerActive()) {
690 BreakableStatementChecker checker;
696 masm_, stmt->statement_pos(), !checker.is_breakable());
699 if (position_recorded) {
700 Debug::GenerateSlot(masm_);
709 void FullCodeGenerator::SetExpressionPosition(Expression* expr,
int pos) {
710 #ifdef ENABLE_DEBUGGER_SUPPORT
711 if (!isolate()->debugger()->IsDebuggerActive()) {
716 BreakableStatementChecker checker;
726 masm_, pos, !checker.is_breakable());
729 if (position_recorded) {
730 Debug::GenerateSlot(masm_);
739 void FullCodeGenerator::SetStatementPosition(
int pos) {
744 void FullCodeGenerator::SetSourcePosition(
int pos) {
745 if (pos != RelocInfo::kNoPosition) {
753 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \
754 &FullCodeGenerator::Emit##Name,
756 const FullCodeGenerator::InlineFunctionGenerator
757 FullCodeGenerator::kInlineFunctionGenerators[] = {
761 #undef INLINE_FUNCTION_GENERATOR_ADDRESS
764 FullCodeGenerator::InlineFunctionGenerator
768 ASSERT(lookup_index >= 0);
769 ASSERT(static_cast<size_t>(lookup_index) <
771 return kInlineFunctionGenerators[lookup_index];
775 void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* expr) {
776 const Runtime::Function*
function = expr->function();
779 InlineFunctionGenerator generator =
780 FindInlineFunctionGenerator(function->function_id);
781 ((*this).*(generator))(expr);
785 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
786 switch (expr->op()) {
788 return VisitComma(expr);
791 return VisitLogicalExpression(expr);
793 return VisitArithmeticExpression(expr);
798 void FullCodeGenerator::VisitInDuplicateContext(Expression* expr) {
799 if (context()->IsEffect()) {
800 VisitForEffect(expr);
801 }
else if (context()->IsAccumulatorValue()) {
802 VisitForAccumulatorValue(expr);
803 }
else if (context()->IsStackValue()) {
804 VisitForStackValue(expr);
805 }
else if (context()->IsTest()) {
807 VisitForControl(expr, test->true_label(), test->false_label(),
808 test->fall_through());
813 void FullCodeGenerator::VisitComma(BinaryOperation* expr) {
814 Comment cmnt(masm_,
"[ Comma");
815 VisitForEffect(expr->left());
816 VisitInDuplicateContext(expr->right());
820 void FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) {
821 bool is_logical_and = expr->op() ==
Token::AND;
822 Comment cmnt(masm_, is_logical_and ?
"[ Logical AND" :
"[ Logical OR");
823 Expression* left = expr->left();
824 Expression* right = expr->right();
825 int right_id = expr->RightId();
828 if (context()->IsTest()) {
831 if (is_logical_and) {
832 VisitForControl(left, &eval_right, test->false_label(), &eval_right);
834 VisitForControl(left, test->true_label(), &eval_right, &eval_right);
837 __ bind(&eval_right);
839 }
else if (context()->IsAccumulatorValue()) {
840 VisitForAccumulatorValue(left);
843 __ push(result_register());
844 Label discard, restore;
845 if (is_logical_and) {
846 DoTest(left, &discard, &restore, &restore);
848 DoTest(left, &restore, &discard, &restore);
851 __ pop(result_register());
857 }
else if (context()->IsStackValue()) {
858 VisitForAccumulatorValue(left);
861 __ push(result_register());
863 if (is_logical_and) {
864 DoTest(left, &discard, &done, &discard);
866 DoTest(left, &done, &discard, &discard);
873 ASSERT(context()->IsEffect());
875 if (is_logical_and) {
876 VisitForControl(left, &eval_right, &done, &eval_right);
878 VisitForControl(left, &done, &eval_right, &eval_right);
881 __ bind(&eval_right);
884 VisitInDuplicateContext(right);
889 void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
891 Comment cmnt(masm_,
"[ ArithmeticExpression");
892 Expression* left = expr->left();
893 Expression* right = expr->right();
895 left->ResultOverwriteAllowed()
899 VisitForStackValue(left);
900 VisitForAccumulatorValue(right);
902 SetSourcePosition(expr->position());
903 if (ShouldInlineSmiCase(op)) {
904 EmitInlineSmiBinaryOp(expr, op, mode, left, right);
906 EmitBinaryOp(expr, op, mode);
911 void FullCodeGenerator::VisitBlock(
Block* stmt) {
912 Comment cmnt(masm_,
"[ Block");
913 NestedBlock nested_block(
this, stmt);
914 SetStatementPosition(stmt);
916 Scope* saved_scope = scope();
918 if (stmt->scope() !=
NULL) {
919 { Comment cmnt(masm_,
"[ Extend block context");
920 scope_ = stmt->scope();
924 PushFunctionArgumentForContextAllocation();
926 FastNewBlockContextStub stub(heap_slots);
929 __ CallRuntime(Runtime::kPushBlockContext, 2);
936 { Comment cmnt(masm_,
"[ Declarations");
941 VisitStatements(stmt->statements());
942 scope_ = saved_scope;
943 __ bind(nested_block.break_label());
947 if (stmt->scope() !=
NULL) {
956 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
957 Comment cmnt(masm_,
"[ ExpressionStatement");
958 SetStatementPosition(stmt);
959 VisitForEffect(stmt->expression());
963 void FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
964 Comment cmnt(masm_,
"[ EmptyStatement");
965 SetStatementPosition(stmt);
969 void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) {
970 Comment cmnt(masm_,
"[ IfStatement");
971 SetStatementPosition(stmt);
972 Label then_part, else_part, done;
974 if (stmt->HasElseStatement()) {
975 VisitForControl(stmt->condition(), &then_part, &else_part, &then_part);
978 Visit(stmt->then_statement());
983 Visit(stmt->else_statement());
985 VisitForControl(stmt->condition(), &then_part, &done, &then_part);
988 Visit(stmt->then_statement());
997 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
998 Comment cmnt(masm_,
"[ ContinueStatement");
999 SetStatementPosition(stmt);
1001 int stack_depth = 0;
1002 int context_length = 0;
1008 while (!current->IsContinueTarget(stmt->target())) {
1009 current = current->Exit(&stack_depth, &context_length);
1011 __ Drop(stack_depth);
1012 if (context_length > 0) {
1013 while (context_length > 0) {
1018 context_register());
1021 __ jmp(current->AsIteration()->continue_label());
1025 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
1026 Comment cmnt(masm_,
"[ BreakStatement");
1027 SetStatementPosition(stmt);
1029 int stack_depth = 0;
1030 int context_length = 0;
1036 while (!current->IsBreakTarget(stmt->target())) {
1037 current = current->Exit(&stack_depth, &context_length);
1039 __ Drop(stack_depth);
1040 if (context_length > 0) {
1041 while (context_length > 0) {
1046 context_register());
1049 __ jmp(current->AsBreakable()->break_label());
1053 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
1054 Comment cmnt(masm_,
"[ ReturnStatement");
1055 SetStatementPosition(stmt);
1056 Expression* expr = stmt->expression();
1057 VisitForAccumulatorValue(expr);
1061 int stack_depth = 0;
1062 int context_length = 0;
1063 while (current !=
NULL) {
1064 current = current->Exit(&stack_depth, &context_length);
1066 __ Drop(stack_depth);
1068 EmitReturnSequence();
1072 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) {
1073 Comment cmnt(masm_,
"[ WithStatement");
1074 SetStatementPosition(stmt);
1076 VisitForStackValue(stmt->expression());
1077 PushFunctionArgumentForContextAllocation();
1078 __ CallRuntime(Runtime::kPushWithContext, 2);
1081 { WithOrCatch body(
this);
1082 Visit(stmt->statement());
1092 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
1093 Comment cmnt(masm_,
"[ DoWhileStatement");
1094 SetStatementPosition(stmt);
1095 Label body, stack_check;
1097 Iteration loop_statement(
this, stmt);
1098 increment_loop_depth();
1101 Visit(stmt->body());
1105 __ bind(loop_statement.continue_label());
1106 PrepareForBailoutForId(stmt->ContinueId(),
NO_REGISTERS);
1107 SetExpressionPosition(stmt->cond(), stmt->condition_position());
1108 VisitForControl(stmt->cond(),
1110 loop_statement.break_label(),
1114 PrepareForBailoutForId(stmt->BackEdgeId(),
NO_REGISTERS);
1115 __ bind(&stack_check);
1116 EmitStackCheck(stmt, &body);
1120 __ bind(loop_statement.break_label());
1121 decrement_loop_depth();
1125 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
1126 Comment cmnt(masm_,
"[ WhileStatement");
1129 Iteration loop_statement(
this, stmt);
1130 increment_loop_depth();
1137 Visit(stmt->body());
1141 __ bind(loop_statement.continue_label());
1142 SetStatementPosition(stmt);
1145 EmitStackCheck(stmt, &body);
1148 VisitForControl(stmt->cond(),
1150 loop_statement.break_label(),
1151 loop_statement.break_label());
1154 __ bind(loop_statement.break_label());
1155 decrement_loop_depth();
1159 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
1160 Comment cmnt(masm_,
"[ ForStatement");
1163 Iteration loop_statement(
this, stmt);
1166 SetStatementPosition(stmt);
1168 if (stmt->init() !=
NULL) {
1169 Visit(stmt->init());
1172 increment_loop_depth();
1178 Visit(stmt->body());
1180 PrepareForBailoutForId(stmt->ContinueId(),
NO_REGISTERS);
1181 __ bind(loop_statement.continue_label());
1182 if (stmt->next() !=
NULL) {
1183 Visit(stmt->next());
1188 SetStatementPosition(stmt);
1191 EmitStackCheck(stmt, &body);
1194 if (stmt->cond() !=
NULL) {
1195 VisitForControl(stmt->cond(),
1197 loop_statement.break_label(),
1198 loop_statement.break_label());
1204 __ bind(loop_statement.break_label());
1205 decrement_loop_depth();
1209 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
1210 Comment cmnt(masm_,
"[ TryCatchStatement");
1211 SetStatementPosition(stmt);
1218 Label try_entry, handler_entry, exit;
1220 __ bind(&handler_entry);
1221 handler_table()->set(stmt->index(),
Smi::FromInt(handler_entry.pos()));
1224 { Comment cmnt(masm_,
"[ Extend catch context");
1225 __ Push(stmt->variable()->name());
1226 __ push(result_register());
1227 PushFunctionArgumentForContextAllocation();
1228 __ CallRuntime(Runtime::kPushCatchContext, 3);
1230 context_register());
1233 Scope* saved_scope = scope();
1234 scope_ = stmt->scope();
1235 ASSERT(scope_->declarations()->is_empty());
1236 { WithOrCatch catch_body(
this);
1237 Visit(stmt->catch_block());
1242 scope_ = saved_scope;
1246 __ bind(&try_entry);
1247 __ PushTryHandler(StackHandler::CATCH, stmt->index());
1248 { TryCatch try_body(
this);
1249 Visit(stmt->try_block());
1256 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
1257 Comment cmnt(masm_,
"[ TryFinallyStatement");
1258 SetStatementPosition(stmt);
1280 Label try_entry, handler_entry, finally_entry;
1284 __ bind(&handler_entry);
1285 handler_table()->set(stmt->index(),
Smi::FromInt(handler_entry.pos()));
1290 __ Call(&finally_entry);
1291 __ push(result_register());
1292 __ CallRuntime(Runtime::kReThrow, 1);
1295 __ bind(&finally_entry);
1296 EnterFinallyBlock();
1297 { Finally finally_body(
this);
1298 Visit(stmt->finally_block());
1303 __ bind(&try_entry);
1304 __ PushTryHandler(StackHandler::FINALLY, stmt->index());
1305 { TryFinally try_body(
this, &finally_entry);
1306 Visit(stmt->try_block());
1314 __ Call(&finally_entry);
1318 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
1319 #ifdef ENABLE_DEBUGGER_SUPPORT
1320 Comment cmnt(masm_,
"[ DebuggerStatement");
1321 SetStatementPosition(stmt);
1329 void FullCodeGenerator::VisitConditional(Conditional* expr) {
1330 Comment cmnt(masm_,
"[ Conditional");
1331 Label true_case, false_case, done;
1332 VisitForControl(expr->condition(), &true_case, &false_case, &true_case);
1335 __ bind(&true_case);
1336 SetExpressionPosition(expr->then_expression(),
1337 expr->then_expression_position());
1338 if (context()->IsTest()) {
1340 VisitForControl(expr->then_expression(),
1341 for_test->true_label(),
1342 for_test->false_label(),
1345 VisitInDuplicateContext(expr->then_expression());
1350 __ bind(&false_case);
1351 SetExpressionPosition(expr->else_expression(),
1352 expr->else_expression_position());
1353 VisitInDuplicateContext(expr->else_expression());
1355 if (!context()->IsTest()) {
1361 void FullCodeGenerator::VisitLiteral(Literal* expr) {
1362 Comment cmnt(masm_,
"[ Literal");
1363 context()->Plug(expr->handle());
1367 void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
1368 Comment cmnt(masm_,
"[ FunctionLiteral");
1371 Handle<SharedFunctionInfo> function_info =
1373 if (function_info.is_null()) {
1377 EmitNewClosure(function_info, expr->pretenure());
1381 void FullCodeGenerator::VisitSharedFunctionInfoLiteral(
1382 SharedFunctionInfoLiteral* expr) {
1383 Comment cmnt(masm_,
"[ SharedFunctionInfoLiteral");
1384 EmitNewClosure(expr->shared_function_info(),
false);
1388 void FullCodeGenerator::VisitThrow(Throw* expr) {
1389 Comment cmnt(masm_,
"[ Throw");
1390 VisitForStackValue(expr->exception());
1391 __ CallRuntime(Runtime::kThrow, 1);
1398 int* context_length) {
1400 __ Drop(*stack_depth);
1407 bool FullCodeGenerator::TryLiteralCompare(CompareOperation* expr) {
1408 Expression* sub_expr;
1409 Handle<String>
check;
1410 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) {
1411 EmitLiteralCompareTypeof(expr, sub_expr, check);
1415 if (expr->IsLiteralCompareUndefined(&sub_expr)) {
1420 if (expr->IsLiteralCompareNull(&sub_expr)) {
1421 EmitLiteralCompareNil(expr, sub_expr,
kNullValue);
bool FLAG_enable_slow_asserts
#define INLINE_FUNCTION_LIST(F)
static Handle< Object > SetProperty(Handle< JSReceiver > object, Handle< String > key, Handle< Object > value, PropertyAttributes attributes, StrictModeFlag strict_mode)
void PrintF(const char *format,...)
static TypeFeedbackInfo * cast(Object *obj)
static String * cast(Object *obj)
Handle< ScopeInfo > GetScopeInfo()
static uint32_t encode(Statevalue)
static Smi * FromInt(int value)
static bool MakeCode(CompilationInfo *info)
static Handle< T > cast(Handle< S > that)
#define ASSERT(condition)
static void PrintCode(Handle< Code > code, CompilationInfo *info)
static bool IsValid(intptr_t value)
static TestContext * cast(AstContext *context)
bool has_pending_exception()
friend class NestedStatement
#define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize)
static bool RecordPositions(MacroAssembler *masm, int pos, bool right_here=false)
static const int kContextOffset
static Flags ComputeFlags(Kind kind, InlineCacheState ic_state=UNINITIALIZED, ExtraICState extra_ic_state=kNoExtraICState, PropertyType type=NORMAL, int argc=-1, InlineCacheHolderFlag holder=OWN_MAP)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
static Handle< SharedFunctionInfo > BuildFunctionInfo(FunctionLiteral *node, Handle< Script > script)
static const int kMaximumSlots
static int LengthOfFixedArray(int cell_count)
PositionsRecorder * positions_recorder()
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
void Check(Statement *stmt)
static bool is_valid(LanguageModevalue)
#define INLINE_RUNTIME_FUNCTION_LIST(F)
static Handle< Code > MakeCodeEpilogue(MacroAssembler *masm, Code::Flags flags, CompilationInfo *info)
void check(i::Vector< const char > string)
static void MakeCodePrologue(CompilationInfo *info)
ZoneList< Declaration * > * declarations()