diff options
Diffstat (limited to 'deps/v8/src/full-codegen/full-codegen.cc')
-rw-r--r-- | deps/v8/src/full-codegen/full-codegen.cc | 552 |
1 files changed, 81 insertions, 471 deletions
diff --git a/deps/v8/src/full-codegen/full-codegen.cc b/deps/v8/src/full-codegen/full-codegen.cc index ee5e8881ba..b8021366a2 100644 --- a/deps/v8/src/full-codegen/full-codegen.cc +++ b/deps/v8/src/full-codegen/full-codegen.cc @@ -42,6 +42,9 @@ class FullCodegenCompilationJob final : public CompilationJob { } CompilationJob::Status FinalizeJobImpl() final { return SUCCEEDED; } + + private: + DISALLOW_COPY_AND_ASSIGN(FullCodegenCompilationJob); }; FullCodeGenerator::FullCodeGenerator(MacroAssembler* masm, @@ -62,7 +65,6 @@ FullCodeGenerator::FullCodeGenerator(MacroAssembler* masm, : 0, info->zone()), back_edges_(2, info->zone()), - handler_table_(info->zone()), source_position_table_builder_(info->zone(), info->SourcePositionRecordingMode()), ic_total_count_(0) { @@ -84,6 +86,7 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) { bool FullCodeGenerator::MakeCode(CompilationInfo* info, uintptr_t stack_limit) { Isolate* isolate = info->isolate(); + DCHECK(!info->shared_info()->must_use_ignition_turbo()); DCHECK(!FLAG_minimal); RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::CompileFullCode); @@ -114,7 +117,6 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info, uintptr_t stack_limit) { CodeGenerator::MakeCodeEpilogue(&masm, nullptr, info, masm.CodeObject()); 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_allow_osr_at_loop_nesting_level(0); @@ -175,41 +177,15 @@ 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) { - table->SetRangeStart(i, handler_table_[i].range_start); - table->SetRangeEnd(i, handler_table_[i].range_end); - table->SetRangeHandler(i, handler_table_[i].handler_offset, - handler_table_[i].catch_prediction); - table->SetRangeData(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, HandlerTable::UNCAUGHT}; - handler_table_.push_back(entry); - return index; -} - - bool FullCodeGenerator::MustCreateObjectLiteralWithRuntime( ObjectLiteral* expr) const { - return masm()->serializer_enabled() || - !FastCloneShallowObjectStub::IsSupported(expr); + return masm()->serializer_enabled() || !expr->IsFastCloningSupported(); } bool FullCodeGenerator::MustCreateArrayLiteralWithRuntime( ArrayLiteral* expr) const { - return expr->depth() > 1 || - expr->values()->length() > JSArray::kInitialMaxFastElementArray; + return !expr->IsFastCloningSupported(); } void FullCodeGenerator::Initialize(uintptr_t stack_limit) { @@ -237,7 +213,7 @@ void FullCodeGenerator::CallLoadIC(FeedbackVectorSlot slot, Handle<Code> code = CodeFactory::LoadIC(isolate()).code(); __ Call(code, RelocInfo::CODE_TARGET); - if (FLAG_tf_load_ic_stub) RestoreContext(); + RestoreContext(); } void FullCodeGenerator::CallStoreIC(FeedbackVectorSlot slot, @@ -499,15 +475,15 @@ void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, TypeofMode typeof_mode) { -#ifdef DEBUG Variable* var = proxy->var(); - DCHECK(var->IsUnallocated() || - (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); -#endif + DCHECK(var->IsUnallocated()); + __ Move(LoadDescriptor::NameRegister(), var->name()); + EmitLoadSlot(LoadGlobalDescriptor::SlotRegister(), proxy->VariableFeedbackSlot()); Handle<Code> code = CodeFactory::LoadGlobalIC(isolate(), typeof_mode).code(); __ Call(code, RelocInfo::CODE_TARGET); + RestoreContext(); } void FullCodeGenerator::VisitSloppyBlockFunctionStatement( @@ -623,10 +599,6 @@ void FullCodeGenerator::EmitIntrinsicAsStubCall(CallRuntime* expr, context()->Plug(result_register()); } -void FullCodeGenerator::EmitNewObject(CallRuntime* expr) { - EmitIntrinsicAsStubCall(expr, CodeFactory::FastNewObject(isolate())); -} - void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { EmitIntrinsicAsStubCall(expr, CodeFactory::NumberToString(isolate())); } @@ -878,30 +850,17 @@ void FullCodeGenerator::VisitProperty(Property* expr) { Expression* key = expr->key(); if (key->IsPropertyName()) { - if (!expr->IsSuperAccess()) { - VisitForAccumulatorValue(expr->obj()); - __ Move(LoadDescriptor::ReceiverRegister(), result_register()); - EmitNamedPropertyLoad(expr); - } else { - VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); - VisitForStackValue( - expr->obj()->AsSuperPropertyReference()->home_object()); - EmitNamedSuperPropertyLoad(expr); - } + DCHECK(!expr->IsSuperAccess()); + VisitForAccumulatorValue(expr->obj()); + __ Move(LoadDescriptor::ReceiverRegister(), result_register()); + EmitNamedPropertyLoad(expr); } else { - if (!expr->IsSuperAccess()) { - VisitForStackValue(expr->obj()); - VisitForAccumulatorValue(expr->key()); - __ Move(LoadDescriptor::NameRegister(), result_register()); - PopOperand(LoadDescriptor::ReceiverRegister()); - EmitKeyedPropertyLoad(expr); - } else { - VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); - VisitForStackValue( - expr->obj()->AsSuperPropertyReference()->home_object()); - VisitForStackValue(expr->key()); - EmitKeyedSuperPropertyLoad(expr); - } + DCHECK(!expr->IsSuperAccess()); + VisitForStackValue(expr->obj()); + VisitForAccumulatorValue(expr->key()); + __ Move(LoadDescriptor::NameRegister(), result_register()); + PopOperand(LoadDescriptor::ReceiverRegister()); + EmitKeyedPropertyLoad(expr); } PrepareForBailoutForId(expr->LoadId(), BailoutState::TOS_REGISTER); context()->Plug(result_register()); @@ -912,8 +871,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { DCHECK(!context()->IsEffect()); DCHECK(!context()->IsTest()); - if (proxy != NULL && - (proxy->var()->IsUnallocated() || proxy->var()->IsLookupSlot())) { + if (proxy != NULL && proxy->var()->IsUnallocated()) { EmitVariableLoad(proxy, INSIDE_TYPEOF); PrepareForBailout(proxy, BailoutState::TOS_REGISTER); } else { @@ -987,19 +945,10 @@ void FullCodeGenerator::EmitContinue(Statement* target) { NestedStatement* current = nesting_stack_; int context_length = 0; // When continuing, we clobber the unpredictable value in the accumulator - // with one that's safe for GC. If we hit an exit from the try block of - // try...finally on our way out, we will unconditionally preserve the - // accumulator on the stack. + // with one that's safe for GC. ClearAccumulator(); while (!current->IsContinueTarget(target)) { if (HasStackOverflow()) return; - if (current->IsTryFinally()) { - Comment cmnt(masm(), "[ Deferred continue through finally"); - current->Exit(&context_length); - DCHECK_EQ(-1, context_length); - current->AsTryFinally()->deferred_commands()->RecordContinue(target); - return; - } current = current->Exit(&context_length); } int stack_depth = current->GetStackDepthAtTarget(); @@ -1028,19 +977,10 @@ void FullCodeGenerator::EmitBreak(Statement* target) { NestedStatement* current = nesting_stack_; int context_length = 0; // When breaking, we clobber the unpredictable value in the accumulator - // with one that's safe for GC. If we hit an exit from the try block of - // try...finally on our way out, we will unconditionally preserve the - // accumulator on the stack. + // with one that's safe for GC. ClearAccumulator(); while (!current->IsBreakTarget(target)) { if (HasStackOverflow()) return; - if (current->IsTryFinally()) { - Comment cmnt(masm(), "[ Deferred break through finally"); - current->Exit(&context_length); - DCHECK_EQ(-1, context_length); - current->AsTryFinally()->deferred_commands()->RecordBreak(target); - return; - } current = current->Exit(&context_length); } int stack_depth = current->GetStackDepthAtTarget(); @@ -1070,31 +1010,34 @@ void FullCodeGenerator::EmitUnwindAndReturn() { int context_length = 0; while (current != NULL) { if (HasStackOverflow()) return; - if (current->IsTryFinally()) { - Comment cmnt(masm(), "[ Deferred return through finally"); - current->Exit(&context_length); - DCHECK_EQ(-1, context_length); - current->AsTryFinally()->deferred_commands()->RecordReturn(); - return; - } current = current->Exit(&context_length); } EmitReturnSequence(); } void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, + FeedbackVectorSlot slot, bool pretenure) { + // If slot is invalid, then it's a native function literal and we + // can pass the empty array or empty literal array, something like that... + // If we're running with the --always-opt or the --prepare-always-opt // flag, we need to use the runtime function so that the new function // we are creating here gets a chance to have its code optimized and // doesn't just get a copy of the existing unoptimized code. if (!FLAG_always_opt && !FLAG_prepare_always_opt && !pretenure && scope()->is_function_scope()) { - FastNewClosureStub stub(isolate()); - __ Move(stub.GetCallInterfaceDescriptor().GetRegisterParameter(0), info); - __ CallStub(&stub); + Callable callable = CodeFactory::FastNewClosure(isolate()); + __ Move(callable.descriptor().GetRegisterParameter(0), info); + __ EmitLoadTypeFeedbackVector( + callable.descriptor().GetRegisterParameter(1)); + __ Move(callable.descriptor().GetRegisterParameter(2), SmiFromSlot(slot)); + __ Call(callable.code(), RelocInfo::CODE_TARGET); } else { __ Push(info); + __ EmitLoadTypeFeedbackVector(result_register()); + __ Push(result_register()); + __ Push(SmiFromSlot(slot)); __ CallRuntime(pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure); } @@ -1110,17 +1053,6 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { CallLoadIC(prop->PropertyFeedbackSlot(), key->value()); } -void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { - // Stack: receiver, home_object - SetExpressionPosition(prop); - Literal* key = prop->key()->AsLiteral(); - DCHECK(!key->value()->IsSmi()); - DCHECK(prop->IsSuperAccess()); - - PushOperand(key->value()); - CallRuntimeWithOperands(Runtime::kLoadFromSuper); -} - void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { SetExpressionPosition(prop); @@ -1131,20 +1063,6 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { RestoreContext(); } -void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { - // Stack: receiver, home_object, key. - SetExpressionPosition(prop); - CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); -} - -void FullCodeGenerator::EmitPropertyKey(LiteralProperty* property, - BailoutId bailout_id) { - VisitForStackValue(property->key()); - CallRuntimeWithOperands(Runtime::kToName); - PrepareForBailoutForId(bailout_id, BailoutState::TOS_REGISTER); - PushOperand(result_register()); -} - void FullCodeGenerator::EmitLoadSlot(Register destination, FeedbackVectorSlot slot) { DCHECK(!slot.IsInvalid()); @@ -1165,33 +1083,8 @@ void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) { - Comment cmnt(masm_, "[ WithStatement"); - SetStatementPosition(stmt); - - VisitForAccumulatorValue(stmt->expression()); - Callable callable = CodeFactory::ToObject(isolate()); - __ Move(callable.descriptor().GetRegisterParameter(0), result_register()); - __ Call(callable.code(), RelocInfo::CODE_TARGET); - RestoreContext(); - PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER); - PushOperand(result_register()); - PushOperand(stmt->scope()->scope_info()); - PushFunctionArgumentForContextAllocation(); - CallRuntimeWithOperands(Runtime::kPushWithContext); - StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); - PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); - - Scope* saved_scope = scope(); - scope_ = stmt->scope(); - { WithOrCatch body(this); - Visit(stmt->statement()); - } - scope_ = saved_scope; - - // Pop context. - LoadContextField(context_register(), Context::PREVIOUS_INDEX); - // Update local stack frame context field. - StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); + // Dynamic scoping is not supported. + UNREACHABLE(); } @@ -1312,43 +1205,8 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { - Comment cmnt(masm_, "[ ForOfStatement"); - - Iteration loop_statement(this, stmt); - increment_loop_depth(); - - // var iterator = iterable[Symbol.iterator](); - SetExpressionAsStatementPosition(stmt->assign_iterator()); - VisitForEffect(stmt->assign_iterator()); - - // Loop entry. - __ bind(loop_statement.continue_label()); - - // result = iterator.next() - SetExpressionAsStatementPosition(stmt->next_result()); - VisitForEffect(stmt->next_result()); - - // if (result.done) break; - Label result_not_done; - VisitForControl(stmt->result_done(), loop_statement.break_label(), - &result_not_done, &result_not_done); - __ bind(&result_not_done); - - // each = result.value - VisitForEffect(stmt->assign_each()); - - // Generate code for the body of the loop. - Visit(stmt->body()); - - // Check stack before looping. - PrepareForBailoutForId(stmt->BackEdgeId(), BailoutState::NO_REGISTERS); - EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label()); - __ jmp(loop_statement.continue_label()); - - // Exit and decrement the loop depth. - PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); - __ bind(loop_statement.break_label()); - decrement_loop_depth(); + // Iterator looping is not supported. + UNREACHABLE(); } void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { @@ -1358,127 +1216,14 @@ void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { } void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { - Comment cmnt(masm_, "[ TryCatchStatement"); - 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 - // and control is passed to the catch block with the exception in the - // result register. - - Label try_entry, handler_entry, exit; - __ jmp(&try_entry); - __ bind(&handler_entry); - if (stmt->clear_pending_message()) 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"); - PushOperand(stmt->variable()->name()); - PushOperand(result_register()); - PushOperand(stmt->scope()->scope_info()); - PushFunctionArgumentForContextAllocation(); - CallRuntimeWithOperands(Runtime::kPushCatchContext); - StoreToFrameField(StandardFrameConstants::kContextOffset, - context_register()); - } - - Scope* saved_scope = scope(); - scope_ = stmt->scope(); - DCHECK(scope_->declarations()->is_empty()); - { WithOrCatch catch_body(this); - Visit(stmt->catch_block()); - } - // Restore the context. - LoadContextField(context_register(), Context::PREVIOUS_INDEX); - StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); - scope_ = saved_scope; - __ jmp(&exit); - - // Try block code. Sets up the exception handler chain. - __ bind(&try_entry); - - int handler_index = NewHandlerTableEntry(); - EnterTryBlock(handler_index, &handler_entry, stmt->catch_prediction()); - { - Comment cmnt_try(masm(), "[ Try block"); - Visit(stmt->try_block()); - } - ExitTryBlock(handler_index); - __ bind(&exit); + // Exception handling is not supported. + UNREACHABLE(); } void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { - Comment cmnt(masm_, "[ TryFinallyStatement"); - 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. - // - // The try-finally construct can enter the finally block in three ways: - // 1. By exiting the try-block normally. This exits the try block, - // pushes the continuation token and falls through to the finally - // block. - // 2. By exiting the try-block with a function-local control flow transfer - // (break/continue/return). The site of the, e.g., break exits the - // try block, pushes the continuation token and jumps to the - // finally block. After the finally block executes, the execution - // continues based on the continuation token to a block that - // continues with the control flow transfer. - // 3. By exiting the try-block with a thrown exception. In the handler, - // we push the exception and continuation token and jump to the - // finally block (which will again dispatch based on the token once - // it is finished). - - Label try_entry, handler_entry, finally_entry; - DeferredCommands deferred(this, &finally_entry); - - // Jump to try-handler setup and try-block code. - __ jmp(&try_entry); - __ bind(&handler_entry); - - // Exception handler code. This code is only executed when an exception - // is thrown. Record the continuation and jump to the finally block. - { - Comment cmnt_handler(masm(), "[ Finally handler"); - deferred.RecordThrow(); - } - - // Set up try handler. - __ bind(&try_entry); - int handler_index = NewHandlerTableEntry(); - EnterTryBlock(handler_index, &handler_entry, stmt->catch_prediction()); - { - Comment cmnt_try(masm(), "[ Try block"); - TryFinally try_body(this, &deferred); - Visit(stmt->try_block()); - } - 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 - // stack. - ClearAccumulator(); - deferred.EmitFallThrough(); - // Fall through to the finally block. - - // Finally block implementation. - __ bind(&finally_entry); - { - Comment cmnt_finally(masm(), "[ Finally block"); - OperandStackDepthIncrement(2); // Token and accumulator are on stack. - EnterFinallyBlock(); - Visit(stmt->finally_block()); - ExitFinallyBlock(); - OperandStackDepthDecrement(2); // Token and accumulator were on stack. - } - - { - Comment cmnt_deferred(masm(), "[ Post-finally dispatch"); - deferred.EmitCommands(); // Return to the calling code. - } + // Exception handling is not supported. + UNREACHABLE(); } @@ -1546,46 +1291,13 @@ void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { SetStackOverflow(); return; } - EmitNewClosure(function_info, expr->pretenure()); + EmitNewClosure(function_info, expr->LiteralFeedbackSlot(), expr->pretenure()); } void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) { - Comment cmnt(masm_, "[ ClassLiteral"); - - if (lit->extends() != NULL) { - VisitForStackValue(lit->extends()); - } else { - PushOperand(isolate()->factory()->the_hole_value()); - } - - VisitForStackValue(lit->constructor()); - - PushOperand(Smi::FromInt(lit->start_position())); - PushOperand(Smi::FromInt(lit->end_position())); - - CallRuntimeWithOperands(Runtime::kDefineClass); - PrepareForBailoutForId(lit->CreateLiteralId(), BailoutState::TOS_REGISTER); - PushOperand(result_register()); - - // Load the "prototype" from the constructor. - __ Move(LoadDescriptor::ReceiverRegister(), result_register()); - CallLoadIC(lit->PrototypeSlot(), isolate()->factory()->prototype_string()); - PrepareForBailoutForId(lit->PrototypeId(), BailoutState::TOS_REGISTER); - PushOperand(result_register()); - - EmitClassDefineProperties(lit); - DropOperands(1); - - // Set the constructor to have fast properties. - CallRuntimeWithOperands(Runtime::kToFastProperties); - - if (lit->class_variable_proxy() != nullptr) { - EmitVariableAssignment(lit->class_variable_proxy()->var(), Token::INIT, - lit->ProxySlot(), HoleCheckMode::kElided); - } - - context()->Plug(result_register()); + // Unsupported + UNREACHABLE(); } void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { @@ -1612,7 +1324,7 @@ void FullCodeGenerator::VisitNativeFunctionLiteral( Comment cmnt(masm_, "[ NativeFunctionLiteral"); Handle<SharedFunctionInfo> shared = Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name()); - EmitNewClosure(shared, false); + EmitNewClosure(shared, expr->LiteralFeedbackSlot(), false); } @@ -1628,32 +1340,6 @@ void FullCodeGenerator::VisitThrow(Throw* expr) { if (context()->IsStackValue()) OperandStackDepthIncrement(1); } -void FullCodeGenerator::EnterTryBlock( - int handler_index, Label* handler, - HandlerTable::CatchPrediction catch_prediction) { - HandlerTableEntry* entry = &handler_table_[handler_index]; - entry->range_start = masm()->pc_offset(); - entry->handler_offset = handler->pos(); - entry->stack_depth = operand_stack_depth_; - entry->catch_prediction = catch_prediction; - - // We are using the operand stack depth, check for accuracy. - EmitOperandStackDepthCheck(); - - // Push context onto operand stack. - STATIC_ASSERT(TryBlockConstant::kElementCount == 1); - PushOperand(context_register()); -} - - -void FullCodeGenerator::ExitTryBlock(int handler_index) { - HandlerTableEntry* entry = &handler_table_[handler_index]; - entry->range_end = masm()->pc_offset(); - - // Drop context from operand stack. - DropOperands(TryBlockConstant::kElementCount); -} - void FullCodeGenerator::VisitCall(Call* expr) { #ifdef DEBUG @@ -1668,48 +1354,38 @@ void FullCodeGenerator::VisitCall(Call* expr) { Expression* callee = expr->expression(); Call::CallType call_type = expr->GetCallType(); - if (expr->is_possibly_eval()) { - EmitPossiblyEvalCall(expr); - } else { - switch (call_type) { - case Call::GLOBAL_CALL: - EmitCallWithLoadIC(expr); - break; - case Call::WITH_CALL: - // Call to a lookup slot looked up through a with scope. - PushCalleeAndWithBaseObject(expr); - EmitCall(expr); - break; - case Call::NAMED_PROPERTY_CALL: { - Property* property = callee->AsProperty(); - VisitForStackValue(property->obj()); - EmitCallWithLoadIC(expr); - break; - } - case Call::KEYED_PROPERTY_CALL: { - Property* property = callee->AsProperty(); - VisitForStackValue(property->obj()); - EmitKeyedCallWithLoadIC(expr, property->key()); - break; - } - case Call::NAMED_SUPER_PROPERTY_CALL: - EmitSuperCallWithLoadIC(expr); - break; - case Call::KEYED_SUPER_PROPERTY_CALL: - EmitKeyedSuperCallWithLoadIC(expr); - break; - case Call::SUPER_CALL: - EmitSuperConstructorCall(expr); - break; - case Call::OTHER_CALL: - // Call to an arbitrary expression not handled specially above. - VisitForStackValue(callee); - OperandStackDepthIncrement(1); - __ PushRoot(Heap::kUndefinedValueRootIndex); - // Emit function call. - EmitCall(expr); - break; + // Eval is unsupported. + CHECK(!expr->is_possibly_eval()); + + switch (call_type) { + case Call::GLOBAL_CALL: + EmitCallWithLoadIC(expr); + break; + case Call::NAMED_PROPERTY_CALL: { + Property* property = callee->AsProperty(); + VisitForStackValue(property->obj()); + EmitCallWithLoadIC(expr); + break; + } + case Call::KEYED_PROPERTY_CALL: { + Property* property = callee->AsProperty(); + VisitForStackValue(property->obj()); + EmitKeyedCallWithLoadIC(expr, property->key()); + break; } + case Call::OTHER_CALL: + // Call to an arbitrary expression not handled specially above. + VisitForStackValue(callee); + OperandStackDepthIncrement(1); + __ PushRoot(Heap::kUndefinedValueRootIndex); + // Emit function call. + EmitCall(expr); + break; + case Call::NAMED_SUPER_PROPERTY_CALL: + case Call::KEYED_SUPER_PROPERTY_CALL: + case Call::SUPER_CALL: + case Call::WITH_CALL: + UNREACHABLE(); } #ifdef DEBUG @@ -1769,78 +1445,12 @@ void FullCodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) { UNREACHABLE(); } +void FullCodeGenerator::VisitGetIterator(GetIterator* expr) { UNREACHABLE(); } void FullCodeGenerator::VisitRewritableExpression(RewritableExpression* expr) { Visit(expr->expression()); } -FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit( - int* context_length) { - // The macros used here must preserve the result register. - - // Calculate how many operands to drop to get down to handler block. - int stack_drop = codegen_->operand_stack_depth_ - GetStackDepthAtTarget(); - DCHECK_GE(stack_drop, 0); - - // Because the handler block contains the context of the finally - // code, we can restore it directly from there for the finally code - // rather than iteratively unwinding contexts via their previous - // links. - if (*context_length > 0) { - __ Drop(stack_drop); // Down to the handler block. - // Restore the context to its dedicated register and the stack. - STATIC_ASSERT(TryBlockConstant::kElementCount == 1); - __ Pop(codegen_->context_register()); - codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset, - codegen_->context_register()); - } else { - // Down to the handler block and also drop context. - __ Drop(stack_drop + TryBlockConstant::kElementCount); - } - - // The caller will ignore outputs. - *context_length = -1; - return previous_; -} - -void FullCodeGenerator::DeferredCommands::RecordBreak(Statement* target) { - TokenId token = dispenser_.GetBreakContinueToken(); - commands_.push_back({kBreak, token, target}); - EmitJumpToFinally(token); -} - -void FullCodeGenerator::DeferredCommands::RecordContinue(Statement* target) { - TokenId token = dispenser_.GetBreakContinueToken(); - commands_.push_back({kContinue, token, target}); - EmitJumpToFinally(token); -} - -void FullCodeGenerator::DeferredCommands::RecordReturn() { - if (return_token_ == TokenDispenserForFinally::kInvalidToken) { - return_token_ = TokenDispenserForFinally::kReturnToken; - commands_.push_back({kReturn, return_token_, nullptr}); - } - EmitJumpToFinally(return_token_); -} - -void FullCodeGenerator::DeferredCommands::RecordThrow() { - if (throw_token_ == TokenDispenserForFinally::kInvalidToken) { - throw_token_ = TokenDispenserForFinally::kThrowToken; - commands_.push_back({kThrow, throw_token_, nullptr}); - } - EmitJumpToFinally(throw_token_); -} - -void FullCodeGenerator::DeferredCommands::EmitFallThrough() { - __ Push(Smi::FromInt(TokenDispenserForFinally::kFallThroughToken)); - __ Push(result_register()); -} - -void FullCodeGenerator::DeferredCommands::EmitJumpToFinally(TokenId token) { - __ Push(Smi::FromInt(token)); - __ Push(result_register()); - __ jmp(finally_entry_); -} bool FullCodeGenerator::TryLiteralCompare(CompareOperation* expr) { Expression* sub_expr; |