From: Jürg Billeter Date: Wed, 4 Oct 2006 22:00:37 +0000 (+0000) Subject: correct takes_ownership in arrays add limited support for array length X-Git-Tag: VALA_0_0_4~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dec15a0f8fcd43a45929af01f0a127edef4f25e0;p=thirdparty%2Fvala.git correct takes_ownership in arrays add limited support for array length 2006-10-04 Jürg Billeter * vala/valasymbolresolver.vala: correct takes_ownership in arrays * vala/valacodegenerator.vala: add limited support for array length fields, store array length from array creation expression, copy array length in array assignments * vala/valafield.vala: support NoArrayLength attribute * compiler/valacompiler.vala: add NoArrayLength attribute to option arrays svn path=/trunk/; revision=140 --- diff --git a/vala/ChangeLog b/vala/ChangeLog index 39f421795..5c8794caf 100644 --- a/vala/ChangeLog +++ b/vala/ChangeLog @@ -1,3 +1,13 @@ +2006-10-04 Jürg Billeter + + * vala/valasymbolresolver.vala: correct takes_ownership in arrays + * vala/valacodegenerator.vala: add limited support for array length + fields, store array length from array creation expression, copy array + length in array assignments + * vala/valafield.vala: support NoArrayLength attribute + * compiler/valacompiler.vala: add NoArrayLength attribute to option + arrays + 2006-10-04 Jürg Billeter * vala/valasymbolresolver.vala, vala/valasemanticanalyzer.vala: specify diff --git a/vala/compiler/valacompiler.vala b/vala/compiler/valacompiler.vala index f145c9620..87a686998 100644 --- a/vala/compiler/valacompiler.vala +++ b/vala/compiler/valacompiler.vala @@ -25,9 +25,12 @@ using GLib; class Vala.Compiler { static string directory; static bool version; + [NoArrayLength ()] static string[] sources; + [NoArrayLength ()] static string[] vapi_directories; static string library; + [NoArrayLength ()] static string[] packages; static bool disable_memory_management; diff --git a/vala/vala/valacodegenerator.vala b/vala/vala/valacodegenerator.vala index 17ce907b7..93415cf0a 100644 --- a/vala/vala/valacodegenerator.vala +++ b/vala/vala/valacodegenerator.vala @@ -908,15 +908,16 @@ public class Vala.CodeGenerator : CodeVisitor { public override void visit_field (Field! f) { CCodeExpression lhs = null; + CCodeStruct st = null; if (f.access != MemberAccessibility.PRIVATE) { - instance_struct.add_field (f.type_reference.get_cname (), f.get_cname ()); + st = instance_struct; if (f.instance) { lhs = new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), f.get_cname ()); } } else if (f.access == MemberAccessibility.PRIVATE) { if (f.instance) { - instance_priv_struct.add_field (f.type_reference.get_cname (), f.get_cname ()); + st = instance_priv_struct; lhs = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), f.get_cname ()); } else { if (f.symbol.parent_symbol.node is DataType) { @@ -934,8 +935,32 @@ public class Vala.CodeGenerator : CodeVisitor { } if (f.instance) { + st.add_field (f.type_reference.get_cname (), f.get_cname ()); + if (f.type_reference.data_type is Array && !f.no_array_length) { + // create fields to store array dimensions + var arr = (Array) f.type_reference.data_type; + + for (int dim = 1; dim <= arr.rank; dim++) { + var len_type = new TypeReference (); + len_type.data_type = int_type.data_type; + + st.add_field (len_type.get_cname (), get_array_length_cname (f.name, dim)); + } + } + if (f.initializer != null) { instance_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (lhs, (CCodeExpression) f.initializer.ccodenode))); + + if (f.type_reference.data_type is Array && !f.no_array_length && + f.initializer is ArrayCreationExpression) { + var ma = new MemberAccess.simple (f.name); + ma.symbol_reference = f.symbol; + + var array_len_lhs = get_array_length_cexpression (ma, 1); + var sizes = ((ArrayCreationExpression) f.initializer).get_sizes (); + var size = (Expression) sizes.data; + instance_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (array_len_lhs, (CCodeExpression) size.ccodenode))); + } } if (f.type_reference.takes_ownership) { @@ -2257,7 +2282,11 @@ public class Vala.CodeGenerator : CodeVisitor { } } - if (array_expr.symbol_reference != null) { + if (array_expr is ArrayCreationExpression) { + var size = ((ArrayCreationExpression) array_expr).get_sizes (); + var length_expr = (Expression) size.nth_data (dim - 1); + return (CCodeExpression) length_expr.ccodenode; + } else if (array_expr.symbol_reference != null) { if (array_expr.symbol_reference.node is FormalParameter) { var param = (FormalParameter) array_expr.symbol_reference.node; if (!param.no_array_length) { @@ -2276,6 +2305,62 @@ public class Vala.CodeGenerator : CodeVisitor { } else { return length_expr; } + } else if (array_expr.symbol_reference.node is Field) { + var field = (Field) array_expr.symbol_reference.node; + if (!field.no_array_length) { + var length_cname = get_array_length_cname (field.name, dim); + + var ma = (MemberAccess) array_expr; + + CCodeExpression pub_inst = null; + DataType base_type = null; + CCodeExpression length_expr = null; + + if (ma.inner == null) { + pub_inst = new CCodeIdentifier ("self"); + + if (current_type_symbol != null) { + /* base type is available if this is a type method */ + base_type = (DataType) current_type_symbol.node; + } + } else { + pub_inst = (CCodeExpression) ma.inner.ccodenode; + + if (ma.inner.static_type != null) { + base_type = ma.inner.static_type.data_type; + } + } + + if (field.instance) { + ref CCodeExpression typed_inst; + if (field.symbol.parent_symbol.node != base_type) { + // FIXME: use C cast if debugging disabled + typed_inst = new CCodeFunctionCall (new CCodeIdentifier (((DataType) field.symbol.parent_symbol.node).get_upper_case_cname (null))); + ((CCodeFunctionCall) typed_inst).add_argument (pub_inst); + } else { + typed_inst = pub_inst; + } + ref CCodeExpression inst; + if (field.access == MemberAccessibility.PRIVATE) { + inst = new CCodeMemberAccess.pointer (typed_inst, "priv"); + } else { + inst = typed_inst; + } + if (((DataType) field.symbol.parent_symbol.node).is_reference_type ()) { + length_expr = new CCodeMemberAccess.pointer (inst, length_cname); + } else { + length_expr = new CCodeMemberAccess (inst, length_cname); + } + } else { + length_expr = new CCodeIdentifier (length_cname); + } + + if (is_out) { + return new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, length_expr); + } else { + return length_expr; + } + } } } @@ -2895,14 +2980,29 @@ public class Vala.CodeGenerator : CodeVisitor { rhs = ccast; } - if (memory_management && a.left.static_type.takes_ownership) { - /* unref old value */ + bool unref_old = (memory_management && a.left.static_type.takes_ownership); + bool array = false; + if (a.left.static_type.data_type is Array) { + array = !(get_array_length_cexpression (a.left, 1) is CCodeConstant); + } + + if (unref_old || array) { var ccomma = new CCodeCommaExpression (); var temp_decl = get_temp_variable_declarator (a.left.static_type); temp_vars.prepend (temp_decl); ccomma.append_expression (new CCodeAssignment (new CCodeIdentifier (temp_decl.name), rhs)); - ccomma.append_expression (get_unref_expression ((CCodeExpression) a.left.ccodenode, a.left.static_type)); + if (unref_old) { + /* unref old value */ + ccomma.append_expression (get_unref_expression ((CCodeExpression) a.left.ccodenode, a.left.static_type)); + } + + if (array) { + var lhs_array_len = get_array_length_cexpression (a.left, 1); + var rhs_array_len = get_array_length_cexpression (a.right, 1); + ccomma.append_expression (new CCodeAssignment (lhs_array_len, rhs_array_len)); + } + ccomma.append_expression (new CCodeIdentifier (temp_decl.name)); rhs = ccomma; diff --git a/vala/vala/valafield.vala b/vala/vala/valafield.vala index f8c71a4c9..c48611e0d 100644 --- a/vala/vala/valafield.vala +++ b/vala/vala/valafield.vala @@ -61,6 +61,12 @@ public class Vala.Field : Member, Invokable, Lockable { _instance = value; } } + + /** + * Specifies whether an array length field should implicitly be created + * if the field type is an array. + */ + public bool no_array_length { get; set; } private string cname; private bool _instance = true; @@ -137,6 +143,8 @@ public class Vala.Field : Member, Invokable, Lockable { foreach (Attribute a in attributes) { if (a.name == "CCode") { process_ccode_attribute (a); + } else if (a.name == "NoArrayLength") { + no_array_length = true; } } } diff --git a/vala/vala/valasymbolresolver.vala b/vala/vala/valasymbolresolver.vala index 1d27696fa..71cfc0343 100644 --- a/vala/vala/valasymbolresolver.vala +++ b/vala/vala/valasymbolresolver.vala @@ -181,21 +181,23 @@ public class Vala.SymbolResolver : CodeVisitor { type.data_type = (DataType) sym.node; } - if (type.data_type != null && !type.data_type.is_reference_type ()) { - /* reset takes_ownership of value-types for contexts - * where types are ref by default (field declarations) - */ - type.takes_ownership = false; - } - /* check for array */ if (type.array_rank > 0) { var element_type = new TypeReference (); element_type.data_type = type.data_type; - element_type.takes_ownership = true; + if (type.data_type != null && type.data_type.is_reference_type ()) { + element_type.takes_ownership = true; + } type.data_type = type.data_type.get_array (type.array_rank); type.add_type_argument (element_type); } + + if (type.data_type != null && !type.data_type.is_reference_type ()) { + /* reset takes_ownership of value-types for contexts + * where types are ref by default (field declarations) + */ + type.takes_ownership = false; + } } }