# HG changeset patch # User Jacob Carlborg # Date 1247056199 -7200 # Node ID c0cfd40362ee93d67a93db34896b6a10058c2883 # Parent 7a60c3c4d421def40077fb12b7dd813506b9581f Fixed the bridge to work with ldc and dmd. Added a couple of hooks to manipulate the source code diff -r 7a60c3c4d421 -r c0cfd40362ee dstep/objc/message.d --- a/dstep/objc/message.d Sun Jul 05 22:14:45 2009 +0200 +++ b/dstep/objc/message.d Wed Jul 08 14:29:59 2009 +0200 @@ -35,36 +35,51 @@ R msgSendSuper (R = id, ARGS...) (SEL op, ARGS args) { - return (cast(R function (id, SEL, ARGS...))&bindings.objc_msgSendSuper)(this, op, args); + alias extern (C) R function (id, SEL, ARGS) fp; + return (cast(fp)&bindings.objc_msgSendSuper)(this, op, args); } void msgSendSuper_stret (T, ARGS...) (out T stretAddr, id self, SEL op, ARGS args) { if (T.sizeof > STRUCT_SIZE_LIMIT) - (cast(void function (T*, id, SEL, ARGS...))&bindings.objc_msgSendSuper_stret)(&stretAddr, self, op, args); + { + alias extern (C) void function (T*, id, SEL, ARGS) fp; + (cast(fp)&bindings.objc_msgSendSuper_stret)(&stretAddr, self, op, args); + } else - stretAddr = (*cast(T function (id, SEL, ARGS...))&bindings.objc_msgSendSuper)(self, op, args); + { + alias extern (C) T function (id, SEL, ARGS) fp; + stretAddr = (*cast(fp)&bindings.objc_msgSendSuper)(self, op, args); + } } } R objc_msgSend (R = id, ARGS...) (id self, SEL op, ARGS args) { - return (cast(R function (id, SEL, ARGS...))&bindings.objc_msgSend)(self, op, args); + alias extern(C) R function (id, SEL, ARGS) fp; + return (cast(fp)&bindings.objc_msgSend)(self, op, args); } R objc_msgSendSuper (R = id, ARGS...) (objc_super* super_, SEL op, ARGS args) { - return (cast(R function (id, SEL, ARGS...))&bindings.objc_msgSendSuper)(super_, op, args); + alias extern(C) R function (objc_super*, SEL, ARGS) fp; + return (cast(fp)&bindings.objc_msgSendSuper)(super_, op, args); } void objc_msgSend_stret (T, ARGS...) (out T stretAddr, id self, SEL op, ARGS args) { if (T.sizeof > STRUCT_SIZE_LIMIT) - (cast(void function (T*, id, SEL, ARGS...))&bindings.objc_msgSend_stret)(&stretAddr, self, op, args); + { + alias extern(C) void function (T*, id, SEL, ARGS) fp; + (cast(void function (fp))&bindings.objc_msgSend_stret)(&stretAddr, self, op, args); + } else - stretAddr = (*cast(T function (id, SEL, ARGS...))&bindings.objc_msgSend)(self, op, args); + { + alias extern (C) T function (id, SEL, ARGS) fp; + stretAddr = (*cast(fp)&bindings.objc_msgSend)(self, op, args); + } } static if (X86 || X86_64) @@ -77,34 +92,44 @@ else static assert(!is(R : double) && !is(R : float), "Only double and float are legal return values for objc_msgSend_fpret"); - return (cast(R function (id, SEL, ARGS...))&bindings.objc_msgSend_fpret)(self, op, args); + alias extern (C) R function (id, SEL, ARGS) fp; + return (cast(fp)&bindings.objc_msgSend_fpret)(self, op, args); } } R method_invoke (R = id, ARGS...) (id receiver, Method m, ARGS args) { static assert(receiver !is null); - return (cast(R function (id, SEL, ARGS...))&bindings.method_invoke)(receiver, m, args); + alias extern (C) R function (id, SEL, ARGS) fp; + return (cast(fp)&bindings.method_invoke)(receiver, m, args); } void method_invoke_stret (ARGS...) (id receiver, Method m, ARGS args) { static assert(receiver !is null); - return (cast(R function (id, SEL, ARGS...))&bindings.method_invoke_stret)(receiver, m, args); + alias extern (C) R function (id, SEL, ARGS) fp; + return (cast(fp)&bindings.method_invoke_stret)(receiver, m, args); } R objc_msgSendv (R = id, T) (id self, SEL op, size_t arg_size, T arg_frame) { - (cast(R function (id, SEL, size_t, T))&bindings.objc_msgSendv)(self, op, arg_size, arg_frame); + alias extern (C) R function (id, SEL, size_t, T) fp; + (cast(fp)&bindings.objc_msgSendv)(self, op, arg_size, arg_frame); } void objc_msgSendv_stret (R = id, T) (out T stretAddr, id self, SEL op, size_t arg_size, T arg_frame) { if (R.sizeof > STRUCT_SIZE_LIMIT) - (cast(void function (R*, id, SEL, size_t, T))&bindings.objc_msgSendv_stret)(&stretAddr, self, op, arg_size, arg_frame); + { + alias extern (C) void function (R*, id, SEL, size_t, T) fp; + (cast(fp)&bindings.objc_msgSendv_stret)(&stretAddr, self, op, arg_size, arg_frame); + } else - stretAddr = (*cast(R function (id, SEL, size_t, T))&bindings.objc_msgSendv)(self, op, arg_size, arg_frame); + { + alias extern (C) R function (id, SEL, size_t, T) fp; + stretAddr = (*cast(fp)&bindings.objc_msgSendv)(self, op, arg_size, arg_frame); + } } version (X86) @@ -112,6 +137,7 @@ R objc_msgSendv_fpret (R = id, T) (id self, SEL op, uint arg_size, T arg_frame) { static assert(!is(R : double) && !is(R : float), "Only double and float are legal return values for objc_msgSendv_fpret"); - return (cast(R function (id, SEL, uint, T))&bindings.objc_msgSendv_fpret)(self, op, arg_size, arg_frame); + alias extern (C) R function (id, SEL, uint, T) fp; + return (cast(fp)&bindings.objc_msgSendv_fpret)(self, op, arg_size, arg_frame); } } \ No newline at end of file diff -r 7a60c3c4d421 -r c0cfd40362ee dstep/objc/objc.d --- a/dstep/objc/objc.d Sun Jul 05 22:14:45 2009 +0200 +++ b/dstep/objc/objc.d Wed Jul 08 14:29:59 2009 +0200 @@ -134,16 +134,23 @@ R msgSend (R = id, ARGS...) (SEL op, ARGS args) { - return (cast(R function (id, SEL, ARGS))&bindings.objc_msgSend)(this, op, args); + alias extern (C) R function (id, SEL, ARGS) fp; + return (cast(fp)&bindings.objc_msgSend)(this, op, args); } void msgSend_stret (T, ARGS...) (out T stretAddr, SEL op, ARGS args) { if (T.sizeof > STRUCT_SIZE_LIMIT) - (cast(void function (T*, id, SEL, ARGS...))&bindings.objc_msgSend_stret)(&stretAddr, this, op, args); + { + alias extern (C) void function (T*, id, SEL, ARGS...) fp; + (cast(fp)&bindings.objc_msgSend_stret)(&stretAddr, this, op, args); + } else - stretAddr = (*cast(T function (id, SEL, ARGS...))&bindings.objc_msgSend)(this, op, args); + { + alias extern (C) T function (id, SEL, ARGS) fp; + stretAddr = (*cast(fp)&bindings.objc_msgSend)(this, op, args); + } } static if (dstep.internal.Version.X86 || X86_64) @@ -156,32 +163,42 @@ else static assert(!is(R == double) && !is(R == float), "dstep.objc.objc.objc_object.msgSend_fpret: Only double and float are legal return values for objc_msgSend_fpret"); - return (cast(R function (id, SEL, ARGS...))&bindings.objc_msgSend_fpret)(this, op, args); + alias extern (C) R function (id, SEL, ARGS) fp; + return (cast(fp)&bindings.objc_msgSend_fpret)(this, op, args); } } R invoke (R = id, ARGS...) (Method m, ARGS args) { - return (cast(R function (id, SEL, ARGS...))&bindings.method_invoke)(this, m, args); + alias extern (C) R function (id, SEL, ARGS) fp; + return (cast(fp)&bindings.method_invoke)(this, m, args); } void invoke_stret (ARGS...) (Method m, ARGS args) { - return (cast(R function (id, SEL, ARGS...))&bindings.method_invoke_stret)(this, m, args); + alias extern (C) R function (id, SEL, ARGS) fp; + return (cast(fp)&bindings.method_invoke_stret)(this, m, args); } R msgSendv (R = id, T) (SEL op, size_t arg_size, T arg_frame) { - (cast(R function (id, SEL, size_t, T))&bindings.objc_msgSendv)(this, op, arg_size, arg_frame); + alias extern (C) R function (id, SEL, size_t, T) fp; + (cast(fp)&bindings.objc_msgSendv)(this, op, arg_size, arg_frame); } void msgSendv_stret (R = id, T) (out T stretAddr, SEL op, size_t arg_size, T arg_frame) { if (R.sizeof > STRUCT_SIZE_LIMIT) - (cast(void function (R*, id, SEL, size_t, T))&bindings.objc_msgSendv_stret)(&stretAddr, this, op, arg_size, arg_frame); + { + alias extern (C) void function (R*, id, SEL, size_t, T) fp; + (cast(fp)&bindings.objc_msgSendv_stret)(&stretAddr, this, op, arg_size, arg_frame); + } else - stretAddr = (*cast(R function (id, SEL, size_t, T))&bindings.objc_msgSendv)(this, op, arg_size, arg_frame); + { + alias extern (C) R function (id, SEL, size_t, T) fp; + stretAddr = (*cast(fp)&bindings.objc_msgSendv)(this, op, arg_size, arg_frame); + } } version (X86) @@ -189,7 +206,8 @@ R msgSendv_fpret (R = id, T) (SEL op, uint arg_size, T arg_frame) { static assert(!is(R == double) && !is(R == float), "dstep.objc.objc.objc_object.msgSend_fpret: Only double and float are legal return values for objc_msgSendv_fpret"); - return (cast(R function (id, SEL, uint, T))&bindings.objc_msgSendv_fpret)(this, op, arg_size, arg_frame); + alias extern (C) R function (id, SEL, uint, T) fp; + return (cast(fp)&bindings.objc_msgSendv_fpret)(this, op, arg_size, arg_frame); } } } diff -r 7a60c3c4d421 -r c0cfd40362ee scripts/dstepgen.rb --- a/scripts/dstepgen.rb Sun Jul 05 22:14:45 2009 +0200 +++ b/scripts/dstepgen.rb Wed Jul 08 14:29:59 2009 +0200 @@ -136,7 +136,7 @@ CPPFLAGS = "-D__APPLE_CPP__ -include /usr/include/AvailabilityMacros.h" CPPFLAGS << "-D__GNUC__" unless /\Acpp-4/.match(File.basename(CPP)) - attr_accessor :frameworks, :headers, :do_64bit + attr_accessor :frameworks, :headers, :do_64bit, :extra def initialize @extern_name = 'extern' @@ -488,28 +488,29 @@ end def structs (header) - re = /typedef\s+struct\s*\w*\s*((\w+)|\{([^{}]*(\{[^}]+\})?)*\}\s*([^\s]+))\s*(__attribute__\(.+\))?\s*;/ + re = /typedef\s+struct\s*\w*\s*((\w+)|\{([^{}]*(\{[^}]+\})?)*\}\s*([^\s]+))\s*(__attribute__\(.+\))?\s*,?(.+)?;/ i = 0 body = nil + @cpp_result.scan(re).each do |m| struct = { :name => m[4], :members => [] } - + unless struct[:name].nil? if struct[:name][0, 1] == "*" struct[:name].sub!("*", "") end end - + return_type = nil stripped_return_type = nil body = m[2] - + if m[2] m[2].split(/,|;/).map do |i| str, bytes = i.split(":", 2).map do |x| x.strip end - + var = get_var_info(str, true) if var @@ -520,7 +521,7 @@ return_type = var.return_type stripped_return_type = var.stripped_return_type end - + struct[:members] << { :name => var.name, :bytes => bytes, :declaredType => var.return_type, :type => "", :type64 => "" } unless str.empty? || str[0] == ?# names = [] @@ -531,12 +532,12 @@ member end end - + struct[:members] = tmp.compact end end end - + header.structs << struct if body end end @@ -909,7 +910,7 @@ VERSION = 1.0 - attr_accessor :out_file, :scaner, :code_to_inject, :dependencies_switch + attr_accessor :out_file, :scaner, :inject_path, :dependencies_switch, :options, :exclude def initialize @do_64bit = false @@ -926,6 +927,9 @@ @umbrella_framework = nil @handled_dependencies = [] @dependencies_switch = false + @options = [] + @extra = false + @exclude = [] # link to foundation framework by default @compiler_flags = "-framework Foundation" @@ -940,6 +944,15 @@ @scaner.do_64bit = do_64bit end + def extra + @extra + end + + def extra= (extra) + @extra = extra + @scaner.extra = extra + end + def collect scaner.scan(@frameworks, @headers) @classes = scaner.get_classes @@ -987,6 +1000,14 @@ header_basenames.unshift("#{name}.h") end + exclude = false + + @exclude.each do |e| + p e + p pnames + exclude = true if e =~ pname + end + if sub_framework pp = framework_path(parent_framework.name) tmp, pname = pp.scan(/^(.+)\/(\w+)\.framework\/?$/)[0] @@ -995,11 +1016,13 @@ @import_directives << header_basenames.map do |x| "#import <#{name}/#{x}>" end.join("\n") - end + end unless exclude + + exclude = false @import_directives << "\n" - @compiler_flags ||= "-F\"#{parent_path}\" -framework #{name}" + @compiler_flags << " -F\"#{parent_path}\" -framework #{name}" unless sub_framework?(framework.name) @cpp_flags ||= "" @cpp_flags << "-F\"#{parent_path}\" " @@ -1014,12 +1037,18 @@ # Memorize the dependencies. @dependencies = DStepGenerator.dependencies_of_framework(path) - handle_sub_frameworks(framework) end + def sub_framework? (framework) + i = framework.index("framework") + return false if i.nil? + !framework.index("framework", i + 1).nil? + end + def handle_sub_frameworks (framework) path = framework_path(framework.name) + @compiler_flags << " -B #{path}/Headers/ " frameworks_path = File.join(path, "Frameworks") frameworks = Dir.glob(File.join(frameworks_path, "*.framework")) @@ -1095,6 +1124,10 @@ bin = unique_tmp_path "bin", "" log = unique_tmp_path "log", ".txt" + @options.each do |option| + @compiler_flags << " #{option} " + end + line = "#{compiler_line} -o #{bin} #{src.path} #{@compiler_flags} 2>#{log}" unless system(line) @@ -1178,7 +1211,7 @@ value.args.each do |arg| types << arg.type - end + end unless value.args.nil? end types @@ -1299,7 +1332,7 @@ arg.resolved_type = resolved_types[i] unless enable_64bit arg.resolved_type64 = resolved_types[i] if enable_64bit i += 1 - end + end unless value.args.nil? end i @@ -1385,35 +1418,55 @@ i end + def get_framework_name (framework) + i = framework.rindex(".framework") + return framework if i.nil? + x = framework.rindex("/", i) + framework[x + 1 ... i] + end + def resolve_types (enable_64bit = false) - code = "#include \n" - code << "#import \n" - - # @dependencies.each do |f| - # # get the framework name - # i = f.index('.') - # str = f[0 ... i] - # i = str.rindex('/') - # str = str[i + 1 .. -1] - # - # code << "#import <#{str}/#{str}.h>\n" - # end - + code = "#include \n" code << @import_directives types = [] - code << @code_to_inject + "\n" unless @code_to_inject.nil? - - @frameworks.each do |framework| + @frameworks.each do |framework| framework.headers.each do |header| + exclude = false - header.imports do |import| - code << "#import <#{import}.h>\n" + @exclude.each do |e| + exclude = true if e =~ header.name end + if framework.name[0, 1] == "/" + code << "#import \"#{framework.name}/Headers/#{header.name}.h\"\n" unless header.name == "xmmintrin" + else + code << "#import <#{framework.name}/#{header.name}.h>\n" unless header.name == "xmmintrin" + end unless exclude + types << collect_header_types(header, enable_64bit) + + exclude = false end - end + end if @extra + + @headers.each do |header| + exclude = false + + @exclude.each do |e| + exclude = true if e =~ header.name + end + + code << "#import <#{header.name}.h>\n" unless exclude || header.name == "xmmintrin" + + exclude = false + end if @extra + + File.foreach(@inject_path) do |line| + code << line + end if !@inject_path.nil? && File.exist?(@inject_path) + + code << "\n\n" @headers.each do |header| types << collect_header_types(header, enable_64bit) @@ -1428,7 +1481,7 @@ types.flatten! types.each do |type| - code << ' printf("%s\n", ' + "@encode(#{type}));\n" + code << ' printf("%s\n", ' + "@encode(__typeof__(#{type})));\n" unless type.nil? || type.length == 0 end code << " return 0;\n}" @@ -1509,7 +1562,7 @@ xml.functionPointer :name => fp, :variadic => value.variadic do value.args.each do |arg| xml.arg :declaredType => arg.type, :type => arg.resolved_type, :type64 => arg.resolved_type64, :const => arg.const - end + end unless value.args.nil? xml.returnValue :declaredType => value.return_type, :type => value.resolved_type, :type64 => value.resolved_type64, :const => value.const end @@ -1662,14 +1715,26 @@ # dstep_gen.out_dir = opt # end - opts.on("-c", "--code CODE", "Add code") do |opt| - dstep_gen.code_to_inject = opt + opts.on("-c", "--code FILE", "The path to a file with code to inject") do |opt| + dstep_gen.inject_path = opt end opts.on("-d", "--dependencies", "Write framework dependencies and exit") do |opt| dstep_gen.dependencies_switch = true end + opts.on("-s", "--option OPTION", "Pass OPTION to the compiler") do |opt| + dstep_gen.options << opt + end + + opts.on("-e", "--extra", "Included extra headers headers") do |opt| + dstep_gen.extra = true + end + + opts.on("-x", "--exclude HEADER", "Exlude the given header file") do |opt| + dstep_gen.exclude << opt + end + help_msg = "Use the `-h' flag or for help." opts.on("-h", "--help", "Show this message.") do