Commit dec15a0f authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter
Browse files

correct takes_ownership in arrays add limited support for array length

2006-10-04  Jürg Billeter  <j@bitron.ch>

	* 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
parent 0e25bbfe
2006-10-04 Jürg Billeter <j@bitron.ch>
* 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 <j@bitron.ch>
* vala/valasymbolresolver.vala, vala/valasemanticanalyzer.vala: specify
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
}
}
}
......
......@@ -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;
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment