summaryrefslogtreecommitdiff
path: root/chromium/v8/src/full-codegen.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/src/full-codegen.cc')
-rw-r--r--chromium/v8/src/full-codegen.cc517
1 files changed, 160 insertions, 357 deletions
diff --git a/chromium/v8/src/full-codegen.cc b/chromium/v8/src/full-codegen.cc
index 0dac7d2e0b0..8ca40ccacd5 100644
--- a/chromium/v8/src/full-codegen.cc
+++ b/chromium/v8/src/full-codegen.cc
@@ -21,262 +21,6 @@
namespace v8 {
namespace internal {
-void BreakableStatementChecker::Check(Statement* stmt) {
- Visit(stmt);
-}
-
-
-void BreakableStatementChecker::Check(Expression* expr) {
- Visit(expr);
-}
-
-
-void BreakableStatementChecker::VisitVariableDeclaration(
- VariableDeclaration* decl) {
-}
-
-
-void BreakableStatementChecker::VisitFunctionDeclaration(
- FunctionDeclaration* decl) {
-}
-
-
-void BreakableStatementChecker::VisitImportDeclaration(
- ImportDeclaration* decl) {
-}
-
-
-void BreakableStatementChecker::VisitExportDeclaration(
- ExportDeclaration* decl) {
-}
-
-
-void BreakableStatementChecker::VisitBlock(Block* stmt) {
-}
-
-
-void BreakableStatementChecker::VisitExpressionStatement(
- ExpressionStatement* stmt) {
- // Check if expression is breakable.
- Visit(stmt->expression());
-}
-
-
-void BreakableStatementChecker::VisitEmptyStatement(EmptyStatement* stmt) {
-}
-
-
-void BreakableStatementChecker::VisitIfStatement(IfStatement* stmt) {
- // If the condition is breakable the if statement is breakable.
- Visit(stmt->condition());
-}
-
-
-void BreakableStatementChecker::VisitContinueStatement(
- ContinueStatement* stmt) {
-}
-
-
-void BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) {
-}
-
-
-void BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) {
- // Return is breakable if the expression is.
- Visit(stmt->expression());
-}
-
-
-void BreakableStatementChecker::VisitWithStatement(WithStatement* stmt) {
- Visit(stmt->expression());
-}
-
-
-void BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) {
- // Switch statements breakable if the tag expression is.
- Visit(stmt->tag());
-}
-
-
-void BreakableStatementChecker::VisitDoWhileStatement(DoWhileStatement* stmt) {
- // Mark do while as breakable to avoid adding a break slot in front of it.
- is_breakable_ = true;
-}
-
-
-void BreakableStatementChecker::VisitWhileStatement(WhileStatement* stmt) {
- // Mark while statements breakable if the condition expression is.
- Visit(stmt->cond());
-}
-
-
-void BreakableStatementChecker::VisitForStatement(ForStatement* stmt) {
- // We set positions for both init and condition, if they exist.
- if (stmt->cond() != NULL || stmt->init() != NULL) is_breakable_ = true;
-}
-
-
-void BreakableStatementChecker::VisitForInStatement(ForInStatement* stmt) {
- // For-in is breakable because we set the position for the enumerable.
- is_breakable_ = true;
-}
-
-
-void BreakableStatementChecker::VisitForOfStatement(ForOfStatement* stmt) {
- // For-of is breakable because we set the position for the next() call.
- is_breakable_ = true;
-}
-
-
-void BreakableStatementChecker::VisitTryCatchStatement(
- TryCatchStatement* stmt) {
- // Mark try catch as breakable to avoid adding a break slot in front of it.
- is_breakable_ = true;
-}
-
-
-void BreakableStatementChecker::VisitTryFinallyStatement(
- TryFinallyStatement* stmt) {
- // Mark try finally as breakable to avoid adding a break slot in front of it.
- is_breakable_ = true;
-}
-
-
-void BreakableStatementChecker::VisitDebuggerStatement(
- DebuggerStatement* stmt) {
- // The debugger statement is breakable.
- is_breakable_ = true;
-}
-
-
-void BreakableStatementChecker::VisitCaseClause(CaseClause* clause) {
-}
-
-
-void BreakableStatementChecker::VisitFunctionLiteral(FunctionLiteral* expr) {
-}
-
-
-void BreakableStatementChecker::VisitClassLiteral(ClassLiteral* expr) {
- if (expr->extends() != NULL) {
- Visit(expr->extends());
- }
-}
-
-
-void BreakableStatementChecker::VisitNativeFunctionLiteral(
- NativeFunctionLiteral* expr) {
-}
-
-
-void BreakableStatementChecker::VisitConditional(Conditional* expr) {
-}
-
-
-void BreakableStatementChecker::VisitVariableProxy(VariableProxy* expr) {
-}
-
-
-void BreakableStatementChecker::VisitLiteral(Literal* expr) {
-}
-
-
-void BreakableStatementChecker::VisitRegExpLiteral(RegExpLiteral* expr) {
-}
-
-
-void BreakableStatementChecker::VisitObjectLiteral(ObjectLiteral* expr) {
-}
-
-
-void BreakableStatementChecker::VisitArrayLiteral(ArrayLiteral* expr) {
-}
-
-
-void BreakableStatementChecker::VisitAssignment(Assignment* expr) {
- // If assigning to a property (including a global property) the assignment is
- // breakable.
- VariableProxy* proxy = expr->target()->AsVariableProxy();
- Property* prop = expr->target()->AsProperty();
- if (prop != NULL || (proxy != NULL && proxy->var()->IsUnallocated())) {
- is_breakable_ = true;
- return;
- }
-
- // Otherwise the assignment is breakable if the assigned value is.
- Visit(expr->value());
-}
-
-
-void BreakableStatementChecker::VisitYield(Yield* expr) {
- // Yield is breakable if the expression is.
- Visit(expr->expression());
-}
-
-
-void BreakableStatementChecker::VisitThrow(Throw* expr) {
- // Throw is breakable if the expression is.
- Visit(expr->exception());
-}
-
-
-void BreakableStatementChecker::VisitProperty(Property* expr) {
- // Property load is breakable.
- is_breakable_ = true;
-}
-
-
-void BreakableStatementChecker::VisitCall(Call* expr) {
- // Function calls both through IC and call stub are breakable.
- is_breakable_ = true;
-}
-
-
-void BreakableStatementChecker::VisitCallNew(CallNew* expr) {
- // Function calls through new are breakable.
- is_breakable_ = true;
-}
-
-
-void BreakableStatementChecker::VisitCallRuntime(CallRuntime* expr) {
-}
-
-
-void BreakableStatementChecker::VisitUnaryOperation(UnaryOperation* expr) {
- Visit(expr->expression());
-}
-
-
-void BreakableStatementChecker::VisitCountOperation(CountOperation* expr) {
- Visit(expr->expression());
-}
-
-
-void BreakableStatementChecker::VisitBinaryOperation(BinaryOperation* expr) {
- Visit(expr->left());
- if (expr->op() != Token::AND &&
- expr->op() != Token::OR) {
- Visit(expr->right());
- }
-}
-
-
-void BreakableStatementChecker::VisitCompareOperation(CompareOperation* expr) {
- Visit(expr->left());
- Visit(expr->right());
-}
-
-
-void BreakableStatementChecker::VisitSpread(Spread* expr) { UNREACHABLE(); }
-
-
-void BreakableStatementChecker::VisitThisFunction(ThisFunction* expr) {
-}
-
-
-void BreakableStatementChecker::VisitSuperReference(SuperReference* expr) {}
-
-
#define __ ACCESS_MASM(masm())
bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
@@ -310,14 +54,11 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
Code::Flags flags = Code::ComputeFlags(Code::FUNCTION);
Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
- code->set_optimizable(info->IsOptimizable() &&
- !info->function()->dont_optimize() &&
- info->function()->scope()->AllowsLazyCompilation());
cgen.PopulateDeoptimizationData(code);
cgen.PopulateTypeFeedbackInfo(code);
+ cgen.PopulateHandlerTable(code);
code->set_has_deoptimization_support(info->HasDeoptimizationSupport());
code->set_has_reloc_info_for_serialization(info->will_serialize());
- code->set_handler_table(*cgen.handler_table());
code->set_compiled_optimizable(info->IsOptimizable());
code->set_allow_osr_at_loop_nesting_level(0);
code->set_profiler_ticks(0);
@@ -397,6 +138,32 @@ void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) {
}
+void FullCodeGenerator::PopulateHandlerTable(Handle<Code> code) {
+ int handler_table_size = static_cast<int>(handler_table_.size());
+ Handle<HandlerTable> table =
+ Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
+ HandlerTable::LengthForRange(handler_table_size), TENURED));
+ for (int i = 0; i < handler_table_size; ++i) {
+ HandlerTable::CatchPrediction prediction =
+ handler_table_[i].try_catch_depth > 0 ? HandlerTable::CAUGHT
+ : HandlerTable::UNCAUGHT;
+ table->SetRangeStart(i, handler_table_[i].range_start);
+ table->SetRangeEnd(i, handler_table_[i].range_end);
+ table->SetRangeHandler(i, handler_table_[i].handler_offset, prediction);
+ table->SetRangeDepth(i, handler_table_[i].stack_depth);
+ }
+ code->set_handler_table(*table);
+}
+
+
+int FullCodeGenerator::NewHandlerTableEntry() {
+ int index = static_cast<int>(handler_table_.size());
+ HandlerTableEntry entry = {0, 0, 0, 0, 0};
+ handler_table_.push_back(entry);
+ return index;
+}
+
+
bool FullCodeGenerator::MustCreateObjectLiteralWithRuntime(
ObjectLiteral* expr) const {
int literal_flags = expr->ComputeFlags();
@@ -413,7 +180,8 @@ bool FullCodeGenerator::MustCreateObjectLiteralWithRuntime(
bool FullCodeGenerator::MustCreateArrayLiteralWithRuntime(
ArrayLiteral* expr) const {
- return expr->depth() > 1 ||
+ // TODO(rossberg): Teach strong mode to FastCloneShallowArrayStub.
+ return expr->depth() > 1 || expr->is_strong() ||
expr->values()->length() > JSObject::kInitialMaxFastElementArray;
}
@@ -438,23 +206,14 @@ void FullCodeGenerator::PrepareForBailout(Expression* node, State state) {
void FullCodeGenerator::CallLoadIC(ContextualMode contextual_mode,
+ LanguageMode language_mode,
TypeFeedbackId id) {
- Handle<Code> ic = CodeFactory::LoadIC(isolate(), contextual_mode).code();
+ Handle<Code> ic =
+ CodeFactory::LoadIC(isolate(), contextual_mode, language_mode).code();
CallIC(ic, id);
}
-void FullCodeGenerator::CallGlobalLoadIC(Handle<String> name) {
- if (masm()->serializer_enabled() || FLAG_vector_ics) {
- // Vector-ICs don't work with LoadGlobalIC.
- return CallLoadIC(CONTEXTUAL);
- }
- Handle<Code> ic = CodeFactory::LoadGlobalIC(
- isolate(), isolate()->global_object(), name).code();
- CallIC(ic, TypeFeedbackId::None());
-}
-
-
void FullCodeGenerator::CallStoreIC(TypeFeedbackId id) {
Handle<Code> ic = CodeFactory::StoreIC(isolate(), language_mode()).code();
CallIC(ic, id);
@@ -643,73 +402,67 @@ int FullCodeGenerator::DeclareGlobalsFlags() {
}
+bool RecordStatementPosition(MacroAssembler* masm, int pos) {
+ if (pos == RelocInfo::kNoPosition) return false;
+ masm->positions_recorder()->RecordStatementPosition(pos);
+ masm->positions_recorder()->RecordPosition(pos);
+ return masm->positions_recorder()->WriteRecordedPositions();
+}
+
+
+bool RecordPosition(MacroAssembler* masm, int pos) {
+ if (pos == RelocInfo::kNoPosition) return false;
+ masm->positions_recorder()->RecordPosition(pos);
+ return masm->positions_recorder()->WriteRecordedPositions();
+}
+
+
void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
- CodeGenerator::RecordPositions(masm_, fun->start_position());
+ RecordPosition(masm_, fun->start_position());
}
void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
- CodeGenerator::RecordPositions(masm_, fun->end_position() - 1);
+ RecordStatementPosition(masm_, fun->end_position() - 1);
}
-void FullCodeGenerator::SetStatementPosition(Statement* stmt) {
- if (!info_->is_debug()) {
- CodeGenerator::RecordPositions(masm_, stmt->position());
- } else {
- // Check if the statement will be breakable without adding a debug break
- // slot.
- BreakableStatementChecker checker(info_->isolate(), zone());
- checker.Check(stmt);
- // Record the statement position right here if the statement is not
- // breakable. For breakable statements the actual recording of the
- // position will be postponed to the breakable code (typically an IC).
- bool position_recorded = CodeGenerator::RecordPositions(
- masm_, stmt->position(), !checker.is_breakable());
- // If the position recording did record a new position generate a debug
- // break slot to make the statement breakable.
- if (position_recorded) {
- DebugCodegen::GenerateSlot(masm_);
- }
+void FullCodeGenerator::SetStatementPosition(
+ Statement* stmt, FullCodeGenerator::InsertBreak insert_break) {
+ if (stmt->position() == RelocInfo::kNoPosition) return;
+ bool recorded = RecordStatementPosition(masm_, stmt->position());
+ if (recorded && insert_break == INSERT_BREAK && info_->is_debug() &&
+ !stmt->IsDebuggerStatement()) {
+ DebugCodegen::GenerateSlot(masm_);
}
}
-void FullCodeGenerator::VisitSuperReference(SuperReference* super) {
- __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0);
+void FullCodeGenerator::SetExpressionPosition(
+ Expression* expr, FullCodeGenerator::InsertBreak insert_break) {
+ if (expr->position() == RelocInfo::kNoPosition) return;
+ bool recorded = RecordPosition(masm_, expr->position());
+ if (recorded && insert_break == INSERT_BREAK && info_->is_debug()) {
+ DebugCodegen::GenerateSlot(masm_);
+ }
}
-void FullCodeGenerator::SetExpressionPosition(Expression* expr) {
- if (!info_->is_debug()) {
- CodeGenerator::RecordPositions(masm_, expr->position());
- } else {
- // Check if the expression will be breakable without adding a debug break
- // slot.
- BreakableStatementChecker checker(info_->isolate(), zone());
- checker.Check(expr);
- // Record a statement position right here if the expression is not
- // breakable. For breakable expressions the actual recording of the
- // position will be postponed to the breakable code (typically an IC).
- // NOTE this will record a statement position for something which might
- // not be a statement. As stepping in the debugger will only stop at
- // statement positions this is used for e.g. the condition expression of
- // a do while loop.
- bool position_recorded = CodeGenerator::RecordPositions(
- masm_, expr->position(), !checker.is_breakable());
- // If the position recording did record a new position generate a debug
- // break slot to make the statement breakable.
- if (position_recorded) {
- DebugCodegen::GenerateSlot(masm_);
- }
- }
+void FullCodeGenerator::SetExpressionAsStatementPosition(Expression* expr) {
+ if (expr->position() == RelocInfo::kNoPosition) return;
+ bool recorded = RecordStatementPosition(masm_, expr->position());
+ if (recorded && info_->is_debug()) DebugCodegen::GenerateSlot(masm_);
}
-void FullCodeGenerator::SetSourcePosition(int pos) {
- if (pos != RelocInfo::kNoPosition) {
- masm_->positions_recorder()->RecordPosition(pos);
- }
+void FullCodeGenerator::VisitSuperPropertyReference(
+ SuperPropertyReference* super) {
+ __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0);
+}
+
+
+void FullCodeGenerator::VisitSuperCallReference(SuperCallReference* super) {
+ __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0);
}
@@ -845,7 +598,7 @@ void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
VisitForStackValue(left);
VisitForAccumulatorValue(right);
- SetSourcePosition(expr->position());
+ SetExpressionPosition(expr);
if (ShouldInlineSmiCase(op)) {
EmitInlineSmiBinaryOp(expr, op, left, right);
} else {
@@ -854,6 +607,22 @@ void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
}
+void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
+ VariableProxy* proxy = expr->AsVariableProxy();
+ DCHECK(!context()->IsEffect());
+ DCHECK(!context()->IsTest());
+
+ if (proxy != NULL && (proxy->var()->IsUnallocatedOrGlobalSlot() ||
+ proxy->var()->IsLookupSlot())) {
+ EmitVariableLoad(proxy, INSIDE_TYPEOF);
+ PrepareForBailout(proxy, TOS_REG);
+ } else {
+ // This expression cannot throw a reference error at the top level.
+ VisitInDuplicateContext(expr);
+ }
+}
+
+
void FullCodeGenerator::VisitBlock(Block* stmt) {
Comment cmnt(masm_, "[ Block");
NestedBlock nested_block(this, stmt);
@@ -985,6 +754,12 @@ void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property,
}
+void FullCodeGenerator::EmitLoadSuperConstructor(SuperCallReference* ref) {
+ VisitForStackValue(ref->this_function_var());
+ __ CallRuntime(Runtime::kGetPrototype, 1);
+}
+
+
void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
Comment cmnt(masm_, "[ ReturnStatement");
SetStatementPosition(stmt);
@@ -1021,7 +796,9 @@ void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) {
void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
Comment cmnt(masm_, "[ DoWhileStatement");
- SetStatementPosition(stmt);
+ // Do not insert break location as we do that below.
+ SetStatementPosition(stmt, SKIP_BREAK);
+
Label body, book_keeping;
Iteration loop_statement(this, stmt);
@@ -1034,7 +811,9 @@ void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
// possible to break on the condition.
__ bind(loop_statement.continue_label());
PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
- SetExpressionPosition(stmt->cond());
+
+ // Here is the actual 'while' keyword.
+ SetExpressionAsStatementPosition(stmt->cond());
VisitForControl(stmt->cond(),
&book_keeping,
loop_statement.break_label(),
@@ -1061,7 +840,7 @@ void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
__ bind(&loop);
- SetExpressionPosition(stmt->cond());
+ SetExpressionAsStatementPosition(stmt->cond());
VisitForControl(stmt->cond(),
&body,
loop_statement.break_label(),
@@ -1085,13 +864,13 @@ void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
Comment cmnt(masm_, "[ ForStatement");
+ // Do not insert break location as we do it below.
+ SetStatementPosition(stmt, SKIP_BREAK);
+
Label test, body;
Iteration loop_statement(this, stmt);
- // Set statement position for a break slot before entering the for-body.
- SetStatementPosition(stmt);
-
if (stmt->init() != NULL) {
SetStatementPosition(stmt->init());
Visit(stmt->init());
@@ -1112,16 +891,12 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
Visit(stmt->next());
}
- // Emit the statement position here as this is where the for
- // statement code starts.
- SetStatementPosition(stmt);
-
// Check stack before looping.
EmitBackEdgeBookkeeping(stmt, &body);
__ bind(&test);
if (stmt->cond() != NULL) {
- SetExpressionPosition(stmt->cond());
+ SetExpressionAsStatementPosition(stmt->cond());
VisitForControl(stmt->cond(),
&body,
loop_statement.break_label(),
@@ -1138,7 +913,6 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
Comment cmnt(masm_, "[ ForOfStatement");
- SetStatementPosition(stmt);
Iteration loop_statement(this, stmt);
increment_loop_depth();
@@ -1150,7 +924,7 @@ void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
__ bind(loop_statement.continue_label());
// result = iterator.next()
- SetExpressionPosition(stmt->next_result());
+ SetExpressionAsStatementPosition(stmt->next_result());
VisitForEffect(stmt->next_result());
// if (result.done) break;
@@ -1179,7 +953,8 @@ void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
Comment cmnt(masm_, "[ TryCatchStatement");
- SetStatementPosition(stmt);
+ SetStatementPosition(stmt, SKIP_BREAK);
+
// The try block adds a handler to the exception handler chain before
// entering, and removes it again when exiting normally. If an exception
// is thrown during execution of the try block, the handler is consumed
@@ -1189,6 +964,9 @@ void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
Label try_entry, handler_entry, exit;
__ jmp(&try_entry);
__ bind(&handler_entry);
+ PrepareForBailoutForId(stmt->HandlerId(), NO_REGISTERS);
+ ClearPendingMessage();
+
// Exception handler code, the exception is in the result register.
// Extend the context before executing the catch block.
{ Comment cmnt(masm_, "[ Extend catch context");
@@ -1214,18 +992,23 @@ void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
// Try block code. Sets up the exception handler chain.
__ bind(&try_entry);
- EnterTryBlock(stmt->index(), &handler_entry);
+
+ try_catch_depth_++;
+ int handler_index = NewHandlerTableEntry();
+ EnterTryBlock(handler_index, &handler_entry);
{ TryCatch try_body(this);
Visit(stmt->try_block());
}
- ExitTryBlock(stmt->index());
+ ExitTryBlock(handler_index);
+ try_catch_depth_--;
__ bind(&exit);
}
void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
Comment cmnt(masm_, "[ TryFinallyStatement");
- SetStatementPosition(stmt);
+ SetStatementPosition(stmt, SKIP_BREAK);
+
// Try finally is compiled by setting up a try-handler on the stack while
// executing the try body, and removing it again afterwards.
//
@@ -1252,6 +1035,8 @@ void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
// Jump to try-handler setup and try-block code.
__ jmp(&try_entry);
__ bind(&handler_entry);
+ PrepareForBailoutForId(stmt->HandlerId(), NO_REGISTERS);
+
// Exception handler code. This code is only executed when an exception
// is thrown. The exception is in the result register, and must be
// preserved by the finally block. Call the finally block and then
@@ -1270,11 +1055,12 @@ void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
// Set up try handler.
__ bind(&try_entry);
- EnterTryBlock(stmt->index(), &handler_entry);
+ int handler_index = NewHandlerTableEntry();
+ EnterTryBlock(handler_index, &handler_entry);
{ TryFinally try_body(this, &finally_entry);
Visit(stmt->try_block());
}
- ExitTryBlock(stmt->index());
+ ExitTryBlock(handler_index);
// Execute the finally block on the way out. Clobber the unpredictable
// value in the result register with one that's safe for GC because the
// finally block will unconditionally preserve the result register on the
@@ -1341,7 +1127,7 @@ void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
// Build the function boilerplate and instantiate it.
Handle<SharedFunctionInfo> function_info =
- Compiler::BuildFunctionInfo(expr, script(), info_);
+ Compiler::GetSharedFunctionInfo(expr, script(), info_);
if (function_info.is_null()) {
SetStackOverflow();
return;
@@ -1377,13 +1163,22 @@ void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) {
__ CallRuntime(Runtime::kDefineClass, 6);
PrepareForBailoutForId(lit->CreateLiteralId(), TOS_REG);
- EmitClassDefineProperties(lit);
+
+ int store_slot_index = 0;
+ EmitClassDefineProperties(lit, &store_slot_index);
if (lit->scope() != NULL) {
DCHECK_NOT_NULL(lit->class_variable_proxy());
+ FeedbackVectorICSlot slot = FLAG_vector_stores
+ ? lit->GetNthSlot(store_slot_index++)
+ : FeedbackVectorICSlot::Invalid();
EmitVariableAssignment(lit->class_variable_proxy()->var(),
- Token::INIT_CONST);
+ Token::INIT_CONST, slot);
}
+
+ // Verify that compilation exactly consumed the number of store ic slots
+ // that the ClassLiteral node had to offer.
+ DCHECK(!FLAG_vector_stores || store_slot_index == lit->slot_count());
}
context()->Plug(result_register());
@@ -1394,15 +1189,19 @@ void FullCodeGenerator::VisitNativeFunctionLiteral(
NativeFunctionLiteral* expr) {
Comment cmnt(masm_, "[ NativeFunctionLiteral");
+ v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate());
+
// Compute the function template for the native function.
Handle<String> name = expr->name();
- v8::Handle<v8::FunctionTemplate> fun_template =
- expr->extension()->GetNativeFunctionTemplate(
- reinterpret_cast<v8::Isolate*>(isolate()), v8::Utils::ToLocal(name));
+ v8::Local<v8::FunctionTemplate> fun_template =
+ expr->extension()->GetNativeFunctionTemplate(v8_isolate,
+ v8::Utils::ToLocal(name));
DCHECK(!fun_template.IsEmpty());
// Instantiate the function and create a shared function info from it.
- Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction());
+ Handle<JSFunction> fun = Utils::OpenHandle(
+ *fun_template->GetFunction(v8_isolate->GetCurrentContext())
+ .ToLocalChecked());
const int literals = fun->NumberOfLiterals();
Handle<Code> code = Handle<Code>(fun->shared()->code());
Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
@@ -1425,22 +1224,24 @@ void FullCodeGenerator::VisitNativeFunctionLiteral(
void FullCodeGenerator::VisitThrow(Throw* expr) {
Comment cmnt(masm_, "[ Throw");
VisitForStackValue(expr->exception());
- SetSourcePosition(expr->position());
+ SetExpressionPosition(expr);
__ CallRuntime(Runtime::kThrow, 1);
// Never returns here.
}
-void FullCodeGenerator::EnterTryBlock(int index, Label* handler) {
- handler_table()->SetRangeStart(index, masm()->pc_offset());
- handler_table()->SetRangeHandler(index, handler->pos());
+void FullCodeGenerator::EnterTryBlock(int handler_index, Label* handler) {
+ HandlerTableEntry* entry = &handler_table_[handler_index];
+ entry->range_start = masm()->pc_offset();
+ entry->handler_offset = handler->pos();
+ entry->try_catch_depth = try_catch_depth_;
// Determine expression stack depth of try statement.
int stack_depth = info_->scope()->num_stack_slots(); // Include stack locals.
for (NestedStatement* current = nesting_stack_; current != NULL; /*nop*/) {
current = current->AccumulateDepth(&stack_depth);
}
- handler_table()->SetRangeDepth(index, stack_depth);
+ entry->stack_depth = stack_depth;
// Push context onto operand stack.
STATIC_ASSERT(TryBlockConstant::kElementCount == 1);
@@ -1448,8 +1249,9 @@ void FullCodeGenerator::EnterTryBlock(int index, Label* handler) {
}
-void FullCodeGenerator::ExitTryBlock(int index) {
- handler_table()->SetRangeEnd(index, masm()->pc_offset());
+void FullCodeGenerator::ExitTryBlock(int handler_index) {
+ HandlerTableEntry* entry = &handler_table_[handler_index];
+ entry->range_end = masm()->pc_offset();
// Drop context from operand stack.
__ Drop(TryBlockConstant::kElementCount);
@@ -1648,4 +1450,5 @@ FullCodeGenerator::EnterBlockScopeIfNeeded::~EnterBlockScopeIfNeeded() {
#undef __
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8