Skip to content

Commit

Permalink
add not reachable FunctionLiteral completion
Browse files Browse the repository at this point in the history
  • Loading branch information
Constellation committed Aug 19, 2011
1 parent 2ebae90 commit d455a11
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 9 deletions.
20 changes: 20 additions & 0 deletions az/ast_fwd.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,25 @@ namespace iv {
namespace core {
namespace ast {

template<>
class ScopeBase<az::AstFactory>
: public Inherit<az::AstFactory, kScope> {
public:
friend class az::AstFactory;
typedef typename SpaceVector<az::AstFactory, FunctionLiteral<az::AstFactory>* >::type FunctionLiterals;

void RegisterFunctionLiteral(FunctionLiteral<az::AstFactory>* literal) {
literals_->push_back(literal);
}

const FunctionLiterals& GetFunctionLiteralsUnderThis() const {
return *literals_;
}

private:
FunctionLiterals* literals_;
};

template<>
class AstNodeBase<az::AstFactory>
: public Inherit<az::AstFactory, kAstNode> {
Expand Down Expand Up @@ -126,6 +145,7 @@ class FunctionLiteralBase<az::AstFactory>
private:
StatementType* normal_;
StatementType* raised_;
bool reachable_;
};

template<>
Expand Down
12 changes: 12 additions & 0 deletions az/cfa2/binding_resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,9 @@ void BindingResolver::Visit(FunctionLiteral* literal) {
// first Statement
literal->set_normal(literal->body().front());
}

heap_->InitWaitingResults(literal);

MarkStatements(literal->body());

// for completion phase
Expand All @@ -505,6 +508,15 @@ void BindingResolver::Visit(FunctionLiteral* literal) {
}
}

for (Scope::FunctionLiterals::const_iterator it = scope.GetFunctionLiteralsUnderThis().begin(),
last = scope.GetFunctionLiteralsUnderThis().end(); it != last; ++it) {
if (!heap_->IsWaited(*it)) {
// not reachable function
heap_->RegisterNotReachable(*it);
Visit(*it);
}
}

// shrink outer scope to previous size (remove added inner scope bindings)
outer_scope_.resize(previous_size);
inner_scope_ = previous_inner_scope;
Expand Down
14 changes: 12 additions & 2 deletions az/cfa2/heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ class Heap : private iv::core::Noncopyable<Heap> {
factory_(),
ast_factory_(ast_factory),
completer_(completer),
state_(kInitialState) {

state_(kInitialState),
waiting_result_(),
not_reachable_functions_() {
const std::vector<AVal> empty;
// initialize builtin objects

Expand Down Expand Up @@ -1057,6 +1058,14 @@ class Heap : private iv::core::Noncopyable<Heap> {
return std::shared_ptr<Execution>();
}

void RegisterNotReachable(FunctionLiteral* literal) {
not_reachable_functions_.insert(literal);
}

bool IsNotReachable(FunctionLiteral* literal) {
return not_reachable_functions_.find(literal) != not_reachable_functions_.end();
}

// prototype getters

const AVal& GetArrayPrototype() const {
Expand Down Expand Up @@ -1153,6 +1162,7 @@ class Heap : private iv::core::Noncopyable<Heap> {
typedef std::deque<std::shared_ptr<Execution> > ExecutionQueue;
typedef std::unordered_map<const FunctionLiteral*, std::shared_ptr<ExecutionQueue> > WaitingMap;
WaitingMap waiting_result_;
std::unordered_set<FunctionLiteral*> not_reachable_functions_;
};

} } // namespace az::cfa2
Expand Down
21 changes: 18 additions & 3 deletions az/cfa2/heap_initializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ void HeapInitializer::Initialize(FunctionLiteral* global) {
}
}

heap_->InitWaitingResults(global);

for (Statements::const_iterator it = global->body().begin(),
last = global->body().end(); it != last; ++it) {
(*it)->Accept(this);
Expand All @@ -33,6 +31,14 @@ void HeapInitializer::Initialize(FunctionLiteral* global) {
heap_->completer()->GetTargetExpression()->Accept(this);
}
}

for (Scope::FunctionLiterals::const_iterator it = scope.GetFunctionLiteralsUnderThis().begin(),
last = scope.GetFunctionLiteralsUnderThis().end(); it != last; ++it) {
if (heap_->IsNotReachable(*it)) {
// not reachable function
Visit(*it);
}
}
}

// Statements
Expand Down Expand Up @@ -285,7 +291,6 @@ void HeapInitializer::Visit(FunctionLiteral* literal) {

// insert current function summary
heap_->InitSummary(literal, obj);
heap_->InitWaitingResults(literal);

for (Statements::const_iterator it = literal->body().begin(),
last = literal->body().end(); it != last; ++it) {
Expand All @@ -299,6 +304,16 @@ void HeapInitializer::Visit(FunctionLiteral* literal) {
heap_->completer()->GetTargetExpression()->Accept(this);
}
}

const Scope& scope = literal->scope();

for (Scope::FunctionLiterals::const_iterator it = scope.GetFunctionLiteralsUnderThis().begin(),
last = scope.GetFunctionLiteralsUnderThis().end(); it != last; ++it) {
if (heap_->IsNotReachable(*it)) {
// not reachable function
Visit(*it);
}
}
}

void HeapInitializer::Visit(IdentifierAccess* prop) {
Expand Down
4 changes: 3 additions & 1 deletion az/factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ class AstFactory
}

Scope* NewScope(FunctionLiteral::DeclType type) {
return new (this) Scope(this, type == FunctionLiteral::GLOBAL);
Scope* scope = new (this) Scope(this, type == FunctionLiteral::GLOBAL);
scope->literals_ = NewVector<FunctionLiteral*>();
return scope;
}

template<typename Range>
Expand Down
12 changes: 10 additions & 2 deletions az/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -2524,7 +2524,14 @@ class Parser : private iv::core::Noncopyable<> {
}
}
} else {
RAISE_RECOVERVABLE("invalid property name");
// FIXME:(Constellation) more effective method
// const std::size_t end = lexer_->begin_position();
// Next();
// RAISE_STATEMENT("invalid property name");
// reporter_->ReportSyntaxError(errors_.back(), begin);
// *res = true; // recovery
// return factory_->NewObjectLiteral(prop, begin, end);
RAISE("invalid property name");
}

if (token_ != Token::TK_RBRACE) {
Expand Down Expand Up @@ -2754,7 +2761,8 @@ class Parser : private iv::core::Noncopyable<> {
end_block_position,
begin_position,
end_block_position);

// register function literal to upper scope
scope_->GetUpperScope()->RegisterFunctionLiteral(function);
if (completer_ &&
completer_->HasCompletionPoint() &&
!completer_->HasTargetFunction()) {
Expand Down
2 changes: 1 addition & 1 deletion deps/iv
Submodule iv updated 2 files
+2 −2 src/alloc.h
+8 −2 src/ast.h

0 comments on commit d455a11

Please sign in to comment.