node/lib/metasm/metasm/compile_c.rb
# dumps an anonymous variable definition, appending to the last line of source
# source.last is a label name or is empty before calling here
# return the length of the data written
dumps an anonymous variable definition, appending to the last line of source
source.last is a label name or is empty before calling here
return the length of the data written
dumps an anonymous variable definition appending to the last line of source source . last is a label name or is empty before calling here return the length of the data written
def c_idata_inner(type, value)
			case type
			when BaseType
				value ||= 0
				if type.name == :void
					@source.last << ':' if not @source.last.empty?
					return 0
				end
				@source.last <<
				case type.name
				when :__int8;  ' db '
				when :__int16; ' dw '
				when :__int32; ' dd '
				when :__int64; ' dq '
				when :ptr; " d#{%w[x b w x d x x x q][@parser.typesize[type.name]]} "
				when :float;   ' db ' + [value].pack(@parser.endianness == :little ? 'e' : 'g').unpack('C*').join(', ') + ' // '
				when :double;  ' db ' + [value].pack(@parser.endianness == :little ? 'E' : 'G').unpack('C*').join(', ') + ' // '
				when :longdouble; ' db ' + [value].pack(@parser.endianness == :little ? 'E' : 'G').unpack('C*').join(', ') + ' // '	
				else raise "unknown idata type #{type.inspect} #{value.inspect}"
				end
				@source.last << c_idata_inner_cexpr(value)
				@parser.typesize[type.name]
			when Struct
				value ||= []
				@source.last << ':' if not @source.last.empty?
				raise "unknown struct initializer #{value.inspect}" if not value.kind_of? ::Array
				sz = 0
				type.members.zip(value).each { |m, v|
					if m.name and wsz = type.offsetof(@parser, m.name) and sz < wsz
						@source << "db #{wsz-sz} dup(?)"
					end
					@source << ''
					flen = c_idata_inner(m.type, v)
					sz += flen
				}
				sz
			when Union
				value ||= []
				@source.last << ':' if not @source.last.empty?
				len = sizeof(nil, type)
				raise "unknown union initializer #{value.inspect}" if not value.kind_of? ::Array
				idx = value.rindex(value.compact.last) || 0
				raise "empty union initializer" if not idx
				wlen = c_idata_inner(type.members[idx].type, value[idx])
				@source << "db #{'0' * (len - wlen) * ', '}" if wlen < len
				len
			when Array
				value ||= []
				if value.kind_of? CExpression and not value.op and value.rexpr.kind_of? ::String
					elen = sizeof(nil, value.type.type)
					@source.last <<
					case elen
					when 1; ' db '
					when 2; ' dw '
					else raise 'bad char* type ' + value.inspect
					end << value.rexpr.inspect
					len = type.length || (value.rexpr.length+1)
					if len > value.rexpr.length
						@source.last << (', 0' * (len - value.rexpr.length))
					end
					elen * len
				elsif value.kind_of? ::Array
					@source.last << ':' if not @source.last.empty?
					len = type.length || value.length
					value.each { |v|
						@source << ''
						c_idata_inner(type.type, v)
					}
					len -= value.length
					if len > 0
						@source << " db #{len * sizeof(nil, type.type)} dup(0)"
					end
					sizeof(nil, type.type) * len
				else raise "unknown static array initializer #{value.inspect}"
				end
			end
		end
def c_idata_inner ( type , value ) case type when BaseType value ||= 0 if type . name == :void @source . last << ':' if not @source . last . empty? return 0 end @source . last << case type . name when :__int8 ; ' db ' when :__int16 ; ' dw ' when :__int32 ; ' dd ' when :__int64 ; ' dq ' when :ptr ; " d#{%w[x b w x d x x x q][@parser.typesize[type.name]]} " when :float ; ' db ' + [ value ] . pack ( @parser . endianness == :little ? 'e' : 'g' ) . unpack ( 'C*' ) . join ( ', ' ) + ' // ' when :double ; ' db ' + [ value ] . pack ( @parser . endianness == :little ? 'E' : 'G' ) . unpack ( 'C*' ) . join ( ', ' ) + ' // ' when :longdouble ; ' db ' + [ value ] . pack ( @parser . endianness == :little ? 'E' : 'G' ) . unpack ( 'C*' ) . join ( ', ' ) + ' // ' else raise "unknown idata type #{type.inspect} #{value.inspect}" end @source . last << c_idata_inner_cexpr ( value ) @parser . typesize [ type . name ] when Struct value ||= [ ] @source . last << ':' if not @source . last . empty? raise "unknown struct initializer #{value.inspect}" if not value . kind_of? :: Array sz = 0 type . members . zip ( value ) . each { | m , v | if m . name and wsz = type . offsetof ( @parser , m . name ) and sz < wsz @source << "db #{wsz-sz} dup(?)" end @source << '' flen = c_idata_inner ( m . type , v ) sz += flen } sz when Union value ||= [ ] @source . last << ':' if not @source . last . empty? len = sizeof ( nil , type ) raise "unknown union initializer #{value.inspect}" if not value . kind_of? :: Array idx = value . rindex ( value . compact . last ) || 0 raise "empty union initializer" if not idx wlen = c_idata_inner ( type . members [ idx ] . type , value [ idx ] ) @source << "db #{'0' * (len - wlen) * ', '}" if wlen < len len when Array value ||= [ ] if value . kind_of? CExpression and not value . op and value . rexpr . kind_of? :: String elen = sizeof ( nil , value . type . type ) @source . last << case elen when 1 ; ' db ' when 2 ; ' dw ' else raise 'bad char* type ' + value . inspect end << value . rexpr . inspect len = type . length || ( value . rexpr . length + 1 ) if len > value . rexpr . length @source . last << ( ', 0' * ( len - value . rexpr . length ) ) end elen * len elsif value . kind_of? :: Array @source . last << ':' if not @source . last . empty? len = type . length || value . length value . each { | v | @source << '' c_idata_inner ( type . type , v ) } len -= value . length if len > 0 @source << " db #{len * sizeof(nil, type.type)} dup(0)" end sizeof ( nil , type . type ) * len else raise "unknown static array initializer #{value.inspect}" end end end
dumps an anonymous variable definition, appending to the last line of source
source.last is a label name or is empty before calling here
return the length of the data written
dumps an anonymous variable definition appending to the last line of source source . last is a label name or is empty before calling here return the length of the data written
# XXX same as :double # could .align here, but if there is our label name just before, it should have been .aligned too..
type
value