From: Jürg Billeter Date: Sun, 10 Aug 2008 14:39:24 +0000 (+0000) Subject: Add --target-glib command-line option, default to 2.12, based on patch by X-Git-Tag: VALA_0_3_5~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8552a486802fe4c15d7abfaaf24fb72e66aec730;p=thirdparty%2Fvala.git Add --target-glib command-line option, default to 2.12, based on patch by 2008-08-10 Jürg Billeter * vala/valacodecontext.vala: * gobject/valaccodeclassbinding.vala: * gobject/valaccodeinterfacebinding.vala: * gobject/valaclassregisterfunction.vala: * gobject/valainterfaceregisterfunction.vala: * gobject/valatyperegisterfunction.vala: * compiler/valacompiler.vala: Add --target-glib command-line option, default to 2.12, based on patch by Jared Moore, fixes bug 544990 svn path=/trunk/; revision=1746 --- diff --git a/ChangeLog b/ChangeLog index a9a9c5c28..fd5b6ec79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2008-08-10 Jürg Billeter + + * vala/valacodecontext.vala: + * gobject/valaccodeclassbinding.vala: + * gobject/valaccodeinterfacebinding.vala: + * gobject/valaclassregisterfunction.vala: + * gobject/valainterfaceregisterfunction.vala: + * gobject/valatyperegisterfunction.vala: + * compiler/valacompiler.vala: + + Add --target-glib command-line option, default to 2.12, + based on patch by Jared Moore, fixes bug 544990 + 2008-08-10 Jürg Billeter * vala/valainterfacewriter.vala: diff --git a/compiler/valacompiler.vala b/compiler/valacompiler.vala index b806244e6..69da0b355 100644 --- a/compiler/valacompiler.vala +++ b/compiler/valacompiler.vala @@ -34,6 +34,7 @@ class Vala.Compiler : Object { static string library; [NoArrayLength ()] static string[] packages; + static string target_glib; static bool ccode_only; static bool compile_only; @@ -75,6 +76,7 @@ class Vala.Compiler : Object { { "Xcc", 'X', 0, OptionArg.STRING_ARRAY, ref cc_options, "Pass OPTION to the C compiler", "OPTION..." }, { "save-temps", 0, 0, OptionArg.NONE, ref save_temps, "Keep temporary files", null }, { "quiet", 'q', 0, OptionArg.NONE, ref quiet_mode, "Do not print messages to the console", null }, + { "target-glib", 0, 0, OptionArg.STRING, ref target_glib, "Target version of glib for code generation", "MAJOR.MINOR" }, { "", 0, 0, OptionArg.FILENAME_ARRAY, ref sources, null, "FILE..." }, { null } }; @@ -168,6 +170,18 @@ class Vala.Compiler : Object { context.thread = thread; context.save_temps = save_temps; + int glib_major = 2; + int glib_minor = 12; + if (target_glib != null && target_glib.scanf ("%d.%d", out glib_major, out glib_minor) != 2) { + Report.error (null, "Invalid format for --target-glib"); + } + + context.target_glib_major = glib_major; + context.target_glib_minor = glib_minor; + if (context.target_glib_major != 2) { + Report.error (null, "This version of valac only supports GLib 2"); + } + if (defines != null) { foreach (string define in defines) { context.add_define (define); diff --git a/gobject/valaccodeclassbinding.vala b/gobject/valaccodeclassbinding.vala index 63ec3e8c8..07248fbf2 100644 --- a/gobject/valaccodeclassbinding.vala +++ b/gobject/valaccodeclassbinding.vala @@ -179,7 +179,7 @@ public class Vala.CCodeClassBinding : CCodeObjectTypeSymbolBinding { } } - var type_fun = new ClassRegisterFunction (cl); + var type_fun = new ClassRegisterFunction (cl, codegen); type_fun.init_from_type (codegen.in_plugin); if (cl.access != SymbolAccessibility.PRIVATE) { codegen.header_type_member_declaration.append (type_fun.get_declaration ()); diff --git a/gobject/valaccodeinterfacebinding.vala b/gobject/valaccodeinterfacebinding.vala index 89f335911..1945cfcb5 100644 --- a/gobject/valaccodeinterfacebinding.vala +++ b/gobject/valaccodeinterfacebinding.vala @@ -87,7 +87,7 @@ public class Vala.CCodeInterfaceBinding : CCodeObjectTypeSymbolBinding { if (!iface.is_static) { add_interface_base_init_function (iface); - var type_fun = new InterfaceRegisterFunction (iface); + var type_fun = new InterfaceRegisterFunction (iface, codegen); type_fun.init_from_type (); if (iface.access != SymbolAccessibility.PRIVATE) { codegen.header_type_member_declaration.append (type_fun.get_declaration ()); diff --git a/gobject/valaclassregisterfunction.vala b/gobject/valaclassregisterfunction.vala index 5e97b8044..7c6d84daf 100644 --- a/gobject/valaclassregisterfunction.vala +++ b/gobject/valaclassregisterfunction.vala @@ -37,8 +37,9 @@ public class Vala.ClassRegisterFunction : TypeRegisterFunction { * @param cl a class * @return newly created class register function */ - public ClassRegisterFunction (Class cl) { + public ClassRegisterFunction (Class cl, CCodeGenerator codegen) { class_reference = cl; + this.codegen = codegen; } public override TypeSymbol get_type_declaration () { @@ -119,7 +120,7 @@ public class Vala.ClassRegisterFunction : TypeRegisterFunction { var iface_info_name = "%s_info".printf (iface.get_lower_case_cname (null)); var reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_add_interface_static")); - reg_call.add_argument (new CCodeIdentifier ("%s_type_id_temp".printf (class_reference.get_lower_case_cname (null)))); + reg_call.add_argument (new CCodeIdentifier ("%s_type_id".printf (class_reference.get_lower_case_cname (null)))); reg_call.add_argument (new CCodeIdentifier (iface.get_type_id ())); reg_call.add_argument (new CCodeIdentifier ("&%s".printf (iface_info_name))); frag.append (new CCodeExpressionStatement (reg_call)); diff --git a/gobject/valainterfaceregisterfunction.vala b/gobject/valainterfaceregisterfunction.vala index b56d14147..9b66fa1ae 100644 --- a/gobject/valainterfaceregisterfunction.vala +++ b/gobject/valainterfaceregisterfunction.vala @@ -32,8 +32,9 @@ public class Vala.InterfaceRegisterFunction : TypeRegisterFunction { */ public weak Interface interface_reference { get; set; } - public InterfaceRegisterFunction (Interface iface) { + public InterfaceRegisterFunction (Interface iface, CCodeGenerator codegen) { interface_reference = iface; + this.codegen = codegen; } public override TypeSymbol get_type_declaration () { @@ -76,7 +77,7 @@ public class Vala.InterfaceRegisterFunction : TypeRegisterFunction { var prereq = prereq_ref.data_type; var func = new CCodeFunctionCall (new CCodeIdentifier ("g_type_interface_add_prerequisite")); - func.add_argument (new CCodeIdentifier ("%s_type_id_temp".printf (interface_reference.get_lower_case_cname (null)))); + func.add_argument (new CCodeIdentifier ("%s_type_id".printf (interface_reference.get_lower_case_cname (null)))); func.add_argument (new CCodeIdentifier (prereq.get_type_id())); frag.append (new CCodeExpressionStatement (func)); diff --git a/gobject/valatyperegisterfunction.vala b/gobject/valatyperegisterfunction.vala index 7e627dd87..f2337d0d1 100644 --- a/gobject/valatyperegisterfunction.vala +++ b/gobject/valatyperegisterfunction.vala @@ -30,10 +30,14 @@ public abstract class Vala.TypeRegisterFunction : Object { private CCodeFragment definition_fragment = new CCodeFragment (); + public CCodeGenerator codegen { get; set; } + /** * Constructs the C function from the specified type. */ public void init_from_type (bool plugin = false) { + bool use_thread_safe = codegen.context.require_glib_version (2, 14); + bool fundamental = false; Class cl = get_type_declaration () as Class; if (cl != null && !cl.is_compact && cl.base_class == null) { @@ -43,9 +47,18 @@ public abstract class Vala.TypeRegisterFunction : Object { string type_id_name = "%s_type_id".printf (get_type_declaration ().get_lower_case_cname (null)); var type_block = new CCodeBlock (); - var cdecl = new CCodeDeclaration ("gsize"); - cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (type_id_name, new CCodeConstant ("0"))); - cdecl.modifiers = CCodeModifiers.STATIC | CCodeModifiers.VOLATILE; + CCodeDeclaration cdecl; + if (use_thread_safe) { + cdecl = new CCodeDeclaration ("gsize"); + cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (type_id_name + "__volatile", new CCodeConstant ("0"))); + } else { + cdecl = new CCodeDeclaration ("GType"); + cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (type_id_name, new CCodeConstant ("0"))); + } + cdecl.modifiers = CCodeModifiers.STATIC; + if (use_thread_safe) { + cdecl.modifiers |= CCodeModifiers.VOLATILE; + } if (!plugin) { type_block.add_statement (cdecl); } else { @@ -111,10 +124,9 @@ public abstract class Vala.TypeRegisterFunction : Object { } reg_call.add_argument (new CCodeConstant (get_type_flags ())); - string temp_type_id_name = "%s_type_id_temp".printf (get_type_declaration ().get_lower_case_cname (null)); - if (!plugin) { + if (use_thread_safe && !plugin) { var temp_decl = new CCodeDeclaration ("GType"); - temp_decl.add_declarator (new CCodeVariableDeclarator.with_initializer (temp_type_id_name, reg_call)); + temp_decl.add_declarator (new CCodeVariableDeclarator.with_initializer (type_id_name, reg_call)); type_init.add_statement (temp_decl); } else { type_init.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (type_id_name), reg_call))); @@ -123,19 +135,33 @@ public abstract class Vala.TypeRegisterFunction : Object { type_init.add_statement (get_type_interface_init_statements ()); if (!plugin) { - var enter = new CCodeFunctionCall (new CCodeIdentifier ("g_once_init_enter")); - enter.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (type_id_name))); - var leave = new CCodeFunctionCall (new CCodeIdentifier ("g_once_init_leave")); - leave.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (type_id_name))); - leave.add_argument (new CCodeIdentifier (temp_type_id_name)); - type_init.add_statement (new CCodeExpressionStatement (leave)); - var cif = new CCodeIfStatement (enter, type_init); + CCodeExpression condition; // the condition that guards the type initialisation + if (use_thread_safe) { + var enter = new CCodeFunctionCall (new CCodeIdentifier ("g_once_init_enter")); + enter.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (type_id_name + "__volatile"))); + condition = enter; + + var leave = new CCodeFunctionCall (new CCodeIdentifier ("g_once_init_leave")); + leave.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (type_id_name + "__volatile"))); + leave.add_argument (new CCodeIdentifier (type_id_name)); + type_init.add_statement (new CCodeExpressionStatement (leave)); + } else { + var id = new CCodeIdentifier (type_id_name); + var zero = new CCodeConstant ("0"); + condition = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, id, zero); + } + + var cif = new CCodeIfStatement (condition, type_init); type_block.add_statement (cif); } else { type_block = type_init; } - type_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier (type_id_name))); + if (use_thread_safe) { + type_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier (type_id_name + "__volatile"))); + } else { + type_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier (type_id_name))); + } declaration_fragment.append (fun.copy ()); diff --git a/vala/valacodecontext.vala b/vala/valacodecontext.vala index f3f563f36..c8c3fad75 100644 --- a/vala/valacodecontext.vala +++ b/vala/valacodecontext.vala @@ -110,6 +110,24 @@ public class Vala.CodeContext : Object { */ public bool save_temps { get; set; } + /** + * Target major version number of glib for code generation. + */ + public int target_glib_major { get; set; } + + /** + * Target minor version number of glib for code generation. + */ + public int target_glib_minor { get; set; } + + /** + * Returns true if the target version of glib is greater than or + * equal to the specified version. + */ + public bool require_glib_version (int major, int minor) { + return (target_glib_major > major) || (target_glib_major == major && target_glib_minor >= minor); + } + public bool save_csources { get { return save_temps; } }