// frames-arm.h for its layout.
void FullCodeGenerator::Generate() {
CompilationInfo* info = info_;
- handler_table_ =
- Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
- HandlerTable::LengthForRange(function()->handler_count()), TENURED));
-
profiling_counter_ = isolate()->factory()->NewCell(
Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
SetFunctionPosition(function());
// re-boxing.
__ bind(&l_try);
__ pop(r0); // result
- EnterTryBlock(expr->index(), &l_catch);
+ int handler_index = NewHandlerTableEntry();
+ EnterTryBlock(handler_index, &l_catch);
const int try_block_size = TryCatch::kElementCount * kPointerSize;
__ push(r0); // result
__ jmp(&l_suspend);
const int generator_object_depth = kPointerSize + try_block_size;
__ ldr(r0, MemOperand(sp, generator_object_depth));
__ push(r0); // g
- __ Push(Smi::FromInt(expr->index())); // handler-index
+ __ Push(Smi::FromInt(handler_index)); // handler-index
DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
__ mov(r1, Operand(Smi::FromInt(l_continuation.pos())));
__ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset));
__ pop(r0); // result
EmitReturnSequence();
__ bind(&l_resume); // received in r0
- ExitTryBlock(expr->index());
+ ExitTryBlock(handler_index);
// receiver = iter; f = 'next'; arg = received;
__ bind(&l_next);
// frames-arm.h for its layout.
void FullCodeGenerator::Generate() {
CompilationInfo* info = info_;
- handler_table_ =
- Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
- HandlerTable::LengthForRange(function()->handler_count()), TENURED));
-
profiling_counter_ = isolate()->factory()->NewCell(
Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
SetFunctionPosition(function());
// re-boxing.
__ Bind(&l_try);
__ Pop(x0); // result
- EnterTryBlock(expr->index(), &l_catch);
+ int handler_index = NewHandlerTableEntry();
+ EnterTryBlock(handler_index, &l_catch);
const int try_block_size = TryCatch::kElementCount * kPointerSize;
__ Push(x0); // result
__ B(&l_suspend);
const int generator_object_depth = kPointerSize + try_block_size;
__ Peek(x0, generator_object_depth);
__ Push(x0); // g
- __ Push(Smi::FromInt(expr->index())); // handler-index
+ __ Push(Smi::FromInt(handler_index)); // handler-index
DCHECK((l_continuation.pos() > 0) && Smi::IsValid(l_continuation.pos()));
__ Mov(x1, Smi::FromInt(l_continuation.pos()));
__ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset));
__ Pop(x0); // result
EmitReturnSequence();
__ Bind(&l_resume); // received in x0
- ExitTryBlock(expr->index());
+ ExitTryBlock(handler_index);
// receiver = iter; f = 'next'; arg = received;
__ Bind(&l_next);
class TryStatement : public Statement {
public:
- int index() const { return index_; }
Block* try_block() const { return try_block_; }
protected:
- TryStatement(Zone* zone, int index, Block* try_block, int pos)
- : Statement(zone, pos), index_(index), try_block_(try_block) {}
+ TryStatement(Zone* zone, Block* try_block, int pos)
+ : Statement(zone, pos), try_block_(try_block) {}
private:
- // Unique (per-function) index of this handler. This is not an AST ID.
- int index_;
-
Block* try_block_;
};
Block* catch_block() const { return catch_block_; }
protected:
- TryCatchStatement(Zone* zone,
- int index,
- Block* try_block,
- Scope* scope,
- Variable* variable,
- Block* catch_block,
- int pos)
- : TryStatement(zone, index, try_block, pos),
+ TryCatchStatement(Zone* zone, Block* try_block, Scope* scope,
+ Variable* variable, Block* catch_block, int pos)
+ : TryStatement(zone, try_block, pos),
scope_(scope),
variable_(variable),
- catch_block_(catch_block) {
- }
+ catch_block_(catch_block) {}
private:
Scope* scope_;
Block* finally_block() const { return finally_block_; }
protected:
- TryFinallyStatement(
- Zone* zone, int index, Block* try_block, Block* finally_block, int pos)
- : TryStatement(zone, index, try_block, pos),
- finally_block_(finally_block) { }
+ TryFinallyStatement(Zone* zone, Block* try_block, Block* finally_block,
+ int pos)
+ : TryStatement(zone, try_block, pos), finally_block_(finally_block) {}
private:
Block* finally_block_;
Expression* expression() const { return expression_; }
Kind yield_kind() const { return yield_kind_; }
- // Delegating yield surrounds the "yield" in a "try/catch". This index
- // locates the catch handler in the handler table, and is equivalent to
- // TryCatchStatement::index().
- int index() const {
- DCHECK_EQ(kDelegating, yield_kind());
- return index_;
- }
- void set_index(int index) {
- DCHECK_EQ(kDelegating, yield_kind());
- index_ = index;
- }
-
// Type feedback information.
bool HasFeedbackSlots() const { return yield_kind() == kDelegating; }
virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
generator_object_(generator_object),
expression_(expression),
yield_kind_(yield_kind),
- index_(-1),
yield_first_feedback_slot_(FeedbackVectorICSlot::Invalid()) {}
private:
Expression* generator_object_;
Expression* expression_;
Kind yield_kind_;
- int index_;
FeedbackVectorICSlot yield_first_feedback_slot_;
};
int materialized_literal_count() { return materialized_literal_count_; }
int expected_property_count() { return expected_property_count_; }
- int handler_count() { return handler_count_; }
int parameter_count() { return parameter_count_; }
bool AllowsLazyCompilation();
FunctionLiteral(Zone* zone, const AstRawString* name,
AstValueFactory* ast_value_factory, Scope* scope,
ZoneList<Statement*>* body, int materialized_literal_count,
- int expected_property_count, int handler_count,
- int parameter_count, FunctionType function_type,
+ int expected_property_count, int parameter_count,
+ FunctionType function_type,
ParameterFlag has_duplicate_parameters,
IsFunctionFlag is_function,
EagerCompileHint eager_compile_hint, FunctionKind kind,
dont_optimize_reason_(kNoReason),
materialized_literal_count_(materialized_literal_count),
expected_property_count_(expected_property_count),
- handler_count_(handler_count),
parameter_count_(parameter_count),
function_token_position_(RelocInfo::kNoPosition) {
bitfield_ = IsExpression::encode(function_type != DECLARATION) |
int materialized_literal_count_;
int expected_property_count_;
- int handler_count_;
int parameter_count_;
int function_token_position_;
IfStatement(zone_, condition, then_statement, else_statement, pos);
}
- TryCatchStatement* NewTryCatchStatement(int index,
- Block* try_block,
- Scope* scope,
+ TryCatchStatement* NewTryCatchStatement(Block* try_block, Scope* scope,
Variable* variable,
- Block* catch_block,
- int pos) {
- return new (zone_) TryCatchStatement(zone_, index, try_block, scope,
- variable, catch_block, pos);
+ Block* catch_block, int pos) {
+ return new (zone_)
+ TryCatchStatement(zone_, try_block, scope, variable, catch_block, pos);
}
- TryFinallyStatement* NewTryFinallyStatement(int index,
- Block* try_block,
- Block* finally_block,
- int pos) {
+ TryFinallyStatement* NewTryFinallyStatement(Block* try_block,
+ Block* finally_block, int pos) {
return new (zone_)
- TryFinallyStatement(zone_, index, try_block, finally_block, pos);
+ TryFinallyStatement(zone_, try_block, finally_block, pos);
}
DebuggerStatement* NewDebuggerStatement(int pos) {
FunctionLiteral* NewFunctionLiteral(
const AstRawString* name, AstValueFactory* ast_value_factory,
Scope* scope, ZoneList<Statement*>* body, int materialized_literal_count,
- int expected_property_count, int handler_count, int parameter_count,
+ int expected_property_count, int parameter_count,
FunctionLiteral::ParameterFlag has_duplicate_parameters,
FunctionLiteral::FunctionType function_type,
FunctionLiteral::IsFunctionFlag is_function,
int position) {
return new (zone_) FunctionLiteral(
zone_, name, ast_value_factory, scope, body, materialized_literal_count,
- expected_property_count, handler_count, parameter_count, function_type,
+ expected_property_count, parameter_count, function_type,
has_duplicate_parameters, is_function, eager_compile_hint, kind,
position);
}
Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
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);
}
+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();
__ bind(&try_entry);
try_catch_depth_++;
- EnterTryBlock(stmt->index(), &handler_entry);
+ 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);
}
// 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
}
-void FullCodeGenerator::EnterTryBlock(int index, Label* handler) {
- handler_table()->SetRangeStart(index, masm()->pc_offset());
- HandlerTable::CatchPrediction prediction =
- try_catch_depth_ > 0 ? HandlerTable::CAUGHT : HandlerTable::UNCAUGHT;
- handler_table()->SetRangeHandler(index, handler->pos(), prediction);
+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);
}
-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);
: 0,
info->zone()),
back_edges_(2, info->zone()),
+ handler_table_(info->zone()),
ic_total_count_(0) {
DCHECK(!info->IsStub());
Initialize();
void Generate();
void PopulateDeoptimizationData(Handle<Code> code);
void PopulateTypeFeedbackInfo(Handle<Code> code);
+ void PopulateHandlerTable(Handle<Code> code);
bool MustCreateObjectLiteralWithRuntime(ObjectLiteral* expr) const;
bool MustCreateArrayLiteralWithRuntime(ArrayLiteral* expr) const;
void EmitLoadStoreICSlot(FeedbackVectorICSlot slot);
- Handle<HandlerTable> handler_table() { return handler_table_; }
+ int NewHandlerTableEntry();
struct BailoutEntry {
BailoutId id;
uint32_t loop_depth;
};
+ struct HandlerTableEntry {
+ unsigned range_start;
+ unsigned range_end;
+ unsigned handler_offset;
+ int stack_depth;
+ int try_catch_depth;
+ };
+
class ExpressionContext BASE_EMBEDDED {
public:
explicit ExpressionContext(FullCodeGenerator* codegen)
const ExpressionContext* context_;
ZoneList<BailoutEntry> bailout_entries_;
ZoneList<BackEdgeEntry> back_edges_;
+ ZoneVector<HandlerTableEntry> handler_table_;
int ic_total_count_;
- Handle<HandlerTable> handler_table_;
Handle<Cell> profiling_counter_;
bool generate_debug_code_;
// frames-ia32.h for its layout.
void FullCodeGenerator::Generate() {
CompilationInfo* info = info_;
- handler_table_ =
- Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
- HandlerTable::LengthForRange(function()->handler_count()), TENURED));
-
profiling_counter_ = isolate()->factory()->NewCell(
Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
SetFunctionPosition(function());
// re-boxing.
__ bind(&l_try);
__ pop(eax); // result
- EnterTryBlock(expr->index(), &l_catch);
+ int handler_index = NewHandlerTableEntry();
+ EnterTryBlock(handler_index, &l_catch);
const int try_block_size = TryCatch::kElementCount * kPointerSize;
__ push(eax); // result
__ jmp(&l_suspend);
const int generator_object_depth = kPointerSize + try_block_size;
__ mov(eax, Operand(esp, generator_object_depth));
__ push(eax); // g
- __ push(Immediate(Smi::FromInt(expr->index()))); // handler-index
+ __ push(Immediate(Smi::FromInt(handler_index))); // handler-index
DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
__ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset),
Immediate(Smi::FromInt(l_continuation.pos())));
__ pop(eax); // result
EmitReturnSequence();
__ bind(&l_resume); // received in eax
- ExitTryBlock(expr->index());
+ ExitTryBlock(handler_index);
// receiver = iter; f = iter.next; arg = received;
__ bind(&l_next);
// frames-mips.h for its layout.
void FullCodeGenerator::Generate() {
CompilationInfo* info = info_;
- handler_table_ =
- Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
- HandlerTable::LengthForRange(function()->handler_count()), TENURED));
-
profiling_counter_ = isolate()->factory()->NewCell(
Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
SetFunctionPosition(function());
// re-boxing.
__ bind(&l_try);
__ pop(a0); // result
- EnterTryBlock(expr->index(), &l_catch);
+ int handler_index = NewHandlerTableEntry();
+ EnterTryBlock(handler_index, &l_catch);
const int try_block_size = TryCatch::kElementCount * kPointerSize;
__ push(a0); // result
__ jmp(&l_suspend);
const int generator_object_depth = kPointerSize + try_block_size;
__ lw(a0, MemOperand(sp, generator_object_depth));
__ push(a0); // g
- __ Push(Smi::FromInt(expr->index())); // handler-index
+ __ Push(Smi::FromInt(handler_index)); // handler-index
DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
__ li(a1, Operand(Smi::FromInt(l_continuation.pos())));
__ sw(a1, FieldMemOperand(a0, JSGeneratorObject::kContinuationOffset));
EmitReturnSequence();
__ mov(a0, v0);
__ bind(&l_resume); // received in a0
- ExitTryBlock(expr->index());
+ ExitTryBlock(handler_index);
// receiver = iter; f = 'next'; arg = received;
__ bind(&l_next);
// frames-mips.h for its layout.
void FullCodeGenerator::Generate() {
CompilationInfo* info = info_;
- handler_table_ =
- Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
- HandlerTable::LengthForRange(function()->handler_count()), TENURED));
-
profiling_counter_ = isolate()->factory()->NewCell(
Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
SetFunctionPosition(function());
// re-boxing.
__ bind(&l_try);
__ pop(a0); // result
- EnterTryBlock(expr->index(), &l_catch);
+ int handler_index = NewHandlerTableEntry();
+ EnterTryBlock(handler_index, &l_catch);
const int try_block_size = TryCatch::kElementCount * kPointerSize;
__ push(a0); // result
__ jmp(&l_suspend);
const int generator_object_depth = kPointerSize + try_block_size;
__ ld(a0, MemOperand(sp, generator_object_depth));
__ push(a0); // g
- __ Push(Smi::FromInt(expr->index())); // handler-index
+ __ Push(Smi::FromInt(handler_index)); // handler-index
DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
__ li(a1, Operand(Smi::FromInt(l_continuation.pos())));
__ sd(a1, FieldMemOperand(a0, JSGeneratorObject::kContinuationOffset));
EmitReturnSequence();
__ mov(a0, v0);
__ bind(&l_resume); // received in a0
- ExitTryBlock(expr->index());
+ ExitTryBlock(handler_index);
// receiver = iter; f = 'next'; arg = received;
__ bind(&l_next);
int pos, int end_pos) {
int materialized_literal_count = -1;
int expected_property_count = -1;
- int handler_count = 0;
int parameter_count = 0;
const AstRawString* name = ast_value_factory()->empty_string();
materialized_literal_count = function_state.materialized_literal_count();
expected_property_count = function_state.expected_property_count();
- handler_count = function_state.handler_count();
}
FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
name, ast_value_factory(), function_scope, body,
- materialized_literal_count, expected_property_count, handler_count,
- parameter_count, FunctionLiteral::kNoDuplicateParameters,
+ materialized_literal_count, expected_property_count, parameter_count,
+ FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
FunctionLiteral::kShouldLazyCompile, kind, pos);
result = factory()->NewFunctionLiteral(
ast_value_factory()->empty_string(), ast_value_factory(), scope_,
body, function_state.materialized_literal_count(),
- function_state.expected_property_count(),
- function_state.handler_count(), 0,
+ function_state.expected_property_count(), 0,
FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval,
FunctionLiteral::kShouldLazyCompile, FunctionKind::kNormalFunction,
if (catch_block != NULL && finally_block != NULL) {
// If we have both, create an inner try/catch.
DCHECK(catch_scope != NULL && catch_variable != NULL);
- int index = function_state_->NextHandlerIndex();
- TryCatchStatement* statement = factory()->NewTryCatchStatement(
- index, try_block, catch_scope, catch_variable, catch_block,
- RelocInfo::kNoPosition);
+ TryCatchStatement* statement =
+ factory()->NewTryCatchStatement(try_block, catch_scope, catch_variable,
+ catch_block, RelocInfo::kNoPosition);
try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
try_block->AddStatement(statement, zone());
catch_block = NULL; // Clear to indicate it's been handled.
if (catch_block != NULL) {
DCHECK(finally_block == NULL);
DCHECK(catch_scope != NULL && catch_variable != NULL);
- int index = function_state_->NextHandlerIndex();
- result = factory()->NewTryCatchStatement(
- index, try_block, catch_scope, catch_variable, catch_block, pos);
+ result = factory()->NewTryCatchStatement(try_block, catch_scope,
+ catch_variable, catch_block, pos);
} else {
DCHECK(finally_block != NULL);
- int index = function_state_->NextHandlerIndex();
- result = factory()->NewTryFinallyStatement(
- index, try_block, finally_block, pos);
+ result = factory()->NewTryFinallyStatement(try_block, finally_block, pos);
}
return result;
ZoneList<Statement*>* body = NULL;
int materialized_literal_count = -1;
int expected_property_count = -1;
- int handler_count = 0;
ExpressionClassifier formals_classifier;
FunctionLiteral::EagerCompileHint eager_compile_hint =
parenthesized_function_ ? FunctionLiteral::kShouldEagerCompile
kind, CHECK_OK);
materialized_literal_count = function_state.materialized_literal_count();
expected_property_count = function_state.expected_property_count();
- handler_count = function_state.handler_count();
if (is_strong(language_mode()) && IsSubclassConstructor(kind)) {
if (!function_state.super_location().IsValid()) {
FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
function_name, ast_value_factory(), scope, body,
- materialized_literal_count, expected_property_count, handler_count,
- num_parameters, duplicate_parameters, function_type,
- FunctionLiteral::kIsFunction, eager_compile_hint, kind, pos);
+ materialized_literal_count, expected_property_count, num_parameters,
+ duplicate_parameters, function_type, FunctionLiteral::kIsFunction,
+ eager_compile_hint, kind, pos);
function_literal->set_function_token_position(function_token_pos);
if (should_be_used_once_hint)
function_literal->set_should_be_used_once_hint();
// frames-ppc.h for its layout.
void FullCodeGenerator::Generate() {
CompilationInfo* info = info_;
- handler_table_ =
- Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
- HandlerTable::LengthForRange(function()->handler_count()), TENURED));
-
profiling_counter_ = isolate()->factory()->NewCell(
Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
SetFunctionPosition(function());
// re-boxing.
__ bind(&l_try);
__ pop(r3); // result
- EnterTryBlock(expr->index(), &l_catch);
+ int handler_index = NewHandlerTableEntry();
+ EnterTryBlock(handler_index, &l_catch);
const int try_block_size = TryCatch::kElementCount * kPointerSize;
__ push(r3); // result
__ b(&l_suspend);
const int generator_object_depth = kPointerSize + try_block_size;
__ LoadP(r3, MemOperand(sp, generator_object_depth));
__ push(r3); // g
- __ Push(Smi::FromInt(expr->index())); // handler-index
+ __ Push(Smi::FromInt(handler_index)); // handler-index
DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
__ LoadSmiLiteral(r4, Smi::FromInt(l_continuation.pos()));
__ StoreP(r4, FieldMemOperand(r3, JSGeneratorObject::kContinuationOffset),
__ pop(r3); // result
EmitReturnSequence();
__ bind(&l_resume); // received in r3
- ExitTryBlock(expr->index());
+ ExitTryBlock(handler_index);
// receiver = iter; f = 'next'; arg = received;
__ bind(&l_next);
return next_materialized_literal_index_;
}
- int NextHandlerIndex() { return next_handler_index_++; }
- int handler_count() { return next_handler_index_; }
-
void AddProperty() { expected_property_count_++; }
int expected_property_count() { return expected_property_count_; }
// array literals.
int next_materialized_literal_index_;
- // Used to assign a per-function index to try and catch handlers.
- int next_handler_index_;
-
// Properties count estimation.
int expected_property_count_;
function_state_ = parser->function_state_;
next_materialized_literal_index_ =
function_state_->next_materialized_literal_index_;
- next_handler_index_ = function_state_->next_handler_index_;
expected_property_count_ = function_state_->expected_property_count_;
}
void Restore() {
function_state_->next_materialized_literal_index_ =
next_materialized_literal_index_;
- function_state_->next_handler_index_ = next_handler_index_;
function_state_->expected_property_count_ = expected_property_count_;
}
private:
FunctionState* function_state_;
int next_materialized_literal_index_;
- int next_handler_index_;
int expected_property_count_;
};
PreParserExpression NewFunctionLiteral(
PreParserIdentifier name, AstValueFactory* ast_value_factory,
Scope* scope, PreParserStatementList body, int materialized_literal_count,
- int expected_property_count, int handler_count, int parameter_count,
+ int expected_property_count, int parameter_count,
FunctionLiteral::ParameterFlag has_duplicate_parameters,
FunctionLiteral::FunctionType function_type,
FunctionLiteral::IsFunctionFlag is_function,
FunctionState** function_state_stack, Scope** scope_stack, Scope* scope,
FunctionKind kind, typename Traits::Type::Factory* factory)
: next_materialized_literal_index_(0),
- next_handler_index_(0),
expected_property_count_(0),
this_location_(Scanner::Location::invalid()),
return_location_(Scanner::Location::invalid()),
}
typename Traits::Type::YieldExpression yield =
factory()->NewYield(generator_object, expression, kind, pos);
- if (kind == Yield::kDelegating) {
- yield->set_index(function_state_->NextHandlerIndex());
- }
return yield;
}
int num_parameters = scope->num_parameters();
int materialized_literal_count = -1;
int expected_property_count = -1;
- int handler_count = 0;
Scanner::Location super_loc;
{
materialized_literal_count =
function_state.materialized_literal_count();
expected_property_count = function_state.expected_property_count();
- handler_count = function_state.handler_count();
}
} else {
// Single-expression body
body->Add(factory()->NewReturnStatement(expression, pos), zone());
materialized_literal_count = function_state.materialized_literal_count();
expected_property_count = function_state.expected_property_count();
- handler_count = function_state.handler_count();
}
super_loc = function_state.super_location();
FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
this->EmptyIdentifierString(), ast_value_factory(), scope, body,
- materialized_literal_count, expected_property_count, handler_count,
- num_parameters, FunctionLiteral::kNoDuplicateParameters,
+ materialized_literal_count, expected_property_count, num_parameters,
+ FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction,
scope->start_position());
// frames-x64.h for its layout.
void FullCodeGenerator::Generate() {
CompilationInfo* info = info_;
- handler_table_ =
- Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
- HandlerTable::LengthForRange(function()->handler_count()), TENURED));
-
profiling_counter_ = isolate()->factory()->NewCell(
Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
SetFunctionPosition(function());
// re-boxing.
__ bind(&l_try);
__ Pop(rax); // result
- EnterTryBlock(expr->index(), &l_catch);
+ int handler_index = NewHandlerTableEntry();
+ EnterTryBlock(handler_index, &l_catch);
const int try_block_size = TryCatch::kElementCount * kPointerSize;
__ Push(rax); // result
__ jmp(&l_suspend);
const int generator_object_depth = kPointerSize + try_block_size;
__ movp(rax, Operand(rsp, generator_object_depth));
__ Push(rax); // g
- __ Push(Smi::FromInt(expr->index())); // handler-index
+ __ Push(Smi::FromInt(handler_index)); // handler-index
DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
__ Move(FieldOperand(rax, JSGeneratorObject::kContinuationOffset),
Smi::FromInt(l_continuation.pos()));
__ Pop(rax); // result
EmitReturnSequence();
__ bind(&l_resume); // received in rax
- ExitTryBlock(expr->index());
+ ExitTryBlock(handler_index);
// receiver = iter; f = 'next'; arg = received;
__ bind(&l_next);
// frames-x87.h for its layout.
void FullCodeGenerator::Generate() {
CompilationInfo* info = info_;
- handler_table_ =
- Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
- HandlerTable::LengthForRange(function()->handler_count()), TENURED));
-
profiling_counter_ = isolate()->factory()->NewCell(
Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
SetFunctionPosition(function());
// re-boxing.
__ bind(&l_try);
__ pop(eax); // result
- EnterTryBlock(expr->index(), &l_catch);
+ int handler_index = NewHandlerTableEntry();
+ EnterTryBlock(handler_index, &l_catch);
const int try_block_size = TryCatch::kElementCount * kPointerSize;
__ push(eax); // result
__ jmp(&l_suspend);
const int generator_object_depth = kPointerSize + try_block_size;
__ mov(eax, Operand(esp, generator_object_depth));
__ push(eax); // g
- __ push(Immediate(Smi::FromInt(expr->index()))); // handler-index
+ __ push(Immediate(Smi::FromInt(handler_index))); // handler-index
DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
__ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset),
Immediate(Smi::FromInt(l_continuation.pos())));
__ pop(eax); // result
EmitReturnSequence();
__ bind(&l_resume); // received in eax
- ExitTryBlock(expr->index());
+ ExitTryBlock(handler_index);
// receiver = iter; f = iter.next; arg = received;
__ bind(&l_next);
--- /dev/null
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function f() {
+ throw "boom";
+ try {} catch (e) {}
+}
+assertThrows(f);