From 66421c36a3b112167b001c821b81a1e97c9c5bf0 Mon Sep 17 00:00:00 2001 From: Artur Skawina Date: Thu, 26 Jan 2012 19:44:28 +0100 Subject: [PATCH] Experimental GTK structs-as-references support. Not enabled by default. This is still missing methods-with-ref-args. Adding them w/o switching to using reference types is too dangerous, and not really an improvement as long as we have to work with pointers. The reason for not switching right now is GDC -- currently it does not return small structs (in our case just a pointer) in registers, making the GTK constructors more expensive than they need to be. Maybe this feature can be enabled anyway, but for now let's wait. Turning this on is backwards compatible (does not require any changes in applications, as the ref structs implicitly convert to pointers); turning if off *would* break apps. --- girtod.d | 40 +++++++++++++++++++++++++++++++++++----- mixin/GLib2__MODULE_HEAD.d | 18 ++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/girtod.d b/girtod.d index 18e04bd..e1d8e44 100644 --- a/girtod.d +++ b/girtod.d @@ -28,7 +28,7 @@ enum PACKAGE_NAME = "gtk2"; // as simple as possible (eg not using absolute module names can result // in problems, either in the module files or apps that import them in // various ways. -// - The original mixed-caps names should be used in the modules. +// - The original mixed-caps module names should be used in the modules. string[] cprotos; // All seen functions and C "methods". @@ -747,7 +747,7 @@ final class x_function : x_elem { } } - r ~= ");"; + r ~= ")"; return r; } @@ -755,6 +755,7 @@ final class x_function : x_elem { string Drettype = Dtype(rettype, crettype); string r = comment_to_D() ~ indent; bool hasthis = 0; + bool refret; // Ugh. Turning off -ffunction-sections causes link failures // because if this missing glib function. @@ -880,6 +881,20 @@ final class x_function : x_elem { goto add_cproto; } + bool hasUpperCase(string s) { + import std.uni; + foreach(c; s) + if (isUpper(c)) + return 1; + return 0; + } + + string refDrettype = Drettype; + if (reftypes && Drettype[$-1]=='*' && hasUpperCase(Drettype)) { + refDrettype = Drettype[0..$-1]; + refret = 1; + } + if (is_funcp) r ~= "extern (C) "; if (tagname=="callback") @@ -887,7 +902,12 @@ final class x_function : x_elem { if (tagname=="constructor" || tagname=="function") r ~= "static "; - r ~= Drettype ~ " " ~ retanno; + if (refret) + r ~= "Ref!(" ~ refDrettype ~ ")"; + else + r ~= Drettype; + + r ~= " " ~ retanno; if (is_funcp) r ~= "function ("; @@ -926,19 +946,25 @@ final class x_function : x_elem { if (Drettype!="void") r ~= "return "; + + if (refret) + r ~= "Ref!(" ~ refDrettype ~ ")("; string oname; if (hasthis) { oname = allargs[0].name; allargs[0].name = "&this"; } - r ~= c_func(0, 0, allargs) ~ "\n" ~ --indent ~ "}\n"; + r ~= c_func(0, 0, allargs); + if (refret) + r ~= ")"; + r ~= ";\n" ~ --indent ~ "}\n"; if (hasthis) allargs[0].name = oname; add_cproto: if (!is_funcp /*&& tagname=="function" || obj*/) - cprotos ~= Drettype ~ " " ~ retanno ~ c_func(1, 0, allargs); + cprotos ~= Drettype ~ " " ~ retanno ~ c_func(1, 0, allargs) ~ ";"; return r; } @@ -1355,6 +1381,8 @@ string load_mixin(string id) { return r; } +bool reftypes = 0; + void main(string[] args) { string infilename, outfilename, modulename; bool xmlcheck; @@ -1387,6 +1415,8 @@ debug(TRACE) { } case "trace-mixins": tracemixins = 1; break; case "check": xmlcheck = 1; break; + case "reftypes": reftypes = 1; break; + case "no-reftypes": reftypes = 0; break; default: die("Unknown long cmdline option: " ~ arg); } break; diff --git a/mixin/GLib2__MODULE_HEAD.d b/mixin/GLib2__MODULE_HEAD.d index a632956..a9cbbe8 100644 --- a/mixin/GLib2__MODULE_HEAD.d +++ b/mixin/GLib2__MODULE_HEAD.d @@ -7,3 +7,21 @@ import std.c.stdarg : va_list; import std.c.stdio : FILE; alias int gboolean; + + +// A wrapper that makes type behave like a reference type. + +struct Ref(S) { + S* __refpointer; + + alias __refpointer this; + + this(S:S)(ref S s) { __refpointer = &s; } + this(SP:S*)(SP s) { __refpointer = s; } + this(A...)(A s) { __refpointer = new S(s); } + + void toString(FT)(scope void delegate(const(char)[]) sink, FT fmt) { + import std.format; + formatValue(sink, *__refpointer, fmt); + } +} -- 2.11.4.GIT