node/lib/metasm/metasm/compile_c.rb
def precompile_optimize_inner(list, step)
			lastgoto = nil
			hadref = false
			walk = lambda { |expr|
				next if not expr.kind_of? CExpression
				# gcc's unary && support
				if not expr.op and not expr.lexpr and expr.rexpr.kind_of? Label
					list << expr.rexpr.name
				else
					walk[expr.lexpr]
					if expr.rexpr.kind_of? ::Array
						expr.rexpr.each { |r| walk[r] }
					else
						walk[expr.rexpr]
					end
				end
			}
			@statements.dup.each { |s|
				lastgoto = nil if not s.kind_of? Label
				case s
				when Block
					s.precompile_optimize_inner(list, step)
					@statements.delete s if step == 2 and s.statements.empty?
				when CExpression; walk[s] if step == 1
				when Label
					case step
					when 1
						if lastgoto and lastgoto.target == s.name
							list << lastgoto
							list.delete s.name if not hadref
						end
					when 2; @statements.delete s if not list.include? s.name
					end
				when Goto, If
					s.kind_of?(If) ? g = s.bthen : g = s
					case step
					when 1
						hadref = list.include? g.target
						lastgoto = g
						list << g.target
					when 2
						if list.include? g
							idx = @statements.index s
							@statements.delete s
							@statements[idx, 0] = s.test if s != g and not s.test.constant?
						end
					end
				end
			}
			list
		end
# step 1: list used labels/unused goto
# step 2: remove unused labels
step 1: list used labels/unused goto
step 2: remove unused labels
step 1 : list used labels / unused goto step 2 : remove unused labels
def precompile_optimize_inner(list, step)
			lastgoto = nil
			hadref = false
			walk = lambda { |expr|
				next if not expr.kind_of? CExpression
				if not expr.op and not expr.lexpr and expr.rexpr.kind_of? Label
					list << expr.rexpr.name
				else
					walk[expr.lexpr]
					if expr.rexpr.kind_of? ::Array
						expr.rexpr.each { |r| walk[r] }
					else
						walk[expr.rexpr]
					end
				end
			}
			@statements.dup.each { |s|
				lastgoto = nil if not s.kind_of? Label
				case s
				when Block
					s.precompile_optimize_inner(list, step)
					@statements.delete s if step == 2 and s.statements.empty?
				when CExpression; walk[s] if step == 1
				when Label
					case step
					when 1
						if lastgoto and lastgoto.target == s.name
							list << lastgoto
							list.delete s.name if not hadref
						end
					when 2; @statements.delete s if not list.include? s.name
					end
				when Goto, If
					s.kind_of?(If) ? g = s.bthen : g = s
					case step
					when 1
						hadref = list.include? g.target
						lastgoto = g
						list << g.target
					when 2
						if list.include? g
							idx = @statements.index s
							@statements.delete s
							@statements[idx, 0] = s.test if s != g and not s.test.constant?
						end
					end
				end
			}
			list
		end
def precompile_optimize_inner ( list , step ) lastgoto = nil hadref = false walk = lambda { | expr | next if not expr . kind_of? CExpression if not expr . op and not expr . lexpr and expr . rexpr . kind_of? Label list << expr . rexpr . name else walk [ expr . lexpr ] if expr . rexpr . kind_of? :: Array expr . rexpr . each { | r | walk [ r ] } else walk [ expr . rexpr ] end end } @statements . dup . each { | s | lastgoto = nil if not s . kind_of? Label case s when Block s . precompile_optimize_inner ( list , step ) @statements . delete s if step == 2 and s . statements . empty? when CExpression ; walk [ s ] if step == 1 when Label case step when 1 if lastgoto and lastgoto . target == s . name list << lastgoto list . delete s . name if not hadref end when 2 ; @statements . delete s if not list . include? s . name end when Goto , If s . kind_of? ( If ) ? g = s . bthen : g = s case step when 1 hadref = list . include? g . target lastgoto = g list << g . target when 2 if list . include? g idx = @statements . index s @statements . delete s @statements [ idx , 0 ] = s . test if s != g and not s . test . constant? end end end } list end
step 1: list used labels/unused goto
step 2: remove unused labels
step 1 : list used labels / unused goto step 2 : remove unused labels
# gcc's unary && support
list
step