[vala] Support locks with static fields
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Subject: [vala] Support locks with static fields
- Date: Mon, 27 Jul 2009 21:12:54 +0000 (UTC)
commit 0154b1a6909c76d41b47a6dca011d078da316c14
Author: Levi Bard <taktaktaktaktaktaktaktaktaktak gmail com>
Date: Mon Jul 27 23:11:30 2009 +0200
Support locks with static fields
Fixes bug 537461.
codegen/valaccodebasemodule.vala | 62 +++++++++++++++++++++++++++++-------
codegen/valagtypemodule.vala | 65 ++++++++++++++++++++++---------------
tests/objects/fields.test | 16 +++++++--
vala/valamemberaccess.vala | 20 +-----------
vala/valasymbol.vala | 44 +++++++++++++++++++++++++
5 files changed, 146 insertions(+), 61 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index bc6adf4..14b35f3 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -747,16 +747,29 @@ internal class Vala.CCodeBaseModule : CCodeModule {
/* stuff meant for all lockable members */
if (m is Lockable && ((Lockable) m).get_lock_used ()) {
CCodeExpression l = new CCodeIdentifier ("self");
- l = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (l, "priv"), get_symbol_lock_name (m));
+ CCodeFragment init_fragment = class_init_fragment;
+ CCodeFragment finalize_fragment = class_finalize_fragment;
+
+ if (m.is_instance_member ()) {
+ l = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (l, "priv"), get_symbol_lock_name (m.name));
+ init_fragment = instance_init_fragment;
+ finalize_fragment = instance_finalize_fragment;
+ } else if (m.is_class_member ()) {
+ TypeSymbol parent = (TypeSymbol)m.parent_symbol;
+ l = new CCodeIdentifier ("%s_GET_CLASS_PRIVATE(%s)".printf(parent.get_upper_case_cname (), parent.get_type_id ()));
+ l = new CCodeMemberAccess.pointer (l, get_symbol_lock_name (m.name));
+ } else {
+ l = new CCodeIdentifier (get_symbol_lock_name ("%s_%s".printf(m.parent_symbol.get_lower_case_cname (), m.name)));
+ }
var initf = new CCodeFunctionCall (new CCodeIdentifier (mutex_type.default_construction_method.get_cname ()));
initf.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, l));
- instance_init_fragment.append (new CCodeExpressionStatement (initf));
+ init_fragment.append (new CCodeExpressionStatement (initf));
- if (instance_finalize_fragment != null) {
+ if (finalize_fragment != null) {
var fc = new CCodeFunctionCall (new CCodeIdentifier ("g_static_rec_mutex_free"));
fc.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, l));
- instance_finalize_fragment.append (new CCodeExpressionStatement (fc));
+ finalize_fragment.append (new CCodeExpressionStatement (fc));
}
}
}
@@ -816,6 +829,20 @@ internal class Vala.CCodeBaseModule : CCodeModule {
}
decl_space.add_type_member_declaration (cdecl);
+ if (f.get_lock_used ()) {
+ // Declare mutex for static member
+ var flock = new CCodeDeclaration (mutex_type.get_cname ());
+ var flock_decl = new CCodeVariableDeclarator (get_symbol_lock_name (f.get_cname ()), new CCodeConstant ("{0}"));
+ flock.add_declarator (flock_decl);
+
+ if (f.is_private_symbol ()) {
+ flock.modifiers = CCodeModifiers.STATIC;
+ } else {
+ flock.modifiers = CCodeModifiers.EXTERN;
+ }
+ decl_space.add_type_member_declaration (flock);
+ }
+
if (f.field_type is ArrayType && !f.no_array_length) {
var array_type = (ArrayType) f.field_type;
@@ -2494,8 +2521,8 @@ internal class Vala.CCodeBaseModule : CCodeModule {
}
}
- public string get_symbol_lock_name (Symbol sym) {
- return "__lock_%s".printf (sym.name);
+ public string get_symbol_lock_name (string symname) {
+ return "__lock_%s".printf (symname);
}
public override void visit_lock_statement (LockStatement stmt) {
@@ -2503,15 +2530,26 @@ internal class Vala.CCodeBaseModule : CCodeModule {
CCodeExpression l = null;
CCodeFunctionCall fc;
var inner_node = ((MemberAccess)stmt.resource).inner;
+ var member = (Member)stmt.resource.symbol_reference;
+ var parent = (TypeSymbol) stmt.resource.symbol_reference.parent_symbol;
- if (inner_node == null) {
- l = new CCodeIdentifier ("self");
- } else if (stmt.resource.symbol_reference.parent_symbol != current_type_symbol) {
- l = new InstanceCast ((CCodeExpression) inner_node.ccodenode, (TypeSymbol) stmt.resource.symbol_reference.parent_symbol);
+ if (member.is_instance_member ()) {
+ if (inner_node == null) {
+ l = new CCodeIdentifier ("self");
+ } else if (stmt.resource.symbol_reference.parent_symbol != current_type_symbol) {
+ l = new InstanceCast ((CCodeExpression) inner_node.ccodenode, parent);
+ } else {
+ l = (CCodeExpression) inner_node.ccodenode;
+ }
+
+ l = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (l, "priv"), get_symbol_lock_name (stmt.resource.symbol_reference.name));
+ } else if (member.is_class_member ()) {
+ l = new CCodeIdentifier ("%s_GET_CLASS_PRIVATE(%s)".printf(parent.get_upper_case_cname (), parent.get_type_id ()));
+ l = new CCodeMemberAccess.pointer (l, get_symbol_lock_name (stmt.resource.symbol_reference.name));
} else {
- l = (CCodeExpression) inner_node.ccodenode;
+ string lock_name = "%s_%s".printf(parent.get_lower_case_cname (), stmt.resource.symbol_reference.name);
+ l = new CCodeIdentifier (get_symbol_lock_name (lock_name));
}
- l = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (l, "priv"), get_symbol_lock_name (stmt.resource.symbol_reference));
fc = new CCodeFunctionCall (new CCodeIdentifier (((Method) mutex_type.scope.lookup ("lock")).get_cname ()));
fc.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, l));
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index 7ac0ed2..e5bf70e 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -271,31 +271,33 @@ internal class Vala.GTypeModule : GErrorModule {
field_ctype = "volatile " + field_ctype;
}
- if (f.binding == MemberBinding.INSTANCE && f.access != SymbolAccessibility.PRIVATE) {
- generate_type_declaration (f.field_type, decl_space);
+ if (f.access != SymbolAccessibility.PRIVATE) {
+ if (f.binding == MemberBinding.INSTANCE) {
+ generate_type_declaration (f.field_type, decl_space);
- instance_struct.add_field (field_ctype, f.get_cname ());
- if (f.field_type is ArrayType && !f.no_array_length) {
- // create fields to store array dimensions
- var array_type = (ArrayType) f.field_type;
- var len_type = int_type.copy ();
+ instance_struct.add_field (field_ctype, f.get_cname ());
+ if (f.field_type is ArrayType && !f.no_array_length) {
+ // create fields to store array dimensions
+ var array_type = (ArrayType) f.field_type;
+ var len_type = int_type.copy ();
- for (int dim = 1; dim <= array_type.rank; dim++) {
- instance_struct.add_field (len_type.get_cname (), head.get_array_length_cname (f.name, dim));
- }
+ for (int dim = 1; dim <= array_type.rank; dim++) {
+ instance_struct.add_field (len_type.get_cname (), head.get_array_length_cname (f.name, dim));
+ }
- if (array_type.rank == 1 && f.is_internal_symbol ()) {
- instance_struct.add_field (len_type.get_cname (), head.get_array_size_cname (f.name));
- }
- } else if (f.field_type is DelegateType) {
- var delegate_type = (DelegateType) f.field_type;
- if (delegate_type.delegate_symbol.has_target) {
- // create field to store delegate target
- instance_struct.add_field ("gpointer", get_delegate_target_cname (f.name));
+ if (array_type.rank == 1 && f.is_internal_symbol ()) {
+ instance_struct.add_field (len_type.get_cname (), head.get_array_size_cname (f.name));
+ }
+ } else if (f.field_type is DelegateType) {
+ var delegate_type = (DelegateType) f.field_type;
+ if (delegate_type.delegate_symbol.has_target) {
+ // create field to store delegate target
+ instance_struct.add_field ("gpointer", get_delegate_target_cname (f.name));
+ }
}
+ } else if (f.binding == MemberBinding.CLASS) {
+ type_struct.add_field (field_ctype, f.get_cname ());
}
- } else if (f.binding == MemberBinding.CLASS && f.access != SymbolAccessibility.PRIVATE) {
- type_struct.add_field (field_ctype, f.get_cname ());
}
}
@@ -331,6 +333,8 @@ internal class Vala.GTypeModule : GErrorModule {
}
bool is_gtypeinstance = !cl.is_compact;
+ bool has_instance_locks = false;
+ bool has_class_locks = false;
var instance_priv_struct = new CCodeStruct ("_%sPrivate".printf (cl.get_cname ()));
var type_priv_struct = new CCodeStruct ("_%sClassPrivate".printf (cl.get_cname ()));
@@ -384,16 +388,25 @@ internal class Vala.GTypeModule : GErrorModule {
}
if (f.get_lock_used ()) {
+ has_instance_locks = true;
+ // add field for mutex
+ instance_priv_struct.add_field (mutex_type.get_cname (), get_symbol_lock_name (f.name));
+ }
+ } else if (f.binding == MemberBinding.CLASS) {
+ if (f.access == SymbolAccessibility.PRIVATE) {
+ type_priv_struct.add_field (field_ctype, f.get_cname ());
+ }
+
+ if (f.get_lock_used ()) {
+ has_class_locks = true;
// add field for mutex
- instance_priv_struct.add_field (mutex_type.get_cname (), get_symbol_lock_name (f));
+ type_priv_struct.add_field (mutex_type.get_cname (), get_symbol_lock_name (f.get_cname ()));
}
- } else if (f.binding == MemberBinding.CLASS && f.access == SymbolAccessibility.PRIVATE) {
- type_priv_struct.add_field (field_ctype, f.get_cname ());
}
}
if (is_gtypeinstance) {
- if (cl.has_class_private_fields) {
+ if (cl.has_class_private_fields || has_class_locks) {
decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (type_priv_struct.name), new CCodeVariableDeclarator ("%sClassPrivate".printf (cl.get_cname ()))));
var cdecl = new CCodeDeclaration ("GQuark");
cdecl.add_declarator (new CCodeVariableDeclarator ("_vala_%s_class_private_quark".printf (cl.get_lower_case_cname ()), new CCodeConstant ("0")));
@@ -402,13 +415,13 @@ internal class Vala.GTypeModule : GErrorModule {
}
/* only add the *Private struct if it is not empty, i.e. we actually have private data */
- if (cl.has_private_fields || cl.get_type_parameters ().size > 0) {
+ if (cl.has_private_fields || cl.get_type_parameters ().size > 0 || has_instance_locks) {
decl_space.add_type_definition (instance_priv_struct);
var macro = "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl.get_type_id (), cl.get_cname ());
decl_space.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (cl.get_upper_case_cname (null)), macro));
}
- if (cl.has_class_private_fields) {
+ if (cl.has_class_private_fields || has_class_locks) {
decl_space.add_type_member_declaration (type_priv_struct);
var macro = "((%sClassPrivate *) g_type_get_qdata (type, _vala_%s_class_private_quark))".printf (cl.get_cname(), cl.get_lower_case_cname ());
diff --git a/tests/objects/fields.test b/tests/objects/fields.test
index f347fbb..7690b6e 100644
--- a/tests/objects/fields.test
+++ b/tests/objects/fields.test
@@ -35,10 +35,18 @@ class Maman.Bar : Foo {
public_base_field = 9;
public_field = 10;
private_field = 11;
- private_static_field = 12;
- public_static_field = 13;
- private_class_field = 14;
- public_class_field = 15;
+ lock (private_static_field) {
+ private_static_field = 12;
+ }
+ lock (public_static_field) {
+ public_static_field = 13;
+ }
+ lock (private_class_field) {
+ private_class_field = 14;
+ }
+ lock (public_class_field) {
+ public_class_field = 15;
+ }
stdout.printf (" %d %d %d %d %d %d %d", public_base_field, public_field,
private_field, private_static_field, public_static_field,
private_class_field, public_class_field);
diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala
index aa44c1e..3ce7399 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -133,25 +133,7 @@ public class Vala.MemberAccess : Expression {
}
public override string to_string () {
- bool instance = true;
- if (symbol_reference is Field) {
- var f = (Field) symbol_reference;
- instance = (f.binding == MemberBinding.INSTANCE);
- } else if (symbol_reference is Method) {
- var m = (Method) symbol_reference;
- if (!(m is CreationMethod)) {
- instance = (m.binding == MemberBinding.INSTANCE);
- }
- } else if (symbol_reference is Property) {
- var prop = (Property) symbol_reference;
- instance = (prop.binding == MemberBinding.INSTANCE);
- } else if (symbol_reference is EnumValue) {
- instance = false;
- } else if (symbol_reference is ErrorCode) {
- instance = false;
- }
-
- if (instance) {
+ if (symbol_reference.is_instance_member ()) {
if (inner == null) {
return member_name;
} else {
diff --git a/vala/valasymbol.vala b/vala/valasymbol.vala
index 61a1c0a..ca54bd6 100644
--- a/vala/valasymbol.vala
+++ b/vala/valasymbol.vala
@@ -313,6 +313,50 @@ public abstract class Vala.Symbol : CodeNode {
// if this is a public symbol, it's equally accessible as the parent symbol
return parent_symbol.get_top_accessible_scope (is_internal);
}
+
+ public virtual bool is_instance_member () {
+ bool instance = true;
+ if (this is Field) {
+ var f = (Field) this;
+ instance = (f.binding == MemberBinding.INSTANCE);
+ } else if (this is Method) {
+ var m = (Method) this;
+ if (!(m is CreationMethod)) {
+ instance = (m.binding == MemberBinding.INSTANCE);
+ }
+ } else if (this is Property) {
+ var prop = (Property) this;
+ instance = (prop.binding == MemberBinding.INSTANCE);
+ } else if (this is EnumValue) {
+ instance = false;
+ } else if (this is ErrorCode) {
+ instance = false;
+ }
+
+ return instance;
+ }
+
+ public virtual bool is_class_member () {
+ bool isclass = true;
+ if (this is Field) {
+ var f = (Field) this;
+ isclass = (f.binding == MemberBinding.CLASS);
+ } else if (this is Method) {
+ var m = (Method) this;
+ if (!(m is CreationMethod)) {
+ isclass = (m.binding == MemberBinding.CLASS);
+ }
+ } else if (this is Property) {
+ var prop = (Property) this;
+ isclass = (prop.binding == MemberBinding.CLASS);
+ } else if (this is EnumValue) {
+ isclass = false;
+ } else if (this is ErrorCode) {
+ isclass = false;
+ }
+
+ return isclass;
+ }
}
public enum Vala.SymbolAccessibility {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]