Skip to content
This repository has been archived by the owner on Nov 2, 2019. It is now read-only.

Commit

Permalink
Handle a special case where control escapes try block through several…
Browse files Browse the repository at this point in the history
… scopes.
  • Loading branch information
whitequark committed Jun 19, 2012
1 parent bea6c70 commit b05e392
Showing 1 changed file with 25 additions and 4 deletions.
29 changes: 25 additions & 4 deletions lib/furnace-avm2/transform/cfg_reduce.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ def transform(cfg)
@postcond_heads = Set.new
@postcond_tails = Set.new

@try_tails = Hash.new { |h,k| h[k] = Set.new }

ast, = extended_block(@cfg.entry)

@visited.add @cfg.exit
Expand Down Expand Up @@ -71,12 +73,25 @@ def possibly_wrap_eh(block, nodes, exception, loop_stack, nesting)
AST::Node.new(:begin, nodes),
] + handlers) ]

# Handle a special case whether control doesn't flow after tails
# of the catches by its own, e.g. the last statement of try
# block is return.
if tails.any? && tails.uniq.count == 1 &&
@dom[tails.first].include?(exception)
tail_code = extended_block(tails.first, nil, loop_stack, nesting + 1, nil)
# Handle a special case whether control doesn't flow after tails
# of the catches by its own, e.g. the last statement of try
# block is return.

tail_block = tails.first
elsif @try_tails.has_key? exception
# Handle a special case where control falls through more than
# one level of scopes.
if @try_tails[exception].count > 1
raise "multiple try block exit points"
end

tail_block = @try_tails[exception].first
end

if tail_block
tail_code = extended_block(tail_block, nil, loop_stack, nesting + 1, nil)
eh_nodes.concat tail_code.children
end

Expand Down Expand Up @@ -134,6 +149,12 @@ def extended_block(block, stopgap=nil, loop_stack=[], nesting=0, upper_exc=nil)
break
elsif block.cti && block.cti.type == :exception_dispatch
log nesting, "exit: spurious exception dispatch traverse"
break
elsif !upper_exc.nil? && block.exception.nil? && block != @cfg.exit
log nesting, "exit: leaving try block"

@try_tails[upper_exc].add block

break
elsif block == @cfg.exit
# We have just arrived to exit node.
Expand Down

0 comments on commit b05e392

Please sign in to comment.