summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ccode/valaccodefunction.vala3
-rw-r--r--ccode/valaccodemodifiers.vala3
-rw-r--r--codegen/valatyperegisterfunction.vala29
3 files changed, 31 insertions, 4 deletions
diff --git a/ccode/valaccodefunction.vala b/ccode/valaccodefunction.vala
index 688c6d1eb..7d29de9fd 100644
--- a/ccode/valaccodefunction.vala
+++ b/ccode/valaccodefunction.vala
@@ -111,6 +111,9 @@ public class Vala.CCodeFunction : CCodeNode {
if (CCodeModifiers.INTERNAL in modifiers) {
writer.write_string ("G_GNUC_INTERNAL ");
}
+ if (!is_declaration && CCodeModifiers.NO_INLINE in modifiers) {
+ writer.write_string ("G_GNUC_NO_INLINE ");
+ }
if (CCodeModifiers.STATIC in modifiers) {
writer.write_string ("static ");
}
diff --git a/ccode/valaccodemodifiers.vala b/ccode/valaccodemodifiers.vala
index 257423040..7b83b5a91 100644
--- a/ccode/valaccodemodifiers.vala
+++ b/ccode/valaccodemodifiers.vala
@@ -41,5 +41,6 @@ public enum Vala.CCodeModifiers {
DESTRUCTOR = 1 << 11,
FORMAT_ARG = 1 << 12,
PRINTF = 1 << 13,
- SCANF = 1 << 14
+ SCANF = 1 << 14,
+ NO_INLINE = 1 << 15
}
diff --git a/codegen/valatyperegisterfunction.vala b/codegen/valatyperegisterfunction.vala
index 23ab2321a..5a7b2cf73 100644
--- a/codegen/valatyperegisterfunction.vala
+++ b/codegen/valatyperegisterfunction.vala
@@ -45,6 +45,7 @@ public abstract class Vala.TypeRegisterFunction {
string type_id_name = "%s_type_id".printf (get_ccode_lower_case_name (type_symbol));
var type_block = new CCodeBlock ();
+ var type_once_block = new CCodeBlock ();
CCodeDeclaration cdecl;
if (!plugin) {
cdecl = new CCodeDeclaration ("gsize");
@@ -59,6 +60,7 @@ public abstract class Vala.TypeRegisterFunction {
}
CCodeFunction fun;
+ CCodeFunction fun_once = null;
if (!plugin) {
fun = new CCodeFunction (get_ccode_type_function (type_symbol), "GType");
fun.modifiers = CCodeModifiers.CONST;
@@ -75,6 +77,16 @@ public abstract class Vala.TypeRegisterFunction {
fun.is_declaration = true;
declaration_fragment.append (fun.copy ());
fun.is_declaration = false;
+
+ fun_once = new CCodeFunction ("%s_once".printf (fun.name), "GType");
+ fun_once.modifiers = CCodeModifiers.CONST | CCodeModifiers.STATIC;
+ if (context.require_glib_version (2, 58)) {
+ fun_once.modifiers |= CCodeModifiers.NO_INLINE;
+ }
+
+ fun_once.is_declaration = true;
+ source_declaration_fragment.append (fun_once.copy ());
+ fun_once.is_declaration = false;
} else {
fun = new CCodeFunction ("%s_register_type".printf (get_ccode_lower_case_name (type_symbol)), "GType");
fun.add_parameter (new CCodeParameter ("module", "GTypeModule *"));
@@ -194,10 +206,14 @@ public abstract class Vala.TypeRegisterFunction {
reg_call.add_argument (new CCodeConstant (get_type_flags ()));
}
+ var once_call_block = new CCodeBlock ();
if (!plugin) {
var temp_decl = new CCodeDeclaration ("GType");
temp_decl.add_declarator (new CCodeVariableDeclarator (type_id_name, reg_call));
type_init.add_statement (temp_decl);
+ temp_decl = new CCodeDeclaration ("GType");
+ temp_decl.add_declarator (new CCodeVariableDeclarator (type_id_name, new CCodeFunctionCall (new CCodeIdentifier (fun_once.name))));
+ once_call_block.add_statement (temp_decl);
} else {
type_init.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (type_id_name), reg_call)));
}
@@ -234,18 +250,25 @@ public abstract class Vala.TypeRegisterFunction {
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));
+ once_call_block.add_statement (new CCodeExpressionStatement (leave));
- var cif = new CCodeIfStatement (enter, type_init);
+ var cif = new CCodeIfStatement (enter, once_call_block);
type_block.add_statement (cif);
type_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier (type_id_name + "__volatile")));
+
+ type_once_block = type_init;
+ type_once_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier (type_id_name)));
} else {
type_block = type_init;
type_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier (type_id_name)));
}
- fun.block = type_block;
+ if (!plugin) {
+ fun_once.block = type_once_block;
+ definition_fragment.append (fun_once);
+ }
+ fun.block = type_block;
definition_fragment.append (fun);
}