node/lib/metasm/metasm/decompile.rb
# reorder statements to put decl first, move assignments to decl, move args to func prototype
reorder statements to put decl first, move assignments to decl, move args to func prototype
reorder statements to put decl first move assignments to decl move args to func prototype
def cleanup_var_decl(scope, func)
		scope.symbol.each_value { |v| v.type = C::BaseType.new(:int) if v.type.void? }
		args = func.type.args
		decl = []
		scope.statements.delete_if { |sm|
			next if not sm.kind_of? C::Declaration
			if sm.var.stackoff.to_i > 0 and sm.var.name !~ /_a(\d+)$/	
				args << sm.var
			else
				decl << sm
			end
			true
		}
		go = true	
		scope.statements.delete_if { |st|
			if go and st.kind_of? C::CExpression and st.op == :'=' and st.rexpr.kind_of? C::CExpression and not st.rexpr.op and
					st.rexpr.rexpr.kind_of? ::Integer and st.lexpr.kind_of? C::Variable and scope.symbol[st.lexpr.name]
				st.lexpr.initializer = st.rexpr
			else
				go = false
			end
		}
		scope.statements[0, 0] = decl.sort_by { |sm| [-sm.var.stackoff.to_i, sm.var.name] }
		func.type.args = []
		argoff = @c_parser.typesize[:ptr]
		args.sort_by { |sm| sm.stackoff.to_i }.each { |a|
			if not curoff = a.stackoff
				func.type.args << a	
				next
			end
			while curoff > argoff
				wantarg = C::Variable.new
				wantarg.name = scope.decompdata[:stackoff_name][argoff] || stackoff_to_varname(argoff)
				wantarg.type = C::BaseType.new(:int)
				wantarg.attributes = ['unused']
				func.type.args << wantarg
				scope.symbol[wantarg.name] = wantarg
				argoff += @c_parser.typesize[:ptr]
			end
			func.type.args << a
			argoff += @c_parser.typesize[:ptr]
		}
	end
def cleanup_var_decl ( scope , func ) scope . symbol . each_value { | v | v . type = C :: BaseType . new ( :int ) if v . type . void? } args = func . type . args decl = [ ] scope . statements . delete_if { | sm | next if not sm . kind_of? C :: Declaration if sm . var . stackoff . to_i > 0 and sm . var . name !~ / _a( \d +)$ / args << sm . var else decl << sm end true } go = true scope . statements . delete_if { | st | if go and st . kind_of? C :: CExpression and st . op == :' = ' and st . rexpr . kind_of? C :: CExpression and not st . rexpr . op and st . rexpr . rexpr . kind_of? :: Integer and st . lexpr . kind_of? C :: Variable and scope . symbol [ st . lexpr . name ] st . lexpr . initializer = st . rexpr else go = false end } scope . statements [ 0 , 0 ] = decl . sort_by { | sm | [ - sm . var . stackoff . to_i , sm . var . name ] } func . type . args = [ ] argoff = @c_parser . typesize [ :ptr ] args . sort_by { | sm | sm . stackoff . to_i } . each { | a | if not curoff = a . stackoff func . type . args << a next end while curoff > argoff wantarg = C :: Variable . new wantarg . name = scope . decompdata [ :stackoff_name ] [ argoff ] || stackoff_to_varname ( argoff ) wantarg . type = C :: BaseType . new ( :int ) wantarg . attributes = [ 'unused' ] func . type . args << wantarg scope . symbol [ wantarg . name ] = wantarg argoff += @c_parser . typesize [ :ptr ] end func . type . args << a argoff += @c_parser . typesize [ :ptr ] } end
reorder statements to put decl first, move assignments to decl, move args to func prototype
reorder statements to put decl first move assignments to decl move args to func prototype
# aliased vars: use 1st domain only # move trivial affectations to initialiser # XXX a = 1 ; b = a ; a = 2 # break from delete_if does not delete.. # reorder declarations # ensure arglist has no hole (create&add unreferenced args) # XXX misalignment ? # __fastcall
scope
func